/******************************************************************************* * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Marc R. Hoffmann - initial API and implementation * *******************************************************************************/ package org.jacoco.report.check; import java.util.ArrayList; import java.util.Collection; import org.jacoco.core.analysis.IBundleCoverage; import org.jacoco.core.analysis.IClassCoverage; import org.jacoco.core.analysis.ICoverageNode; import org.jacoco.core.analysis.IMethodCoverage; import org.jacoco.core.analysis.IPackageCoverage; import org.jacoco.core.analysis.ISourceFileCoverage; import org.jacoco.report.ILanguageNames; /** * Internal class to check a list of rules against a {@link IBundleCoverage} * instance. */ class BundleChecker { private final ILanguageNames names; private final IViolationsOutput output; private final Collection bundleRules; private final Collection packageRules; private final Collection classRules; private final Collection sourceFileRules; private final Collection methodRules; private final boolean traversePackages; private final boolean traverseClasses; private final boolean traverseSourceFiles; private final boolean traverseMethods; public BundleChecker(final Collection rules, final ILanguageNames names, final IViolationsOutput output) { this.names = names; this.output = output; this.bundleRules = new ArrayList(); this.packageRules = new ArrayList(); this.classRules = new ArrayList(); this.sourceFileRules = new ArrayList(); this.methodRules = new ArrayList(); for (final Rule rule : rules) { switch (rule.getElement()) { case BUNDLE: bundleRules.add(rule); break; case PACKAGE: packageRules.add(rule); break; case CLASS: classRules.add(rule); break; case SOURCEFILE: sourceFileRules.add(rule); break; case METHOD: methodRules.add(rule); break; } } traverseMethods = !methodRules.isEmpty(); traverseClasses = !classRules.isEmpty() || traverseMethods; traverseSourceFiles = !sourceFileRules.isEmpty(); traversePackages = !packageRules.isEmpty() || traverseClasses || traverseSourceFiles; } public void checkBundle(final IBundleCoverage bundleCoverage) { final String name = bundleCoverage.getName(); checkRules(bundleCoverage, bundleRules, "bundle", name); if (traversePackages) { for (final IPackageCoverage p : bundleCoverage.getPackages()) { check(p); } } } private void check(final IPackageCoverage packageCoverage) { final String name = names.getPackageName(packageCoverage.getName()); checkRules(packageCoverage, packageRules, "package", name); if (traverseClasses) { for (final IClassCoverage c : packageCoverage.getClasses()) { check(c); } } if (traverseSourceFiles) { for (final ISourceFileCoverage s : packageCoverage.getSourceFiles()) { check(s); } } } private void check(final IClassCoverage classCoverage) { final String name = names .getQualifiedClassName(classCoverage.getName()); checkRules(classCoverage, classRules, "class", name); if (traverseMethods) { for (final IMethodCoverage m : classCoverage.getMethods()) { check(m, classCoverage.getName()); } } } private void check(final ISourceFileCoverage sourceFile) { final String name = sourceFile.getPackageName() + "/" + sourceFile.getName(); checkRules(sourceFile, sourceFileRules, "source file", name); } private void check(final IMethodCoverage method, final String className) { final String name = names.getQualifiedMethodName(className, method.getName(), method.getDesc(), method.getSignature()); checkRules(method, methodRules, "method", name); } private void checkRules(final ICoverageNode node, final Collection rules, final String typename, final String elementname) { for (final Rule rule : rules) { if (rule.matches(elementname)) { for (final Limit limit : rule.getLimits()) { checkLimit(node, typename, elementname, rule, limit); } } } } private void checkLimit(final ICoverageNode node, final String elementtype, final String typename, final Rule rule, final Limit limit) { final String message = limit.check(node); if (message != null) { output.onViolation(node, rule, limit, String.format( "Rule violated for %s %s: %s", elementtype, typename, message)); } } }