001    /*
002    Copyright (C) 2002 Steve Jernigan <sjernigan@iname.com>.
003    
004    This file is part of JavaNCSS2Ant and JavaNCSS
005    (http://sourceforge.net/projects/javancss2ant/ ,
006    http://www.kclee.com/clemens/java/javancss/).
007    
008    JavaNCSS2Ant and JavaNCSS are free software; you can redistribute it and/or modify it
009    under the terms of the GNU General Public License as published by the
010    Free Software Foundation; either version 2, or (at your option) any
011    later version.
012    
013    JavaNCSS2Ant and JavaNCSS are distributed in the hope that it will be useful, but WITHOUT
014    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
016    for more details.
017    
018    You should have received a copy of the GNU General Public License
019    along with JavaNCSS; see the file COPYING.  If not, write to
020    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
021    Boston, MA 02111-1307, USA.  */
022    
023    package javancss;
024    
025    import java.io.File;
026    import java.io.FileOutputStream;
027    import java.io.IOException;
028    import java.io.PrintWriter;
029    import java.util.ArrayList;
030    import java.util.List;
031    
032    import ccl.util.Util;
033    import org.apache.tools.ant.BuildException;
034    import org.apache.tools.ant.DirectoryScanner;
035    import org.apache.tools.ant.Project;
036    import org.apache.tools.ant.taskdefs.MatchingTask;
037    import org.apache.tools.ant.types.CommandlineJava;
038    import org.apache.tools.ant.types.Path;
039    
040    /**
041     * Ant task to report and check basic code metrics.
042     *
043     * <p>This task wraps the JavaNCSS library for determining code metrics. The
044     * library determines several code metrics such as object counts, non-commented
045     * source statements (NCSS), cyclomatic complexity numbers (CCN), and javadoc
046     * statements. These counts are subtotaled per function, class, and package.
047     * This task allows you to place minimum and maximum thresholds on each of these
048     * (not all of these make sense but all are included for completeness).
049     *
050     * <p>The original version of this task was written by Steve Jernigan and made
051     * available on SourceForge as the JavaNCSS2Ant project. It was subsequently
052     * extended by Phillip Wells to enable access to the report generation feature
053     * of the tool whereupon it was submitted for inclusion in Ant itself.
054     *
055     * <p>JavaNCSS was developed by Christoph Clemens Lee and is available
056     * <a href="http://www.kclee.com/clemens/java/javancss/">here</a>.
057     *
058     * @author Phillip Wells
059     * @author Steve Jernigan
060     * @author Clemens Lee
061     */
062    public class JavancssAntTask extends MatchingTask {
063        /**
064         * The command to be executed to run to tool.
065         */
066        private CommandlineJava commandline = new CommandlineJava();
067        /**
068         * Whether the build should halt if there is an error or a threshold is
069         * exceeded.
070         */
071        private boolean abortOnFail = false;
072        /**
073         * The directory containing the source files to be scanned by the tool.
074         */
075        private File srcdir;
076        /**
077         * The classpath to be used.
078         */
079        private Path classpath;
080        /**
081         * The location of the output file.
082         */
083        private File outputfile;
084        /**
085         * The format of the output file. Allowable values are 'plain' or 'xml'.
086         */
087        private String format = "plain";
088        /**
089         * Indicates the failure of the JavaNCSS process.
090         */
091        private static final int FAILURE = 1;
092        /**
093         * Indicates the success of the JavaNCSS process.
094         */
095        private static final int SUCCESS = 0;
096        /**
097         * The maximum number of classes per package.
098         */
099        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        public void execute() throws BuildException {
290            if (srcdir == null) {
291                throw new BuildException("srcdir attribute must be set!");
292            }
293            if (!srcdir.exists()) {
294                throw new BuildException("srcdir does not exist!");
295            }
296            if (!srcdir.isDirectory()) {
297                throw new BuildException("srcdir is not a directory!");
298            }
299    
300            List fileList = findFilesToAnalyse();
301    
302            // First check thresholds
303            if (thresholdsExceeded(fileList) && abortOnFail) {
304                throw new BuildException("Metric threshold value(s) surpassed");
305            }
306    
307            // Then generate report
308            int exitValue = generateReport(fileList);
309            if (exitValue == FAILURE) {
310                if (abortOnFail) {
311                    throw new BuildException("JavaNcss failed", location);
312                } else {
313                    log("JavaNcss failed", Project.MSG_ERR);
314                }
315            }
316        }
317    
318        /**
319         * Generates a report on the specified files.
320         * @param fileList the files to be analyzed.
321         * @return {@link #SUCCESS} if there were no errors; otherwise {@link #FAILURE}.
322         * @throws BuildException if an error occurs whilst generating the report.
323         */
324        private int generateReport(List fileList) {
325            // If an output file has not been specified no report should be
326            // generated
327            if (!generateReport) {
328                return SUCCESS;
329            }
330    
331            // result is in this.javancssArguments
332            log("Generating report");
333            if (outputfile != null) {
334                log("Report to be stored in " + outputfile.getPath(), Project.MSG_VERBOSE);
335            } else {
336                log("Report to be sent to standard output", Project.MSG_VERBOSE);
337            }
338            String[] javancssArguments = getCommandLineArguments(fileList);
339            log("Executing: javancss " + Util.objectsToVector(javancssArguments)
340                , 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 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 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 filesArray 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 copyFiles(String[] filesArray) {
391            List returnVector = new ArrayList(filesArray.length);
392            for (int i = 0; i < filesArray.length; i++) {
393                returnVector.add(new File(srcdir, filesArray[i]));
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(project);
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 fileList) {
414            List arguments = new ArrayList();
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] = (String) 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 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 (int i = 0; i < fileList.size(); i++) {
462                    log(fileList.get(i).toString(), 3);
463                    pw.println(fileList.get(i).toString());
464                }
465                pw.close();
466                fos.close();
467            } catch (IOException e) {
468                throw new BuildException(e, location);
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 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 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 pkgMetrics = getJavaNcss(fileList).getPackageMetrics();
504                for (int i = 0; i < pkgMetrics.size(); i++) {
505                    PackageMetric pkgMetric = (PackageMetric) pkgMetrics.get(i);
506                    failed = packageThresholdExceeded(pkgMetric) || failed;
507                }
508            }
509            return failed;
510        }
511    
512        /**
513         * Checks thresholds for the specified package.
514         * @param packageMetrics the metrics of the package under test.
515         * @return true if a threshold has been exceeded; false otherwise.
516         */
517        private boolean packageThresholdExceeded(PackageMetric packageMetrics) {
518            boolean failed = false;
519            String errorMsg = "";
520            if (classPerPkgMax < packageMetrics.classes) {
521                failed = true;
522                errorMsg = packageMetrics.classes + " classes exceeds maximum per package";
523            } else if (classPerPkgMin > packageMetrics.classes) {
524                failed = true;
525                errorMsg = packageMetrics.classes + " classes does not meet minimum per package";
526            }
527            if (funcPerPkgMax < packageMetrics.functions) {
528                failed = true;
529                errorMsg = packageMetrics.functions + " functions exceeds maximum pre package";
530            } else if (funcPerPkgMin > packageMetrics.functions) {
531                failed = true;
532                errorMsg = packageMetrics.functions + " functions does not meet minimum per package";
533            }
534            if (ncssPerPkgMax < packageMetrics.ncss) {
535                failed = true;
536                errorMsg = packageMetrics.ncss + " NCSS exceeds maximum per package";
537            } else if (ncssPerPkgMin > packageMetrics.ncss) {
538                failed = true;
539                errorMsg = packageMetrics.ncss + " NCSS does not meet minimum per package";
540            }
541    
542            if (failed) {
543                log(packageMetrics.name + " - " + errorMsg, Project.MSG_INFO);
544            }
545            return failed;
546        }
547    
548        /**
549         * Checks thresholds for all classes and interfaces.
550         * @param fileList the files to be analysed.
551         * @return true if a threshold has been exceeded; false otherwise.
552         */
553        private boolean classThresholdsExceeded(List fileList) {
554            boolean failed = false;
555            if (!((classPerClassMax == Integer.MAX_VALUE) &&
556                    (classPerClassMin == -1) &&
557                    (funcPerClassMax == Integer.MAX_VALUE) &&
558                    (funcPerClassMin == -1) &&
559                    (jvdcPerClassMax == Integer.MAX_VALUE) &&
560                    (jvdcPerClassMin == -1) &&
561                    (ncssPerClassMax == Integer.MAX_VALUE) &&
562                    (ncssPerClassMin == -1))) {
563                List objMetrics = getJavaNcss(fileList).getObjectMetrics();
564                for (int i = 0; i < objMetrics.size(); i++) {
565                    ObjectMetric objMetric = (ObjectMetric) objMetrics.get(i);
566                    failed = classThresholdExceeded(objMetric) || failed;
567                }
568            }
569            return failed;
570        }
571    
572        /**
573         * Checks thresholds for the specified class or interface.
574         * @param classMetrics the metrics of the class or interface under test.
575         * @return true if a threshold has been exceeded; false otherwise.
576         */
577        private boolean classThresholdExceeded(ObjectMetric classMetrics) {
578            boolean failed = false;
579            String errorMsg = "";
580    
581            int classPerClass = classMetrics.classes;
582            int funcPerClass = classMetrics.functions;
583            int ncssPerClass = classMetrics.ncss;
584            int jvdcPerClass = classMetrics.javadocs;
585    
586            if (classPerClassMax < classPerClass) {
587                failed = true;
588                errorMsg = classPerClass + " inner classes exceeds maximum per class";
589            } else if (classPerClassMin > classPerClass) {
590                failed = true;
591                errorMsg = classPerClass + " inner classes does not meet minimum per class";
592            }
593            if (funcPerClassMax < funcPerClass) {
594                failed = true;
595                errorMsg = funcPerClass + " functions exceeds maximum pre class";
596            } else if (funcPerClassMin > funcPerClass) {
597                failed = true;
598                errorMsg = funcPerClass + " functions does not meet minimum per class";
599            }
600            if (ncssPerClassMax < ncssPerClass) {
601                failed = true;
602                errorMsg = ncssPerClass + " NCSS exceeds maximum per class";
603            } else if (ncssPerClassMin > ncssPerClass) {
604                failed = true;
605                errorMsg = ncssPerClass + " NCSS does not meet minimum per class";
606            }
607            if (jvdcPerClassMax < jvdcPerClass) {
608                failed = true;
609                errorMsg = jvdcPerClass + " javadoc statements exceeds maximum per class";
610            } else if (jvdcPerClassMin > jvdcPerClass) {
611                failed = true;
612                errorMsg = jvdcPerClass + " javadoc statements does not meet minimum per class";
613            }
614    
615            if (failed) {
616                log(classMetrics.name + " - " + errorMsg, Project.MSG_INFO);
617            }
618            return failed;
619        }
620    
621        /**
622         * Checks thresholds for all functions.
623         * @param fileList the files to be analysed.
624         * @return true if a threshold has been exceeded; false otherwise.
625         */
626        private boolean functionThresholdsExceeded(List fileList) {
627            boolean failed = false;
628            //check thresholds
629            if (!((jvdcPerFuncMax == Integer.MAX_VALUE) &&
630                    (jvdcPerFuncMin == -1) &&
631                    (ccnPerFuncMax == Integer.MAX_VALUE) &&
632                    (ccnPerFuncMin == -1) &&
633                    (ncssPerFuncMax == Integer.MAX_VALUE) &&
634                    (ncssPerFuncMin == -1))) {
635                //call getFunctionMetrics
636                List funcMetrics = getJavaNcss(fileList).getFunctionMetrics();
637                for (int i = 0; i < funcMetrics.size(); i++) {
638                    FunctionMetric funcMetric = (FunctionMetric) funcMetrics.get(i);
639                    failed = functionThresholdExceeded(funcMetric) || failed;
640                }
641            }
642            return failed;
643        }
644    
645        /**
646         * Checks thresholds for the specified function.
647         * @param functionMetrics the metrics of the function under test.
648         * @return true if a threshold has been exceeded; false otherwise.
649         */
650        private boolean functionThresholdExceeded(FunctionMetric functionMetrics) {
651            boolean failed = false;
652            String errorMsg = "";
653    
654            int ccnPerFunc = functionMetrics.ccn;
655            int ncssPerFunc = functionMetrics.ncss;
656            int jvdcPerFunc = functionMetrics.javadocs;
657    
658            if (ccnPerFuncMax < ccnPerFunc) {
659                failed = true;
660                errorMsg = ccnPerFunc + " CCN exceeds maximum per function";
661            } else if (ccnPerFuncMin > ccnPerFunc) {
662                failed = true;
663                errorMsg = ccnPerFunc + " CCN does not meet minimum per function";
664            }
665            if (ncssPerFuncMax < ncssPerFunc) {
666                failed = true;
667                errorMsg = ncssPerFunc + " NCSS exceeds maximum per function";
668            } else if (ncssPerFuncMin > ncssPerFunc) {
669                failed = true;
670                errorMsg = ncssPerFunc + " NCSS does not meet minimum per function";
671            }
672            if (jvdcPerFuncMax < jvdcPerFunc) {
673                failed = true;
674                errorMsg = jvdcPerFunc + " javadoc statements exceeds maximum per function";
675            } else if (jvdcPerFuncMin > jvdcPerFunc) {
676                failed = true;
677                errorMsg = jvdcPerFunc + " javadoc statements does not meet minimum per function";
678            }
679    
680            if (failed) {
681                log(functionMetrics.name + " - " + errorMsg, Project.MSG_INFO);
682            }
683            return failed;
684        }
685    
686        /**
687         * Sets the maximum number of classes per package.
688         * @param classPerPkgMax the maximum number of classes per package.
689         */
690        public void setClassPerPkgMax(int classPerPkgMax) {
691            this.classPerPkgMax = classPerPkgMax;
692        }
693    
694        /**
695         * Sets the minimum number of classes per package.
696         * @param classPerPkgMin the minimum number of classes per package.
697         */
698        public void setClassPerPkgMin(int classPerPkgMin) {
699            this.classPerPkgMin = classPerPkgMin;
700        }
701    
702        /**
703         * Sets the maximum number of functions per package.
704         * @param funcPerPkgMax the maximum number of functions per package.
705         */
706        public void setFuncPerPkgMax(int funcPerPkgMax) {
707            this.funcPerPkgMax = funcPerPkgMax;
708        }
709    
710        /**
711         * Sets the minimum number of functions per package.
712         * @param funcPerPkgMin the minimum number of functions per package.
713         */
714        public void setFuncPerPkgMin(int funcPerPkgMin) {
715            this.funcPerPkgMin = funcPerPkgMin;
716        }
717    
718        /**
719         * Sets the maximum number of non-commenting source statements per package.
720         * @param ncssPerPkgMax the maximum number of non-commenting source
721         * statements per package.
722         */
723        public void setNcssPerPkgMax(int ncssPerPkgMax) {
724            this.ncssPerPkgMax = ncssPerPkgMax;
725        }
726    
727        /**
728         * Sets the minimum number of non-commenting source statements per package.
729         * @param ncssPerPkgMin the minimum number of non-commenting source
730         * statements per package.
731         */
732        public void setNcssPerPkgMin(int ncssPerPkgMin) {
733            this.ncssPerPkgMin = ncssPerPkgMin;
734        }
735    
736        /**
737         * Sets the maximum number of inner classes per class.
738         * @param classPerClassMax the maximum number of inner classes per class.
739         */
740        public void setClassPerClassMax(int classPerClassMax) {
741            this.classPerClassMax = classPerClassMax;
742        }
743    
744        /**
745         * Sets the minimum number of inner classes per class.
746         * @param classPerClassMin the minimum number of inner classes per class.
747         */
748        public void setClassPerClassMin(int classPerClassMin) {
749            this.classPerClassMin = classPerClassMin;
750        }
751    
752        /**
753         * Sets the maximum number of functions per class.
754         * @param funcPerClassMax the maximum number of functions per class.
755         */
756        public void setFuncPerClassMax(int funcPerClassMax) {
757            this.funcPerClassMax = funcPerClassMax;
758        }
759    
760        /**
761         * Sets the minimum number of functions per class.
762         * @param funcPerClassMin the minimum number of functions per class.
763         */
764        public void setFuncPerClassMin(int funcPerClassMin) {
765            this.funcPerClassMin = funcPerClassMin;
766        }
767    
768        /**
769         * Sets the maximum number of non-commenting source statements per class.
770         * @param ncssPerClassMax the maximum number of non-commenting source
771         * statements per class.
772         */
773        public void setNcssPerClassMax(int ncssPerClassMax) {
774            this.ncssPerClassMax = ncssPerClassMax;
775        }
776    
777        /**
778         * Sets the minimum number of non-commenting source statements per class.
779         * @param ncssPerClassMin the minimum number of non-commenting source
780         * statements per class.
781         */
782        public void setNcssPerClassMin(int ncssPerClassMin) {
783            this.ncssPerClassMin = ncssPerClassMin;
784        }
785    
786        /**
787         * Sets the maximum number of javadoc comments per class.
788         * @param jvdcPerClassMax the maximum number of javadoc comments per class.
789         */
790        public void setJvdcPerClassMax(int jvdcPerClassMax) {
791            this.jvdcPerClassMax = jvdcPerClassMax;
792        }
793    
794        /**
795         * Sets the minimum number of javadoc comments per class.
796         * @param jvdcPerClassMin the minimum number of javadoc comments per class.
797         */
798        public void setJvdcPerClassMin(int jvdcPerClassMin) {
799            this.jvdcPerClassMin = jvdcPerClassMin;
800        }
801    
802        /**
803         * Sets the maximum value of the Cyclomatic Complexity Number per function.
804         * @param ccnPerFuncMax the maximum value of the Cyclomatic Complexity Number
805         * per function.
806         */
807        public void setCcnPerFuncMax(int ccnPerFuncMax) {
808            this.ccnPerFuncMax = ccnPerFuncMax;
809        }
810    
811        /**
812         * Sets the minimum value of the Cyclomatic Complexity Number per function.
813         * @param ccnPerFuncMin the minimum value of the Cyclomatic Complexity Number
814         * per function.
815         */
816        public void setCcnPerFuncMin(int ccnPerFuncMin) {
817            this.ccnPerFuncMin = ccnPerFuncMin;
818        }
819    
820        /**
821         * Sets the maximum number of non-commenting source statements per function.
822         * @param ncssPerFuncMax the maximum number of non-commenting source
823         * statements per function.
824         */
825        public void setNcssPerFuncMax(int ncssPerFuncMax) {
826            this.ncssPerFuncMax = ncssPerFuncMax;
827        }
828    
829        /**
830         * Sets the minimum number of non-commenting source statements per function.
831         * @param ncssPerFuncMin the minimum number of non-commenting source
832         * statements per function.
833         */
834        public void setNcssPerFuncMin(int ncssPerFuncMin) {
835            this.ncssPerFuncMin = ncssPerFuncMin;
836        }
837    
838        /**
839         * Sets the maximum number of javadoc comments per function.
840         * @param jvdcPerFuncMax the maximum number of javadoc comments per function.
841         */
842        public void setJvdcPerFuncMax(int jvdcPerFuncMax) {
843            this.jvdcPerFuncMax = jvdcPerFuncMax;
844        }
845    
846        /**
847         * Sets the minimum number of javadoc comments per function.
848         * @param jvdcPerFuncMin the minimum number of javadoc comments per function.
849         */
850        public void setJvdcPerFuncMin(int jvdcPerFuncMin) {
851            this.jvdcPerFuncMin = jvdcPerFuncMin;
852        }
853    }