KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > cobertura > check > Main


1 /*
2  * Cobertura - http://cobertura.sourceforge.net/
3  *
4  * Copyright (C) 2003 jcoverage ltd.
5  * Copyright (C) 2005 Mark Doliner
6  * Copyright (C) 2005 Nathan Wilson
7  *
8  * Cobertura is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published
10  * by the Free Software Foundation; either version 2 of the License,
11  * or (at your option) any later version.
12  *
13  * Cobertura is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Cobertura; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21  * USA
22  */

23
24 package net.sourceforge.cobertura.check;
25
26 import java.io.File JavaDoc;
27 import java.math.BigDecimal JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.StringTokenizer JavaDoc;
32
33 import net.sourceforge.cobertura.coveragedata.ClassData;
34 import net.sourceforge.cobertura.coveragedata.CoverageDataFileHandler;
35 import net.sourceforge.cobertura.coveragedata.ProjectData;
36 import net.sourceforge.cobertura.util.Header;
37
38 import org.apache.log4j.Logger;
39 import org.apache.oro.text.regex.MalformedPatternException;
40 import org.apache.oro.text.regex.Pattern;
41 import org.apache.oro.text.regex.Perl5Compiler;
42 import org.apache.oro.text.regex.Perl5Matcher;
43
44 public class Main
45 {
46
47     private static final Logger logger = Logger.getLogger(Main.class);
48
49     final Perl5Matcher pm = new Perl5Matcher();
50
51     final Perl5Compiler pc = new Perl5Compiler();
52
53     /**
54      * The default CoverageRate needed for a class to pass the check.
55      */

56     CoverageRate minimumCoverageRate;
57
58     /**
59      * The keys of this map contain regular expression Patterns that
60      * match against classes. The values of this map contain
61      * CoverageRate objects that specify the minimum coverage rates
62      * needed for a class that matches the pattern.
63      */

64     Map JavaDoc minimumCoverageRates = new HashMap JavaDoc();
65
66     /**
67      * The keys of this map contain package names. The values of this
68      * map contain PackageCoverage objects that track the line and
69      * branch coverage values for a package.
70      */

71     Map JavaDoc packageCoverageMap = new HashMap JavaDoc();
72
73     double inRangeAndDivideByOneHundred(String JavaDoc coverageRateAsPercentage)
74     {
75         return inRangeAndDivideByOneHundred(Integer.valueOf(
76                 coverageRateAsPercentage).intValue());
77     }
78
79     double inRangeAndDivideByOneHundred(int coverageRateAsPercentage)
80     {
81         if ((coverageRateAsPercentage >= 0)
82                 && (coverageRateAsPercentage <= 100))
83         {
84             return (double)coverageRateAsPercentage / 100;
85         }
86         throw new IllegalArgumentException JavaDoc("The value "
87                 + coverageRateAsPercentage
88                 + "% is invalid. Percentages must be between 0 and 100.");
89     }
90
91     void setMinimumCoverageRate(String JavaDoc minimumCoverageRate)
92             throws MalformedPatternException
93     {
94         StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(minimumCoverageRate,
95                 ":");
96         this.minimumCoverageRates.put(pc.compile(tokenizer.nextToken()),
97                 new CoverageRate(inRangeAndDivideByOneHundred(tokenizer
98                         .nextToken()), inRangeAndDivideByOneHundred(tokenizer
99                         .nextToken())));
100     }
101
102     /**
103      * This method returns the CoverageRate object that
104      * applies to the given class. If checks if there is a
105      * pattern that matches the class name, and returns that
106      * if it finds one. Otherwise it uses the global minimum
107      * rates that were passed in.
108      */

109     CoverageRate findMinimumCoverageRate(String JavaDoc classname)
110     {
111         Iterator JavaDoc iter = this.minimumCoverageRates.entrySet().iterator();
112         while (iter.hasNext())
113         {
114             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)iter.next();
115
116             if (pm.matches(classname, (Pattern)entry.getKey()))
117             {
118                 return (CoverageRate)entry.getValue();
119             }
120         }
121         return this.minimumCoverageRate;
122     }
123
124     public Main(String JavaDoc[] args) throws MalformedPatternException
125     {
126         int exitStatus = 0;
127
128         Header.print(System.out);
129
130         File JavaDoc dataFile = CoverageDataFileHandler.getDefaultDataFile();
131         double branchCoverageRate = 0.0;
132         double lineCoverageRate = 0.0;
133         double packageBranchCoverageRate = 0.0;
134         double packageLineCoverageRate = 0.0;
135         double totalBranchCoverageRate = 0.0;
136         double totalLineCoverageRate = 0.0;
137
138         for (int i = 0; i < args.length; i++)
139         {
140             if (args[i].equals("--branch"))
141             {
142                 branchCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
143             }
144             else if (args[i].equals("--datafile"))
145             {
146                 dataFile = new File JavaDoc(args[++i]);
147             }
148             else if (args[i].equals("--line"))
149             {
150                 lineCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
151             }
152             else if (args[i].equals("--regex"))
153             {
154                 setMinimumCoverageRate(args[++i]);
155             }
156             else if (args[i].equals("--packagebranch"))
157             {
158                 packageBranchCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
159             }
160             else if (args[i].equals("--packageline"))
161             {
162                 packageLineCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
163             }
164             else if (args[i].equals("--totalbranch"))
165             {
166                 totalBranchCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
167             }
168             else if (args[i].equals("--totalline"))
169             {
170                 totalLineCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
171             }
172         }
173
174         ProjectData projectData = CoverageDataFileHandler
175                 .loadCoverageData(dataFile);
176
177         if (projectData == null)
178         {
179             System.err.println("Error: Unable to read from data file "
180                     + dataFile.getAbsolutePath());
181             System.exit(1);
182         }
183
184         // If they didn't specify any thresholds, then use some defaults
185
if ((branchCoverageRate == 0) && (lineCoverageRate == 0)
186                 && (packageLineCoverageRate == 0)
187                 && (packageBranchCoverageRate == 0)
188                 && (totalLineCoverageRate == 0)
189                 && (totalBranchCoverageRate == 0)
190                 && (this.minimumCoverageRates.size() == 0))
191         {
192             branchCoverageRate = 0.5;
193             lineCoverageRate = 0.5;
194             packageBranchCoverageRate = 0.5;
195             packageLineCoverageRate = 0.5;
196             totalBranchCoverageRate = 0.5;
197             totalLineCoverageRate = 0.5;
198         }
199
200         this.minimumCoverageRate = new CoverageRate(lineCoverageRate,
201                 branchCoverageRate);
202
203         double totalLines = 0;
204         double totalLinesCovered = 0;
205         double totalBranches = 0;
206         double totalBranchesCovered = 0;
207
208         Iterator JavaDoc iter = projectData.getClasses().iterator();
209         while (iter.hasNext())
210         {
211             ClassData classData = (ClassData)iter.next();
212             CoverageRate coverageRate = findMinimumCoverageRate(classData
213                     .getName());
214
215             if (totalBranchCoverageRate > 0.0)
216             {
217                 totalBranches += classData.getNumberOfValidBranches();
218                 totalBranchesCovered += classData.getNumberOfCoveredBranches();
219             }
220
221             if (totalLineCoverageRate > 0.0)
222             {
223                 totalLines += classData.getNumberOfValidLines();
224                 totalLinesCovered += classData.getNumberOfCoveredLines();
225             }
226
227             PackageCoverage packageCoverage = getPackageCoverage(classData
228                     .getPackageName());
229             if (packageBranchCoverageRate > 0.0)
230             {
231                 packageCoverage.addBranchCount(classData
232                         .getNumberOfValidBranches());
233                 packageCoverage.addBranchCoverage(classData
234                         .getNumberOfCoveredBranches());
235             }
236
237             if (packageLineCoverageRate > 0.0)
238             {
239                 packageCoverage.addLineCount(classData.getNumberOfValidLines());
240                 packageCoverage.addLineCoverage(classData
241                         .getNumberOfCoveredLines());
242             }
243
244             logger.debug("Class " + classData.getName()
245                     + ", line coverage rate: "
246                     + percentage(classData.getLineCoverageRate())
247                     + "%, branch coverage rate: "
248                     + percentage(classData.getBranchCoverageRate()) + "%");
249
250             if (classData.getBranchCoverageRate() < coverageRate
251                     .getBranchCoverageRate())
252             {
253                 System.err.println(classData.getName()
254                         + " failed check. Branch coverage rate of "
255                         + percentage(classData.getBranchCoverageRate())
256                         + "% is below "
257                         + percentage(coverageRate.getBranchCoverageRate())
258                         + "%");
259                 exitStatus |= 2;
260             }
261
262             if (classData.getLineCoverageRate() < coverageRate
263                     .getLineCoverageRate())
264             {
265                 System.err.println(classData.getName()
266                         + " failed check. Line coverage rate of "
267                         + percentage(classData.getLineCoverageRate())
268                         + "% is below "
269                         + percentage(coverageRate.getLineCoverageRate()) + "%");
270                 exitStatus |= 4;
271             }
272         }
273
274         exitStatus |= checkPackageCoverageLevels(packageBranchCoverageRate,
275                 packageLineCoverageRate);
276
277         // Check the rates for the overal project
278
if ((totalBranches > 0)
279                 && (totalBranchCoverageRate > (totalBranchesCovered / totalBranches)))
280         {
281             System.err
282                     .println("Project failed check. "
283                             + "Total branch coverage rate of "
284                             + percentage(totalBranchesCovered / totalBranches)
285                             + "% is below "
286                             + percentage(totalBranchCoverageRate) + "%");
287             exitStatus |= 8;
288         }
289
290         if ((totalLines > 0)
291                 && (totalLineCoverageRate > (totalLinesCovered / totalLines)))
292         {
293             System.err.println("Project failed check. "
294                     + "Total line coverage rate of "
295                     + percentage(totalLinesCovered / totalLines)
296                     + "% is below " + percentage(totalLineCoverageRate) + "%");
297             exitStatus |= 16;
298         }
299
300         System.exit(exitStatus);
301     }
302
303     private PackageCoverage getPackageCoverage(String JavaDoc packageName)
304     {
305         PackageCoverage packageCoverage = (PackageCoverage)packageCoverageMap
306                 .get(packageName);
307         if (packageCoverage == null)
308         {
309             packageCoverage = new PackageCoverage();
310             packageCoverageMap.put(packageName, packageCoverage);
311         }
312         return packageCoverage;
313     }
314
315     private int checkPackageCoverageLevels(double packageBranchCoverageRate,
316             double packageLineCoverageRate)
317     {
318         int exitStatus = 0;
319         Iterator JavaDoc iter = packageCoverageMap.entrySet().iterator();
320         while (iter.hasNext())
321         {
322             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)iter.next();
323             String JavaDoc packageName = (String JavaDoc)entry.getKey();
324             PackageCoverage packageCoverage = (PackageCoverage)entry.getValue();
325
326             exitStatus |= checkPackageCoverage(packageBranchCoverageRate,
327                     packageLineCoverageRate, packageName, packageCoverage);
328         }
329         return exitStatus;
330     }
331
332     private int checkPackageCoverage(double packageBranchCoverageRate,
333             double packageLineCoverageRate, String JavaDoc packageName,
334             PackageCoverage packageCoverage)
335     {
336         int exitStatus = 0;
337         double branchCoverage = packageCoverage.getBranchCoverage()
338                 / packageCoverage.getBranchCount();
339         if ((packageCoverage.getBranchCount() > 0)
340                 && (packageBranchCoverageRate > branchCoverage))
341         {
342             System.err.println("Package " + packageName
343                     + " failed check. Package branch coverage rate of "
344                     + percentage(branchCoverage) + "% is below "
345                     + percentage(packageBranchCoverageRate) + "%");
346             exitStatus |= 32;
347         }
348
349         double lineCoverage = packageCoverage.getLineCoverage()
350                 / packageCoverage.getLineCount();
351         if ((packageCoverage.getLineCount() > 0)
352                 && (packageLineCoverageRate > lineCoverage))
353         {
354             System.err.println("Package " + packageName
355                     + " failed check. Package line coverage rate of "
356                     + percentage(lineCoverage) + "% is below "
357                     + percentage(packageLineCoverageRate) + "%");
358             exitStatus |= 64;
359         }
360
361         return exitStatus;
362     }
363
364     private String JavaDoc percentage(double coverateRate)
365     {
366         BigDecimal JavaDoc decimal = new BigDecimal JavaDoc(coverateRate * 100);
367         return decimal.setScale(1, BigDecimal.ROUND_DOWN).toString();
368     }
369
370     public static void main(String JavaDoc[] args) throws MalformedPatternException
371     {
372         new Main(args);
373     }
374
375 }
376
Popular Tags