alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Cobertura example source code file (Main.java)

This example Cobertura source code file (Main.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Cobertura tags/keywords

bigdecimal, coveragerate, coveragerate, file, io, iterator, iterator, main, malformedpatternexception, math, packagecoverage, packagecoverage, perl5compiler, string, string, total, util

The Cobertura Main.java source code

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

package net.sourceforge.cobertura.check;

import java.io.File;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

import net.sourceforge.cobertura.coveragedata.ClassData;
import net.sourceforge.cobertura.coveragedata.CoverageDataFileHandler;
import net.sourceforge.cobertura.coveragedata.ProjectData;
import net.sourceforge.cobertura.util.Header;

import org.apache.log4j.Logger;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;

public class Main
{

	private static final Logger logger = Logger.getLogger(Main.class);

	final Perl5Matcher pm = new Perl5Matcher();

	final Perl5Compiler pc = new Perl5Compiler();

	/**
	 * The default CoverageRate needed for a class to pass the check.
	 */
	CoverageRate minimumCoverageRate;

	/**
	 * The keys of this map contain regular expression Patterns that
	 * match against classes.  The values of this map contain
	 * CoverageRate objects that specify the minimum coverage rates
	 * needed for a class that matches the pattern.
	 */
	Map minimumCoverageRates = new HashMap();

	/**
	 * The keys of this map contain package names. The values of this 
	 * map contain PackageCoverage objects that track the line and
	 * branch coverage values for a package.
	 */
	Map packageCoverageMap = new HashMap();

	double inRangeAndDivideByOneHundred(String coverageRateAsPercentage)
	{
		return inRangeAndDivideByOneHundred(Integer.valueOf(
				coverageRateAsPercentage).intValue());
	}

	double inRangeAndDivideByOneHundred(int coverageRateAsPercentage)
	{
		if ((coverageRateAsPercentage >= 0)
				&& (coverageRateAsPercentage <= 100))
		{
			return (double)coverageRateAsPercentage / 100;
		}
		throw new IllegalArgumentException("The value "
				+ coverageRateAsPercentage
				+ "% is invalid.  Percentages must be between 0 and 100.");
	}

	void setMinimumCoverageRate(String minimumCoverageRate)
			throws MalformedPatternException
	{
		StringTokenizer tokenizer = new StringTokenizer(minimumCoverageRate,
				":");
		this.minimumCoverageRates.put(pc.compile(tokenizer.nextToken()),
				new CoverageRate(inRangeAndDivideByOneHundred(tokenizer
						.nextToken()), inRangeAndDivideByOneHundred(tokenizer
						.nextToken())));
	}

	/**
	 * This method returns the CoverageRate object that
	 * applies to the given class.  If checks if there is a
	 * pattern that matches the class name, and returns that
	 * if it finds one.  Otherwise it uses the global minimum
	 * rates that were passed in.
	 */
	CoverageRate findMinimumCoverageRate(String classname)
	{
		Iterator iter = this.minimumCoverageRates.entrySet().iterator();
		while (iter.hasNext())
		{
			Map.Entry entry = (Map.Entry)iter.next();

			if (pm.matches(classname, (Pattern)entry.getKey()))
			{
				return (CoverageRate)entry.getValue();
			}
		}
		return this.minimumCoverageRate;
	}

	public Main(String[] args) throws MalformedPatternException
	{
		int exitStatus = 0;

		Header.print(System.out);

		File dataFile = CoverageDataFileHandler.getDefaultDataFile();
		double branchCoverageRate = -1.0;
		double lineCoverageRate = -1.0;
		double packageBranchCoverageRate = -1.0;
		double packageLineCoverageRate = -1.0;
		double totalBranchCoverageRate = -1.0;
		double totalLineCoverageRate = -1.0;

		for (int i = 0; i < args.length; i++)
		{
			if (args[i].equals("--branch"))
			{
				branchCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
			}
			else if (args[i].equals("--datafile"))
			{
				dataFile = new File(args[++i]);
			}
			else if (args[i].equals("--line"))
			{
				lineCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
			}
			else if (args[i].equals("--regex"))
			{
				setMinimumCoverageRate(args[++i]);
			}
			else if (args[i].equals("--packagebranch"))
			{
				packageBranchCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
			}
			else if (args[i].equals("--packageline"))
			{
				packageLineCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
			}
			else if (args[i].equals("--totalbranch"))
			{
				totalBranchCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
			}
			else if (args[i].equals("--totalline"))
			{
				totalLineCoverageRate = inRangeAndDivideByOneHundred(args[++i]);
			}
		}

		ProjectData projectData = CoverageDataFileHandler
				.loadCoverageData(dataFile);

		if (projectData == null)
		{
			System.err.println("Error: Unable to read from data file "
					+ dataFile.getAbsolutePath());
			System.exit(1);
		}

		// If they didn't specify any thresholds, then use some defaults
		if ((branchCoverageRate == -1.0) && (lineCoverageRate == -1.0)
				&& (packageLineCoverageRate == -1.0)
				&& (packageBranchCoverageRate == -1.0)
				&& (totalLineCoverageRate == -1.0)
				&& (totalBranchCoverageRate == -1.0)
				&& (this.minimumCoverageRates.size() == 0))
		{
			branchCoverageRate = 0.5;
			lineCoverageRate = 0.5;
			packageBranchCoverageRate = 0.5;
			packageLineCoverageRate = 0.5;
			totalBranchCoverageRate = 0.5;
			totalLineCoverageRate = 0.5;
		}
		// If they specified one or more thresholds, default everything else to 0
		else
		{
			if (branchCoverageRate == -1.0)
				branchCoverageRate = 0.0;
			if (lineCoverageRate == -1.0)
				lineCoverageRate = 0.0;
			if (packageLineCoverageRate == -1.0)
				packageLineCoverageRate = 0.0;
			if (packageBranchCoverageRate == -1.0)
				packageBranchCoverageRate = 0.0;
			if (totalLineCoverageRate == -1.0)
				totalLineCoverageRate = 0.0;
			if (totalBranchCoverageRate == -1.0)
				totalBranchCoverageRate = 0.0;
		}

		this.minimumCoverageRate = new CoverageRate(lineCoverageRate,
				branchCoverageRate);

		double totalLines = 0;
		double totalLinesCovered = 0;
		double totalBranches = 0;
		double totalBranchesCovered = 0;

		Iterator iter = projectData.getClasses().iterator();
		while (iter.hasNext())
		{
			ClassData classData = (ClassData)iter.next();
			CoverageRate coverageRate = findMinimumCoverageRate(classData
					.getName());

			if (totalBranchCoverageRate > 0.0)
			{
				totalBranches += classData.getNumberOfValidBranches();
				totalBranchesCovered += classData.getNumberOfCoveredBranches();
			}

			if (totalLineCoverageRate > 0.0)
			{
				totalLines += classData.getNumberOfValidLines();
				totalLinesCovered += classData.getNumberOfCoveredLines();
			}

			PackageCoverage packageCoverage = getPackageCoverage(classData
					.getPackageName());
			if (packageBranchCoverageRate > 0.0)
			{
				packageCoverage.addBranchCount(classData
						.getNumberOfValidBranches());
				packageCoverage.addBranchCoverage(classData
						.getNumberOfCoveredBranches());
			}

			if (packageLineCoverageRate > 0.0)
			{
				packageCoverage.addLineCount(classData.getNumberOfValidLines());
				packageCoverage.addLineCoverage(classData
						.getNumberOfCoveredLines());
			}

			logger.debug("Class " + classData.getName()
					+ ", line coverage rate: "
					+ percentage(classData.getLineCoverageRate())
					+ "%, branch coverage rate: "
					+ percentage(classData.getBranchCoverageRate()) + "%");

			if (classData.getBranchCoverageRate() < coverageRate
					.getBranchCoverageRate())
			{
				System.err.println(classData.getName()
						+ " failed check. Branch coverage rate of "
						+ percentage(classData.getBranchCoverageRate())
						+ "% is below "
						+ percentage(coverageRate.getBranchCoverageRate())
						+ "%");
				exitStatus |= 2;
			}

			if (classData.getLineCoverageRate() < coverageRate
					.getLineCoverageRate())
			{
				System.err.println(classData.getName()
						+ " failed check. Line coverage rate of "
						+ percentage(classData.getLineCoverageRate())
						+ "% is below "
						+ percentage(coverageRate.getLineCoverageRate()) + "%");
				exitStatus |= 4;
			}
		}

		exitStatus |= checkPackageCoverageLevels(packageBranchCoverageRate,
				packageLineCoverageRate);

		// Check the rates for the overall project
		if ((totalBranches > 0)
				&& (totalBranchCoverageRate > (totalBranchesCovered / totalBranches)))
		{
			System.err
					.println("Project failed check. "
							+ "Total branch coverage rate of "
							+ percentage(totalBranchesCovered / totalBranches)
							+ "% is below "
							+ percentage(totalBranchCoverageRate) + "%");
			exitStatus |= 8;
		}

		if ((totalLines > 0)
				&& (totalLineCoverageRate > (totalLinesCovered / totalLines)))
		{
			System.err.println("Project failed check. "
					+ "Total line coverage rate of "
					+ percentage(totalLinesCovered / totalLines)
					+ "% is below " + percentage(totalLineCoverageRate) + "%");
			exitStatus |= 16;
		}

		System.exit(exitStatus);
	}

	private PackageCoverage getPackageCoverage(String packageName)
	{
		PackageCoverage packageCoverage = (PackageCoverage)packageCoverageMap
				.get(packageName);
		if (packageCoverage == null)
		{
			packageCoverage = new PackageCoverage();
			packageCoverageMap.put(packageName, packageCoverage);
		}
		return packageCoverage;
	}

	private int checkPackageCoverageLevels(double packageBranchCoverageRate,
			double packageLineCoverageRate)
	{
		int exitStatus = 0;
		Iterator iter = packageCoverageMap.entrySet().iterator();
		while (iter.hasNext())
		{
			Map.Entry entry = (Map.Entry)iter.next();
			String packageName = (String)entry.getKey();
			PackageCoverage packageCoverage = (PackageCoverage)entry.getValue();

			exitStatus |= checkPackageCoverage(packageBranchCoverageRate,
					packageLineCoverageRate, packageName, packageCoverage);
		}
		return exitStatus;
	}

	private int checkPackageCoverage(double packageBranchCoverageRate,
			double packageLineCoverageRate, String packageName,
			PackageCoverage packageCoverage)
	{
		int exitStatus = 0;
		double branchCoverage = packageCoverage.getBranchCoverage()
				/ packageCoverage.getBranchCount();
		if ((packageCoverage.getBranchCount() > 0)
				&& (packageBranchCoverageRate > branchCoverage))
		{
			System.err.println("Package " + packageName
					+ " failed check. Package branch coverage rate of "
					+ percentage(branchCoverage) + "% is below "
					+ percentage(packageBranchCoverageRate) + "%");
			exitStatus |= 32;
		}

		double lineCoverage = packageCoverage.getLineCoverage()
				/ packageCoverage.getLineCount();
		if ((packageCoverage.getLineCount() > 0)
				&& (packageLineCoverageRate > lineCoverage))
		{
			System.err.println("Package " + packageName
					+ " failed check. Package line coverage rate of "
					+ percentage(lineCoverage) + "% is below "
					+ percentage(packageLineCoverageRate) + "%");
			exitStatus |= 64;
		}

		return exitStatus;
	}

	private String percentage(double coverateRate)
	{
		BigDecimal decimal = new BigDecimal(coverateRate * 100);
		return decimal.setScale(1, BigDecimal.ROUND_DOWN).toString();
	}

	public static void main(String[] args) throws MalformedPatternException
	{
		new Main(args);
	}

}

Other Cobertura examples (source code examples)

Here is a short list of links related to this Cobertura Main.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.