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
42 private String format = TEXT_FORMAT;
43 private int minimumTokenCount;
44 private File outputFile;
45 private List filesets = new ArrayList();
46
47 public void execute() throws BuildException {
48 try {
49 validateFields();
50
51 log("Tokenizing files", Project.MSG_INFO);
52 CPD cpd = new CPD(minimumTokenCount, new JavaLanguage());
53 tokenizeFiles(cpd);
54
55 log("Starting to analyze code", Project.MSG_INFO);
56 long timeTaken = analyzeCode(cpd);
57 log("Done analyzing code; that took " + timeTaken + " milliseconds");
58
59 log("Generating report", Project.MSG_INFO);
60 report(cpd);
61 } catch (IOException ioe) {
62 log(ioe.toString(), Project.MSG_ERR);
63 throw new BuildException("IOException during task execution", ioe);
64 } catch (ReportException re) {
65 log(re.toString(), Project.MSG_ERR);
66 throw new BuildException("ReportException during task execution", re);
67 }
68 }
69
70 private void report(CPD cpd) throws ReportException {
71 if (!cpd.getMatches().hasNext()) {
72 log("No duplicates over " + minimumTokenCount + " tokens found", Project.MSG_INFO);
73 }
74 Renderer renderer = createRenderer();
75 if (outputFile.isAbsolute()) {
76 new FileReporter(outputFile).report(renderer.render(cpd.getMatches()));
77 } else {
78 new FileReporter(new File(project.getBaseDir(), outputFile.toString()));
79 }
80 }
81
82
83 private void tokenizeFiles(CPD cpd) throws IOException {
84 for (Iterator iterator = filesets.iterator(); iterator.hasNext();) {
85 FileSet fileSet = (FileSet) iterator.next();
86 DirectoryScanner directoryScanner = fileSet.getDirectoryScanner(project);
87 String[] includedFiles = directoryScanner.getIncludedFiles();
88 for (int i = 0; i < includedFiles.length; i++) {
89 File file = new File(directoryScanner.getBasedir() + System.getProperty("file.separator") + includedFiles[i]);
90 log("Tokenizing " + file.getAbsolutePath(), Project.MSG_VERBOSE);
91 cpd.add(file);
92 }
93 }
94 }
95
96 private long analyzeCode(CPD cpd) {
97 long start = System.currentTimeMillis();
98 cpd.go();
99 long stop = System.currentTimeMillis();
100 return stop - start;
101 }
102
103 private Renderer createRenderer() {
104 if (format.equals(TEXT_FORMAT)) {
105 return new SimpleRenderer();
106 } else
107 return new XMLRenderer();
108 }
109
110 private void validateFields() throws BuildException{
111 if(minimumTokenCount == 0){
112 throw new BuildException("minimumTokenCount is required and must be greater than zero");
113 } else if(outputFile == null) {
114 throw new BuildException("outputFile is a required attribute");
115 } else if (filesets.isEmpty()) {
116 throw new BuildException("Must include at least one FileSet");
117 }
118
119 }
120
121 public void addFileset(FileSet set) {
122 filesets.add(set);
123 }
124
125 public void setMinimumTokenCount(int minimumTokenCount) {
126 this.minimumTokenCount = minimumTokenCount;
127 }
128
129 public void setOutputFile(File outputFile) {
130 this.outputFile = outputFile;
131 }
132
133 public void setFormat(FormatAttribute formatAttribute) {
134 format = formatAttribute.getValue();
135 }
136
137 public static class FormatAttribute extends EnumeratedAttribute {
138 private String[] formats = new String[] {XML_FORMAT, TEXT_FORMAT};
139
140 public String[] getValues() {
141 return formats;
142 }
143 }
144 }
This page was automatically generated by Maven