1 /******************************************************************************* 2 * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors 3 * This program and the accompanying materials are made available under 4 * the terms of the Eclipse Public License 2.0 which is available at 5 * http://www.eclipse.org/legal/epl-2.0 6 * 7 * SPDX-License-Identifier: EPL-2.0 8 * 9 * Contributors: 10 * Marc R. Hoffmann - initial API and implementation 11 * 12 *******************************************************************************/ 13 package org.jacoco.core.internal.analysis; 14 15 import java.util.ArrayList; 16 import java.util.Collection; 17 import java.util.Collections; 18 import java.util.HashMap; 19 import java.util.HashSet; 20 import java.util.Map; 21 import java.util.Set; 22 23 import org.jacoco.core.analysis.CoverageNodeImpl; 24 import org.jacoco.core.analysis.IBundleCoverage; 25 import org.jacoco.core.analysis.IClassCoverage; 26 import org.jacoco.core.analysis.IPackageCoverage; 27 import org.jacoco.core.analysis.ISourceFileCoverage; 28 29 /** 30 * Implementation of {@link IBundleCoverage}. 31 */ 32 public class BundleCoverageImpl extends CoverageNodeImpl 33 implements IBundleCoverage { 34 35 private final Collection<IPackageCoverage> packages; 36 37 /** 38 * Creates a new instance of a bundle with the given name. 39 * 40 * @param name 41 * name of this bundle 42 * @param packages 43 * collection of all packages contained in this bundle 44 */ BundleCoverageImpl(final String name, final Collection<IPackageCoverage> packages)45 public BundleCoverageImpl(final String name, 46 final Collection<IPackageCoverage> packages) { 47 super(ElementType.BUNDLE, name); 48 this.packages = packages; 49 increment(packages); 50 } 51 52 /** 53 * Creates a new instance of a bundle with the given name. The packages are 54 * calculated from the given classes and source files. 55 * 56 * @param name 57 * name of this bundle 58 * @param classes 59 * all classes in this bundle 60 * @param sourcefiles 61 * all source files in this bundle 62 */ BundleCoverageImpl(final String name, final Collection<IClassCoverage> classes, final Collection<ISourceFileCoverage> sourcefiles)63 public BundleCoverageImpl(final String name, 64 final Collection<IClassCoverage> classes, 65 final Collection<ISourceFileCoverage> sourcefiles) { 66 this(name, groupByPackage(classes, sourcefiles)); 67 } 68 groupByPackage( final Collection<IClassCoverage> classes, final Collection<ISourceFileCoverage> sourcefiles)69 private static Collection<IPackageCoverage> groupByPackage( 70 final Collection<IClassCoverage> classes, 71 final Collection<ISourceFileCoverage> sourcefiles) { 72 final Map<String, Collection<IClassCoverage>> classesByPackage = new HashMap<String, Collection<IClassCoverage>>(); 73 for (final IClassCoverage c : classes) { 74 addByName(classesByPackage, c.getPackageName(), c); 75 } 76 77 final Map<String, Collection<ISourceFileCoverage>> sourceFilesByPackage = new HashMap<String, Collection<ISourceFileCoverage>>(); 78 for (final ISourceFileCoverage s : sourcefiles) { 79 addByName(sourceFilesByPackage, s.getPackageName(), s); 80 } 81 82 final Set<String> packageNames = new HashSet<String>(); 83 packageNames.addAll(classesByPackage.keySet()); 84 packageNames.addAll(sourceFilesByPackage.keySet()); 85 86 final Collection<IPackageCoverage> result = new ArrayList<IPackageCoverage>(); 87 for (final String name : packageNames) { 88 Collection<IClassCoverage> c = classesByPackage.get(name); 89 if (c == null) { 90 c = Collections.emptyList(); 91 } 92 Collection<ISourceFileCoverage> s = sourceFilesByPackage.get(name); 93 if (s == null) { 94 s = Collections.emptyList(); 95 } 96 result.add(new PackageCoverageImpl(name, c, s)); 97 } 98 return result; 99 } 100 addByName(final Map<String, Collection<T>> map, final String name, final T value)101 private static <T> void addByName(final Map<String, Collection<T>> map, 102 final String name, final T value) { 103 Collection<T> list = map.get(name); 104 if (list == null) { 105 list = new ArrayList<T>(); 106 map.put(name, list); 107 } 108 list.add(value); 109 } 110 111 // === IBundleCoverage implementation === 112 getPackages()113 public Collection<IPackageCoverage> getPackages() { 114 return packages; 115 } 116 117 } 118