BundleChecker.java revision 55fae171b754e20062fae7cdb2d5feae8ee54017
1/*******************************************************************************
2 * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 *    Marc R. Hoffmann - initial API and implementation
10 *
11 *******************************************************************************/
12package org.jacoco.report.check;
13
14import java.util.ArrayList;
15import java.util.Collection;
16
17import org.jacoco.core.analysis.IBundleCoverage;
18import org.jacoco.core.analysis.IClassCoverage;
19import org.jacoco.core.analysis.ICoverageNode;
20import org.jacoco.core.analysis.IMethodCoverage;
21import org.jacoco.core.analysis.IPackageCoverage;
22import org.jacoco.core.analysis.ISourceFileCoverage;
23import org.jacoco.report.ILanguageNames;
24
25/**
26 * Internal class to check a list of rules against a {@link IBundleCoverage}
27 * instance.
28 */
29class BundleChecker {
30
31	private final ILanguageNames names;
32	private final IViolationsOutput output;
33
34	private final Collection<Rule> bundleRules;
35	private final Collection<Rule> packageRules;
36	private final Collection<Rule> classRules;
37	private final ArrayList<Rule> sourceFileRules;
38	private final Collection<Rule> methodRules;
39
40	private final boolean traversePackages;
41	private final boolean traverseClasses;
42	private final boolean traverseSourceFiles;
43	private final boolean traverseMethods;
44
45	public BundleChecker(final Collection<Rule> rules,
46			final ILanguageNames names, final IViolationsOutput output) {
47		this.names = names;
48		this.output = output;
49		this.bundleRules = new ArrayList<Rule>();
50		this.packageRules = new ArrayList<Rule>();
51		this.classRules = new ArrayList<Rule>();
52		this.sourceFileRules = new ArrayList<Rule>();
53		this.methodRules = new ArrayList<Rule>();
54		for (final Rule rule : rules) {
55			switch (rule.getElement()) {
56			case BUNDLE:
57				bundleRules.add(rule);
58				break;
59			case PACKAGE:
60				packageRules.add(rule);
61				break;
62			case CLASS:
63				classRules.add(rule);
64				break;
65			case SOURCEFILE:
66				sourceFileRules.add(rule);
67				break;
68			case METHOD:
69				methodRules.add(rule);
70				break;
71			}
72		}
73		traverseMethods = !methodRules.isEmpty();
74		traverseClasses = !classRules.isEmpty() || traverseMethods;
75		traverseSourceFiles = !sourceFileRules.isEmpty();
76		traversePackages = !packageRules.isEmpty() || traverseClasses
77				|| traverseSourceFiles;
78	}
79
80	public void checkBundle(final IBundleCoverage bundleCoverage) {
81		final String name = bundleCoverage.getName();
82		checkRules(bundleCoverage, bundleRules, "bundle", name);
83		if (traversePackages) {
84			for (final IPackageCoverage p : bundleCoverage.getPackages()) {
85				check(p);
86			}
87		}
88	}
89
90	private void check(final IPackageCoverage packageCoverage) {
91		final String name = names.getPackageName(packageCoverage.getName());
92		checkRules(packageCoverage, packageRules, "package", name);
93		if (traverseClasses) {
94			for (final IClassCoverage c : packageCoverage.getClasses()) {
95				check(c);
96			}
97		}
98		if (traverseSourceFiles) {
99			for (final ISourceFileCoverage s : packageCoverage.getSourceFiles()) {
100				check(s);
101			}
102		}
103	}
104
105	private void check(final IClassCoverage classCoverage) {
106		final String name = names
107				.getQualifiedClassName(classCoverage.getName());
108		checkRules(classCoverage, classRules, "class", name);
109		if (traverseMethods) {
110			for (final IMethodCoverage m : classCoverage.getMethods()) {
111				check(m, classCoverage.getName());
112			}
113		}
114	}
115
116	private void check(final ISourceFileCoverage sourceFile) {
117		final String name = sourceFile.getPackageName() + "/"
118				+ sourceFile.getName();
119		checkRules(sourceFile, sourceFileRules, "source file", name);
120	}
121
122	private void check(final IMethodCoverage method, final String className) {
123		final String name = names.getQualifiedMethodName(className,
124				method.getName(), method.getDesc(), method.getSignature());
125		checkRules(method, methodRules, "method", name);
126	}
127
128	private void checkRules(final ICoverageNode node,
129			final Collection<Rule> rules, final String typename,
130			final String elementname) {
131		for (final Rule rule : rules) {
132			if (rule.matches(elementname)) {
133				for (final Limit limit : rule.getLimits()) {
134					checkLimit(node, typename, elementname, rule, limit);
135				}
136			}
137		}
138	}
139
140	private void checkLimit(final ICoverageNode node, final String elementtype,
141			final String typename, final Rule rule, final Limit limit) {
142		final String message = limit.check(node);
143		if (message != null) {
144			output.onViolation(node, rule, limit, String.format(
145					"Rule violated for %s %s: %s", elementtype, typename,
146					message));
147		}
148	}
149
150}
151