View Javadoc
1   /*
2   Copyright (C) 2002 Steve Jernigan <sjernigan@iname.com>.
3   
4   This file is part of JavaNCSS2Ant and JavaNCSS
5   (http://sourceforge.net/projects/javancss2ant/ ,
6   http://www.kclee.de/clemens/java/javancss/).
7   
8   JavaNCSS2Ant and JavaNCSS are free software; you can redistribute it and/or modify it
9   under the terms of the GNU General Public License as published by the
10  Free Software Foundation; either version 2, or (at your option) any
11  later version.
12  
13  JavaNCSS2Ant and JavaNCSS are distributed in the hope that it will be useful, but WITHOUT
14  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16  for more details.
17  
18  You should have received a copy of the GNU General Public License
19  along with JavaNCSS; see the file COPYING.  If not, write to
20  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  Boston, MA 02111-1307, USA.  */
22  
23  package javancss;
24  
25  import java.io.File;
26  import java.io.FileOutputStream;
27  import java.io.IOException;
28  import java.io.PrintWriter;
29  import java.util.ArrayList;
30  import java.util.Arrays;
31  import java.util.List;
32  
33  import org.apache.tools.ant.BuildException;
34  import org.apache.tools.ant.DirectoryScanner;
35  import org.apache.tools.ant.Project;
36  import org.apache.tools.ant.taskdefs.MatchingTask;
37  import org.apache.tools.ant.types.CommandlineJava;
38  import org.apache.tools.ant.types.Path;
39  
40  /**
41   * Ant task to report and check basic code metrics.
42   *
43   * <p>This task wraps the JavaNCSS library for determining code metrics. The
44   * library determines several code metrics such as object counts, non-commented
45   * source statements (NCSS), cyclomatic complexity numbers (CCN), and javadoc
46   * statements. These counts are subtotaled per function, class, and package.
47   * This task allows you to place minimum and maximum thresholds on each of these
48   * (not all of these make sense but all are included for completeness).
49   *
50   * <p>The original version of this task was written by Steve Jernigan and made
51   * available on SourceForge as the JavaNCSS2Ant project. It was subsequently
52   * extended by Phillip Wells to enable access to the report generation feature
53   * of the tool whereupon it was submitted for inclusion in Ant itself.
54   *
55   * <p>JavaNCSS was developed by Christoph Clemens Lee and is available
56   * <a href="http://www.kclee.de/clemens/java/javancss/">here</a>.
57   *
58   * @author Phillip Wells
59   * @author Steve Jernigan
60   * @author Clemens Lee
61   */
62  public class JavancssAntTask extends MatchingTask {
63      /**
64       * The command to be executed to run to tool.
65       */
66      private CommandlineJava commandline = new CommandlineJava();
67      /**
68       * Whether the build should halt if there is an error or a threshold is
69       * exceeded.
70       */
71      private boolean abortOnFail = false;
72      /**
73       * The directory containing the source files to be scanned by the tool.
74       */
75      private File srcdir;
76      /**
77       * The classpath to be used.
78       */
79      private Path classpath;
80      /**
81       * The location of the output file.
82       */
83      private File outputfile;
84      /**
85       * The format of the output file. Allowable values are 'plain' or 'xml'.
86       */
87      private String format = "plain";
88      /**
89       * Indicates the failure of the JavaNCSS process.
90       */
91      private static final int FAILURE = 1;
92      /**
93       * Indicates the success of the JavaNCSS process.
94       */
95      private static final int SUCCESS = 0;
96      /**
97       * The maximum number of classes per package.
98       */
99      private int classPerPkgMax = Integer.MAX_VALUE;
100     /**
101      * The minimum number of classes per package.
102      */
103     private int classPerPkgMin = -1;
104     /**
105      * The maximum number of functions per package.
106      */
107     private int funcPerPkgMax = Integer.MAX_VALUE;
108     /**
109      * The minimum number of functions per package.
110      */
111     private int funcPerPkgMin = -1;
112     /**
113      * The maximum number of non-commenting source statements per package.
114      */
115     private int ncssPerPkgMax = Integer.MAX_VALUE;
116     /**
117      * The minimum number of non-commenting source statements per package.
118      */
119     private int ncssPerPkgMin = -1;
120     /**
121      * The maximum number of inner classes per class.
122      */
123     private int classPerClassMax = Integer.MAX_VALUE;
124     /**
125      * The minimum number of inner classes per class.
126      */
127     private int classPerClassMin = -1;
128     /**
129      * The maximum number of functions per class.
130      */
131     private int funcPerClassMax = Integer.MAX_VALUE;
132     /**
133      * The minimum number of functions per class.
134      */
135     private int funcPerClassMin = -1;
136     /**
137      * The maximum number of non-commenting source statements per class.
138      */
139     private int ncssPerClassMax = Integer.MAX_VALUE;
140     /**
141      * The minimum number of non-commenting source statements per class.
142      */
143     private int ncssPerClassMin = -1;
144     /**
145      * The maximum number of javadoc comments per class.
146      */
147     private int jvdcPerClassMax = Integer.MAX_VALUE;
148     /**
149      * The minimum number of javadoc comments per class.
150      */
151     private int jvdcPerClassMin = -1;
152     /**
153      * The maximum number of javadoc comments per function.
154      */
155     private int jvdcPerFuncMax = Integer.MAX_VALUE;
156     /**
157      * The minimum number of javadoc comments per function.
158      */
159     private int jvdcPerFuncMin = -1;
160     /**
161      * The maximum value of the Cyclomatic Complexity Number per function.
162      */
163     private int ccnPerFuncMax = Integer.MAX_VALUE;
164     /**
165      * The minimum value of the Cyclomatic Complexity Number per function.
166      */
167     private int ccnPerFuncMin = -1;
168     /**
169      * The maximum number of non-commenting source statements per function.
170      */
171     private int ncssPerFuncMax = Integer.MAX_VALUE;
172     /**
173      * The minimum number of non-commenting source statements per function.
174      */
175     private int ncssPerFuncMin = -1;
176     /**
177      * Whether package metrics should be generated.
178      */
179     private boolean packageMetrics = true;
180     /**
181      * Whether class metrics should be generated.
182      */
183     private boolean classMetrics = true;
184     /**
185      * Whether function metrics should be generated.
186      */
187     private boolean functionMetrics = true;
188     /**
189      * Whether to generate a report.
190      */
191     private boolean generateReport = false;
192     /**
193      * The JavaNCSS object containing details of the code whose metrics are
194      * to be checked.
195      */
196     private Javancss javancss;
197 
198     /**
199      * Creates a new instance of the task.
200      */
201     public JavancssAntTask() {
202         commandline.setClassname("javancss.Main");
203     }
204 
205     /**
206      * Sets the format of the output file.
207      * @param format the format of the output file. Allowable values are 'plain'
208      * or 'xml'.
209      */
210     public void setFormat(String format) {
211         this.format = format;
212     }
213 
214     /**
215      * Whether package metrics should be generated.
216      * @param packageMetrics true if they should; false otherwise.
217      */
218     public void setPackageMetrics(boolean packageMetrics) {
219         this.packageMetrics = packageMetrics;
220     }
221 
222     /**
223      * Whether class/interface metrics should be generated.
224      * @param classMetrics true if they should; false otherwise.
225      */
226     public void setClassMetrics(boolean classMetrics) {
227         this.classMetrics = classMetrics;
228     }
229 
230     /**
231      * Whether function metrics should be generated.
232      * @param functionMetrics true if they should; false otherwise.
233      */
234     public void setFunctionMetrics(boolean functionMetrics) {
235         this.functionMetrics = functionMetrics;
236     }
237 
238     /**
239      * Whether a report should be generated. Default is false.
240      * @param generateReport true if they should; false otherwise.
241      */
242     public void setGenerateReport(boolean generateReport) {
243         this.generateReport = generateReport;
244     }
245 
246     /**
247      * Sets the directory to be scanned by the tool. This should be the
248      * directory containing the source files whose metrics are to be
249      * analysed.
250      * @param srcdir the directory to be scanned by the tool.
251      */
252     public void setSrcdir(File srcdir) {
253         this.srcdir = srcdir;
254     }
255 
256     /**
257      * Sets the location of the output file.
258      * @param outputfile the location of the output file.
259      */
260     public void setOutputfile(File outputfile) {
261         this.outputfile = outputfile;
262     }
263 
264     /**
265      * Set the classpath to be used.
266      * @param classpath the classpath to be used.
267      */
268     public void setClasspath(Path classpath) {
269         if (this.classpath == null) {
270             this.classpath = classpath;
271         } else {
272             this.classpath.append(classpath);
273         }
274     }
275 
276     /**
277      * Sets whether the build should halt if there is an error or a threshold is
278      * exceeded.
279      * @param abortOnFail true if it should; false otherwise.
280      */
281     public void setAbortOnFail(boolean abortOnFail) {
282         this.abortOnFail = abortOnFail;
283     }
284 
285     /**
286      * Executes this task.
287      * @throws BuildException if an error occurs.
288      */
289     @Override
290     public void execute() throws BuildException {
291         if (srcdir == null) {
292             throw new BuildException("srcdir attribute must be set!");
293         }
294         if (!srcdir.exists()) {
295             throw new BuildException("srcdir does not exist!");
296         }
297         if (!srcdir.isDirectory()) {
298             throw new BuildException("srcdir is not a directory!");
299         }
300 
301         List<File> fileList = findFilesToAnalyse();
302 
303         // First check thresholds
304         if (thresholdsExceeded(fileList) && abortOnFail) {
305             throw new BuildException("Metric threshold value(s) surpassed");
306         }
307 
308         // Then generate report
309         int exitValue = generateReport(fileList);
310         if (exitValue == FAILURE) {
311             if (abortOnFail) {
312                 throw new BuildException("JavaNcss failed", getLocation());
313             } else {
314                 log("JavaNcss failed", Project.MSG_ERR);
315             }
316         }
317     }
318 
319     /**
320      * Generates a report on the specified files.
321      * @param fileList the files to be analyzed.
322      * @return {@link #SUCCESS} if there were no errors; otherwise {@link #FAILURE}.
323      * @throws BuildException if an error occurs whilst generating the report.
324      */
325     private int generateReport(List<File> fileList) {
326         // If an output file has not been specified no report should be
327         // generated
328         if (!generateReport) {
329             return SUCCESS;
330         }
331 
332         // result is in this.javancssArguments
333         log("Generating report");
334         if (outputfile != null) {
335             log("Report to be stored in " + outputfile.getPath(), Project.MSG_VERBOSE);
336         } else {
337             log("Report to be sent to standard output", Project.MSG_VERBOSE);
338         }
339         String[] javancssArguments = getCommandLineArguments(fileList);
340         log("Executing: javancss " + Arrays.toString( javancssArguments ), Project.MSG_VERBOSE);
341 
342         try {
343             Javancss javancss = new Javancss(javancssArguments);
344 
345             if (javancss.getLastError() == null) {
346                 return SUCCESS;
347             }
348         }
349         catch (IOException ioe)
350         {
351             log("IO exception while executing JavaNCSS: " + ioe.getMessage(), Project.MSG_ERR);
352         }
353 
354         return FAILURE;
355     }
356 
357     /**
358      * Checks to see if the metrics of the specified files have exceeded any of
359      * the thresholds.
360      * @param fileList the files to be analysed.
361      * @return true if any of the thresholds have been exceeded; false otherwise.
362      */
363     private boolean thresholdsExceeded(List<File> fileList) {
364         return packageThresholdsExceeded(fileList) ||
365                 classThresholdsExceeded(fileList) ||
366                 functionThresholdsExceeded(fileList);
367     }
368 
369 
370     /**
371      * Builds a list of all files to be analysed. We need to do this when
372      * testing thresholds as the Javancss object does not have a constructor
373      * that lets us make use of the -recursive option
374      */
375     private List<File> findFilesToAnalyse() {
376         DirectoryScanner ds = super.getDirectoryScanner(srcdir);
377         String[] files = ds.getIncludedFiles();
378         if (files.length == 0) {
379             log("No files in specified directory " + srcdir, 3);
380         }
381         return copyFiles(files);
382     }
383 
384     /**
385      * Converts the specified array of filenames into a vector of paths.
386      * @param filenames an array of filenames.
387      * @return a vector of paths. The path is constructed by prepending this
388      * task's source directory to each filename.
389      */
390     private List<File> copyFiles(String[] filenames) {
391         List<File> returnVector = new ArrayList<File>(filenames.length);
392         for (String filename : filenames) {
393             returnVector.add(new File(srcdir, filename));
394         }
395         return returnVector;
396     }
397 
398     /**
399      * Maybe creates a nested classpath element.
400      */
401     public Path createClasspath() {
402         if (classpath == null) {
403             classpath = new Path(getProject());
404         }
405         return classpath.createPath();
406     }
407 
408     /**
409      * Gets the command line arguments to be sent to JavaNCSS.
410      * @param fileList a list of all source files to be analysed.
411      * @return the command line arguments to be sent to JavaNCSS.
412      */
413     private String[] getCommandLineArguments(List<File> fileList) {
414         List<String> arguments = new ArrayList<String>();
415 
416         // Set metrics to be generated
417         if (packageMetrics) {
418             arguments.add("-package");
419         }
420         if (classMetrics) {
421             arguments.add("-object");
422         }
423         if (functionMetrics) {
424             arguments.add("-function");
425         }
426 
427         // Set format of report
428         if (format.equals("xml")) {
429             arguments.add("-xml");
430         }
431 
432         // Set location of report
433         if (outputfile != null) {
434             arguments.add("-out");
435             arguments.add(outputfile.getPath());
436         }
437 
438         // Set source code to be processed
439         arguments.add("@" + createSourceListFile(fileList).getPath());
440 
441         String[] javancssArguments = new String[arguments.size()];
442         for (int argument = 0; argument < arguments.size(); argument++) {
443             javancssArguments[argument] = arguments.get(argument);
444         }
445         return javancssArguments;
446     }
447 
448     /**
449      * Creates a temporary file containing a list of all source files to be
450      * analysed.
451      * @param fileList the source files to be analysed.
452      * @return a file containing a list of all specified source files.
453      */
454     private File createSourceListFile(List<File> fileList) {
455         File srcListFile;
456         try {
457             srcListFile = File.createTempFile("srcList", null);
458             srcListFile.deleteOnExit();
459             FileOutputStream fos = new FileOutputStream(srcListFile);
460             PrintWriter pw = new PrintWriter(fos);
461             for (File file : fileList) {
462                 log(file.toString(), 3);
463                 pw.println(file.toString());
464             }
465             pw.close();
466             fos.close();
467         } catch (IOException e) {
468             throw new BuildException(e, getLocation());
469         }
470         return srcListFile;
471     }
472 
473     /**
474      * Gets the JavaNCSS object containing details of the code whose metrics are
475      * to be checked.
476      * @param fileList the files to be analysed.
477      * @return the JavaNCSS object containing details of the code whose metrics
478      * are to be checked.
479      */
480     private Javancss getJavaNcss(List<File> fileList)
481     {
482         if (javancss == null)
483         {
484             log("Checking metrics on " + fileList.size() + " files");
485             javancss = new Javancss(fileList);
486         }
487         return javancss;
488     }
489 
490     /**
491      * Checks package thresholds for all packages.
492      * @param fileList the files to be analysed.
493      * @return true if a threshold has been exceeded; false otherwise.
494      */
495     private boolean packageThresholdsExceeded(List<File> fileList) {
496         boolean failed = false;
497         if (!(classPerPkgMax == Integer.MAX_VALUE &&
498                 classPerPkgMin == -1 &&
499                 funcPerPkgMax == Integer.MAX_VALUE &&
500                 funcPerPkgMin == -1 &&
501                 ncssPerPkgMax == Integer.MAX_VALUE &&
502                 ncssPerPkgMin == -1)) {
503            List<PackageMetric> pkgMetrics = getJavaNcss(fileList).getPackageMetrics();
504             for (PackageMetric pkgMetric : pkgMetrics) {
505                 failed = packageThresholdExceeded(pkgMetric) || failed;
506             }
507         }
508         return failed;
509     }
510 
511     /**
512      * Checks thresholds for the specified package.
513      * @param packageMetrics the metrics of the package under test.
514      * @return true if a threshold has been exceeded; false otherwise.
515      */
516     private boolean packageThresholdExceeded(PackageMetric packageMetrics) {
517         boolean failed = false;
518         String errorMsg = "";
519         if (classPerPkgMax < packageMetrics.classes) {
520             failed = true;
521             errorMsg = packageMetrics.classes + " classes exceeds maximum per package";
522         } else if (classPerPkgMin > packageMetrics.classes) {
523             failed = true;
524             errorMsg = packageMetrics.classes + " classes does not meet minimum per package";
525         }
526         if (funcPerPkgMax < packageMetrics.functions) {
527             failed = true;
528             errorMsg = packageMetrics.functions + " functions exceeds maximum pre package";
529         } else if (funcPerPkgMin > packageMetrics.functions) {
530             failed = true;
531             errorMsg = packageMetrics.functions + " functions does not meet minimum per package";
532         }
533         if (ncssPerPkgMax < packageMetrics.ncss) {
534             failed = true;
535             errorMsg = packageMetrics.ncss + " NCSS exceeds maximum per package";
536         } else if (ncssPerPkgMin > packageMetrics.ncss) {
537             failed = true;
538             errorMsg = packageMetrics.ncss + " NCSS does not meet minimum per package";
539         }
540 
541         if (failed) {
542             log(packageMetrics.name + " - " + errorMsg, Project.MSG_INFO);
543         }
544         return failed;
545     }
546 
547     /**
548      * Checks thresholds for all classes and interfaces.
549      * @param fileList the files to be analysed.
550      * @return true if a threshold has been exceeded; false otherwise.
551      */
552     private boolean classThresholdsExceeded(List<File> fileList) {
553         boolean failed = false;
554         if (!(classPerClassMax == Integer.MAX_VALUE &&
555                 classPerClassMin == -1 &&
556                 funcPerClassMax == Integer.MAX_VALUE &&
557                 funcPerClassMin == -1 &&
558                 jvdcPerClassMax == Integer.MAX_VALUE &&
559                 jvdcPerClassMin == -1 &&
560                 ncssPerClassMax == Integer.MAX_VALUE &&
561                 ncssPerClassMin == -1)) {
562             List<ObjectMetric> objMetrics = getJavaNcss(fileList).getObjectMetrics();
563             for (ObjectMetric objMetric : objMetrics) {
564                 failed = classThresholdExceeded(objMetric) || failed;
565             }
566         }
567         return failed;
568     }
569 
570     /**
571      * Checks thresholds for the specified class or interface.
572      * @param classMetrics the metrics of the class or interface under test.
573      * @return true if a threshold has been exceeded; false otherwise.
574      */
575     private boolean classThresholdExceeded(ObjectMetric classMetrics) {
576         boolean failed = false;
577         String errorMsg = "";
578 
579         int classPerClass = classMetrics.classes;
580         int funcPerClass = classMetrics.functions;
581         int ncssPerClass = classMetrics.ncss;
582         int jvdcPerClass = classMetrics.javadocs;
583 
584         if (classPerClassMax < classPerClass) {
585             failed = true;
586             errorMsg = classPerClass + " inner classes exceeds maximum per class";
587         } else if (classPerClassMin > classPerClass) {
588             failed = true;
589             errorMsg = classPerClass + " inner classes does not meet minimum per class";
590         }
591         if (funcPerClassMax < funcPerClass) {
592             failed = true;
593             errorMsg = funcPerClass + " functions exceeds maximum pre class";
594         } else if (funcPerClassMin > funcPerClass) {
595             failed = true;
596             errorMsg = funcPerClass + " functions does not meet minimum per class";
597         }
598         if (ncssPerClassMax < ncssPerClass) {
599             failed = true;
600             errorMsg = ncssPerClass + " NCSS exceeds maximum per class";
601         } else if (ncssPerClassMin > ncssPerClass) {
602             failed = true;
603             errorMsg = ncssPerClass + " NCSS does not meet minimum per class";
604         }
605         if (jvdcPerClassMax < jvdcPerClass) {
606             failed = true;
607             errorMsg = jvdcPerClass + " javadoc statements exceeds maximum per class";
608         } else if (jvdcPerClassMin > jvdcPerClass) {
609             failed = true;
610             errorMsg = jvdcPerClass + " javadoc statements does not meet minimum per class";
611         }
612 
613         if (failed) {
614             log(classMetrics.name + " - " + errorMsg, Project.MSG_INFO);
615         }
616         return failed;
617     }
618 
619     /**
620      * Checks thresholds for all functions.
621      * @param fileList the files to be analysed.
622      * @return true if a threshold has been exceeded; false otherwise.
623      */
624     private boolean functionThresholdsExceeded(List<File> fileList) {
625         boolean failed = false;
626         //check thresholds
627         if (!(jvdcPerFuncMax == Integer.MAX_VALUE &&
628                 jvdcPerFuncMin == -1 &&
629                 ccnPerFuncMax == Integer.MAX_VALUE &&
630                 ccnPerFuncMin == -1 &&
631                 ncssPerFuncMax == Integer.MAX_VALUE &&
632                 ncssPerFuncMin == -1)) {
633             //call getFunctionMetrics
634             List<FunctionMetric> funcMetrics = getJavaNcss(fileList).getFunctionMetrics();
635             for (FunctionMetric funcMetric : funcMetrics) {
636                 failed = functionThresholdExceeded(funcMetric) || failed;
637             }
638         }
639         return failed;
640     }
641 
642     /**
643      * Checks thresholds for the specified function.
644      * @param functionMetrics the metrics of the function under test.
645      * @return true if a threshold has been exceeded; false otherwise.
646      */
647     private boolean functionThresholdExceeded(FunctionMetric functionMetrics) {
648         boolean failed = false;
649         String errorMsg = "";
650 
651         int ccnPerFunc = functionMetrics.ccn;
652         int ncssPerFunc = functionMetrics.ncss;
653         int jvdcPerFunc = functionMetrics.javadocs;
654 
655         if (ccnPerFuncMax < ccnPerFunc) {
656             failed = true;
657             errorMsg = ccnPerFunc + " CCN exceeds maximum per function";
658         } else if (ccnPerFuncMin > ccnPerFunc) {
659             failed = true;
660             errorMsg = ccnPerFunc + " CCN does not meet minimum per function";
661         }
662         if (ncssPerFuncMax < ncssPerFunc) {
663             failed = true;
664             errorMsg = ncssPerFunc + " NCSS exceeds maximum per function";
665         } else if (ncssPerFuncMin > ncssPerFunc) {
666             failed = true;
667             errorMsg = ncssPerFunc + " NCSS does not meet minimum per function";
668         }
669         if (jvdcPerFuncMax < jvdcPerFunc) {
670             failed = true;
671             errorMsg = jvdcPerFunc + " javadoc statements exceeds maximum per function";
672         } else if (jvdcPerFuncMin > jvdcPerFunc) {
673             failed = true;
674             errorMsg = jvdcPerFunc + " javadoc statements does not meet minimum per function";
675         }
676 
677         if (failed) {
678             log(functionMetrics.name + " - " + errorMsg, Project.MSG_INFO);
679         }
680         return failed;
681     }
682 
683     /**
684      * Sets the maximum number of classes per package.
685      * @param classPerPkgMax the maximum number of classes per package.
686      */
687     public void setClassPerPkgMax(int classPerPkgMax) {
688         this.classPerPkgMax = classPerPkgMax;
689     }
690 
691     /**
692      * Sets the minimum number of classes per package.
693      * @param classPerPkgMin the minimum number of classes per package.
694      */
695     public void setClassPerPkgMin(int classPerPkgMin) {
696         this.classPerPkgMin = classPerPkgMin;
697     }
698 
699     /**
700      * Sets the maximum number of functions per package.
701      * @param funcPerPkgMax the maximum number of functions per package.
702      */
703     public void setFuncPerPkgMax(int funcPerPkgMax) {
704         this.funcPerPkgMax = funcPerPkgMax;
705     }
706 
707     /**
708      * Sets the minimum number of functions per package.
709      * @param funcPerPkgMin the minimum number of functions per package.
710      */
711     public void setFuncPerPkgMin(int funcPerPkgMin) {
712         this.funcPerPkgMin = funcPerPkgMin;
713     }
714 
715     /**
716      * Sets the maximum number of non-commenting source statements per package.
717      * @param ncssPerPkgMax the maximum number of non-commenting source
718      * statements per package.
719      */
720     public void setNcssPerPkgMax(int ncssPerPkgMax) {
721         this.ncssPerPkgMax = ncssPerPkgMax;
722     }
723 
724     /**
725      * Sets the minimum number of non-commenting source statements per package.
726      * @param ncssPerPkgMin the minimum number of non-commenting source
727      * statements per package.
728      */
729     public void setNcssPerPkgMin(int ncssPerPkgMin) {
730         this.ncssPerPkgMin = ncssPerPkgMin;
731     }
732 
733     /**
734      * Sets the maximum number of inner classes per class.
735      * @param classPerClassMax the maximum number of inner classes per class.
736      */
737     public void setClassPerClassMax(int classPerClassMax) {
738         this.classPerClassMax = classPerClassMax;
739     }
740 
741     /**
742      * Sets the minimum number of inner classes per class.
743      * @param classPerClassMin the minimum number of inner classes per class.
744      */
745     public void setClassPerClassMin(int classPerClassMin) {
746         this.classPerClassMin = classPerClassMin;
747     }
748 
749     /**
750      * Sets the maximum number of functions per class.
751      * @param funcPerClassMax the maximum number of functions per class.
752      */
753     public void setFuncPerClassMax(int funcPerClassMax) {
754         this.funcPerClassMax = funcPerClassMax;
755     }
756 
757     /**
758      * Sets the minimum number of functions per class.
759      * @param funcPerClassMin the minimum number of functions per class.
760      */
761     public void setFuncPerClassMin(int funcPerClassMin) {
762         this.funcPerClassMin = funcPerClassMin;
763     }
764 
765     /**
766      * Sets the maximum number of non-commenting source statements per class.
767      * @param ncssPerClassMax the maximum number of non-commenting source
768      * statements per class.
769      */
770     public void setNcssPerClassMax(int ncssPerClassMax) {
771         this.ncssPerClassMax = ncssPerClassMax;
772     }
773 
774     /**
775      * Sets the minimum number of non-commenting source statements per class.
776      * @param ncssPerClassMin the minimum number of non-commenting source
777      * statements per class.
778      */
779     public void setNcssPerClassMin(int ncssPerClassMin) {
780         this.ncssPerClassMin = ncssPerClassMin;
781     }
782 
783     /**
784      * Sets the maximum number of javadoc comments per class.
785      * @param jvdcPerClassMax the maximum number of javadoc comments per class.
786      */
787     public void setJvdcPerClassMax(int jvdcPerClassMax) {
788         this.jvdcPerClassMax = jvdcPerClassMax;
789     }
790 
791     /**
792      * Sets the minimum number of javadoc comments per class.
793      * @param jvdcPerClassMin the minimum number of javadoc comments per class.
794      */
795     public void setJvdcPerClassMin(int jvdcPerClassMin) {
796         this.jvdcPerClassMin = jvdcPerClassMin;
797     }
798 
799     /**
800      * Sets the maximum value of the Cyclomatic Complexity Number per function.
801      * @param ccnPerFuncMax the maximum value of the Cyclomatic Complexity Number
802      * per function.
803      */
804     public void setCcnPerFuncMax(int ccnPerFuncMax) {
805         this.ccnPerFuncMax = ccnPerFuncMax;
806     }
807 
808     /**
809      * Sets the minimum value of the Cyclomatic Complexity Number per function.
810      * @param ccnPerFuncMin the minimum value of the Cyclomatic Complexity Number
811      * per function.
812      */
813     public void setCcnPerFuncMin(int ccnPerFuncMin) {
814         this.ccnPerFuncMin = ccnPerFuncMin;
815     }
816 
817     /**
818      * Sets the maximum number of non-commenting source statements per function.
819      * @param ncssPerFuncMax the maximum number of non-commenting source
820      * statements per function.
821      */
822     public void setNcssPerFuncMax(int ncssPerFuncMax) {
823         this.ncssPerFuncMax = ncssPerFuncMax;
824     }
825 
826     /**
827      * Sets the minimum number of non-commenting source statements per function.
828      * @param ncssPerFuncMin the minimum number of non-commenting source
829      * statements per function.
830      */
831     public void setNcssPerFuncMin(int ncssPerFuncMin) {
832         this.ncssPerFuncMin = ncssPerFuncMin;
833     }
834 
835     /**
836      * Sets the maximum number of javadoc comments per function.
837      * @param jvdcPerFuncMax the maximum number of javadoc comments per function.
838      */
839     public void setJvdcPerFuncMax(int jvdcPerFuncMax) {
840         this.jvdcPerFuncMax = jvdcPerFuncMax;
841     }
842 
843     /**
844      * Sets the minimum number of javadoc comments per function.
845      * @param jvdcPerFuncMin the minimum number of javadoc comments per function.
846      */
847     public void setJvdcPerFuncMin(int jvdcPerFuncMin) {
848         this.jvdcPerFuncMin = jvdcPerFuncMin;
849     }
850 }