View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugins.pmd;
20  
21  import java.io.File;
22  import java.io.FileInputStream;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.util.List;
26  
27  import org.apache.maven.plugin.MojoExecutionException;
28  import org.apache.maven.plugin.MojoFailureException;
29  import org.apache.maven.plugins.annotations.Execute;
30  import org.apache.maven.plugins.annotations.LifecyclePhase;
31  import org.apache.maven.plugins.annotations.Mojo;
32  import org.apache.maven.plugins.annotations.Parameter;
33  import org.apache.maven.plugins.pmd.model.CpdErrorDetail;
34  import org.apache.maven.plugins.pmd.model.CpdFile;
35  import org.apache.maven.plugins.pmd.model.Duplication;
36  import org.apache.maven.plugins.pmd.model.io.xpp3.CpdXpp3Reader;
37  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
38  
39  /**
40   * Fails the build if there were any CPD violations in the source code.
41   *
42   * @version $Id$
43   * @since 2.0
44   */
45  @Mojo(name = "cpd-check", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true)
46  @Execute(goal = "cpd")
47  public class CpdViolationCheckMojo extends AbstractPmdViolationCheckMojo<Duplication> {
48      /**
49       * Default constructor. Initializes with the correct {@link ExcludeDuplicationsFromFile}.
50       */
51      public CpdViolationCheckMojo() {
52          super(new ExcludeDuplicationsFromFile());
53      }
54  
55      /**
56       * Skip the CPD violation checks. Most useful on the command line via "-Dcpd.skip=true".
57       */
58      @Parameter(property = "cpd.skip", defaultValue = "false")
59      private boolean skip;
60  
61      /**
62       * Whether to fail the build if the validation check fails.
63       *
64       * @since 3.0
65       */
66      @Parameter(property = "cpd.failOnViolation", defaultValue = "true", required = true)
67      protected boolean failOnViolation;
68  
69      /**
70       * {@inheritDoc}
71       */
72      public void execute() throws MojoExecutionException, MojoFailureException {
73          if (skip) {
74              getLog().info("Skipping CPD execution");
75              return;
76          }
77  
78          executeCheck("cpd.xml", "duplication", "CPD duplication", 10);
79      }
80  
81      /**
82       * {@inheritDoc}
83       */
84      @Override
85      protected void printError(Duplication item, String severity) {
86          int lines = item.getLines();
87  
88          StringBuilder buff = new StringBuilder(100);
89          buff.append("CPD ").append(severity).append(": Found ");
90          buff.append(lines).append(" lines of duplicated code at locations:");
91          this.getLog().info(buff.toString());
92  
93          for (CpdFile file : item.getFiles()) {
94              buff.setLength(0);
95              buff.append("    ");
96              buff.append(file.getPath());
97              buff.append(" line ").append(file.getLine());
98              this.getLog().info(buff.toString());
99          }
100 
101         this.getLog().debug("CPD " + severity + ": Code Fragment ");
102         this.getLog().debug(item.getCodefragment());
103     }
104 
105     /**
106      * {@inheritDoc}
107      */
108     @Override
109     protected List<Duplication> getErrorDetails(File cpdFile) throws XmlPullParserException, IOException {
110         try (InputStream in = new FileInputStream(cpdFile)) {
111             CpdXpp3Reader reader = new CpdXpp3Reader();
112             CpdErrorDetail details = reader.read(in, false);
113             return details.getDuplications();
114         }
115     }
116 
117     @Override
118     protected int getPriority(Duplication errorDetail) {
119         return 0;
120     }
121 
122     @Override
123     protected ViolationDetails<Duplication> newViolationDetailsInstance() {
124         return new ViolationDetails<>();
125     }
126 
127     @Override
128     public boolean isFailOnViolation() {
129         return failOnViolation;
130     }
131 }