1 /***
2 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 */
4 package net.sourceforge.pmd.cpd;
5
6 import org.apache.tools.ant.BuildException;
7 import org.apache.tools.ant.DirectoryScanner;
8 import org.apache.tools.ant.Project;
9 import org.apache.tools.ant.Task;
10 import org.apache.tools.ant.types.EnumeratedAttribute;
11 import org.apache.tools.ant.types.FileSet;
12
13 import java.io.File;
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.Iterator;
17 import java.util.List;
18
19 /***
20 * CPDTask
21 *
22 * Runs the CPD utility via ant. The ant task looks like this:
23 *
24 * <project name="CPDProj" default="main" basedir=".">
25 * <taskdef name="cpd" classname="net.sourceforge.pmd.cpd.CPDTask" />
26 * <target name="main">
27 * <cpd minimumTokenCount="100" outputFile="c:\cpdrun.txt">
28 * <fileset dir="/path/to/my/src">
29 * <include name="*.java"/>
30 * </fileset>
31 * </cpd>
32 * </target>
33 *</project>
34 *
35 * Required: minimumTokenCount, outputFile, and at least one file
36 */
37 public class CPDTask extends Task {
38
39 private static final String TEXT_FORMAT = "text";
40 private static final String XML_FORMAT = "xml";
41 private static final String CSV_FORMAT = "csv";
42
43 private String format = TEXT_FORMAT;
44 private int minimumTokenCount;
45 private File outputFile;
46 private List filesets = new ArrayList();
47
48 public void execute() throws BuildException {
49 try {
50 validateFields();
51
52 log("Tokenizing files", Project.MSG_INFO);
53 CPD cpd = new CPD(minimumTokenCount, new JavaLanguage());
54 tokenizeFiles(cpd);
55
56 log("Starting to analyze code", Project.MSG_INFO);
57 long timeTaken = analyzeCode(cpd);
58 log("Done analyzing code; that took " + timeTaken + " milliseconds");
59
60 log("Generating report", Project.MSG_INFO);
61 report(cpd);
62 } catch (IOException ioe) {
63 log(ioe.toString(), Project.MSG_ERR);
64 throw new BuildException("IOException during task execution", ioe);
65 } catch (ReportException re) {
66 log(re.toString(), Project.MSG_ERR);
67 throw new BuildException("ReportException during task execution", re);
68 }
69 }
70
71 private void report(CPD cpd) throws ReportException {
72 if (!cpd.getMatches().hasNext()) {
73 log("No duplicates over " + minimumTokenCount + " tokens found", Project.MSG_INFO);
74 }
75 Renderer renderer = createRenderer();
76 if (outputFile.isAbsolute()) {
77 new FileReporter(outputFile).report(renderer.render(cpd.getMatches()));
78 } else {
79 new FileReporter(new File(project.getBaseDir(), outputFile.toString()));
80 }
81 }
82
83
84 private void tokenizeFiles(CPD cpd) throws IOException {
85 for (Iterator iterator = filesets.iterator(); iterator.hasNext();) {
86 FileSet fileSet = (FileSet) iterator.next();
87 DirectoryScanner directoryScanner = fileSet.getDirectoryScanner(project);
88 String[] includedFiles = directoryScanner.getIncludedFiles();
89 for (int i = 0; i < includedFiles.length; i++) {
90 File file = new File(directoryScanner.getBasedir() + System.getProperty("file.separator") + includedFiles[i]);
91 log("Tokenizing " + file.getAbsolutePath(), Project.MSG_VERBOSE);
92 cpd.add(file);
93 }
94 }
95 }
96
97 private long analyzeCode(CPD cpd) {
98 long start = System.currentTimeMillis();
99 cpd.go();
100 long stop = System.currentTimeMillis();
101 return stop - start;
102 }
103
104 private Renderer createRenderer() {
105 if (format.equals(TEXT_FORMAT)) {
106 return new SimpleRenderer();
107 } else if (format.equals(CSV_FORMAT)) {
108 return new CSVRenderer();
109 }
110 return new XMLRenderer();
111 }
112
113 private void validateFields() throws BuildException{
114 if(minimumTokenCount == 0){
115 throw new BuildException("minimumTokenCount is required and must be greater than zero");
116 } else if(outputFile == null) {
117 throw new BuildException("outputFile is a required attribute");
118 } else if (filesets.isEmpty()) {
119 throw new BuildException("Must include at least one FileSet");
120 }
121
122 }
123
124 public void addFileset(FileSet set) {
125 filesets.add(set);
126 }
127
128 public void setMinimumTokenCount(int minimumTokenCount) {
129 this.minimumTokenCount = minimumTokenCount;
130 }
131
132 public void setOutputFile(File outputFile) {
133 this.outputFile = outputFile;
134 }
135
136 public void setFormat(FormatAttribute formatAttribute) {
137 format = formatAttribute.getValue();
138 }
139
140 public static class FormatAttribute extends EnumeratedAttribute {
141 private String[] formats = new String[] {XML_FORMAT, TEXT_FORMAT, CSV_FORMAT};
142
143 public String[] getValues() {
144 return formats;
145 }
146 }
147 }
This page was automatically generated by Maven