1/*******************************************************************************
2 * Copyright (c) 2009, 2015 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.core.analysis;
13
14import java.io.Serializable;
15import java.util.ArrayList;
16import java.util.Collection;
17import java.util.Collections;
18import java.util.Comparator;
19import java.util.List;
20
21import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
22
23/**
24 * Comparator to compare {@link ICoverageNode} objects by different counter
25 * criteria.
26 *
27 * @see CounterComparator#on(ICoverageNode.CounterEntity)
28 */
29public class NodeComparator implements Comparator<ICoverageNode>, Serializable {
30
31	private static final long serialVersionUID = 8550521643608826519L;
32
33	private final Comparator<ICounter> counterComparator;
34
35	private final CounterEntity entity;
36
37	NodeComparator(final Comparator<ICounter> counterComparator,
38			final CounterEntity entity) {
39		this.counterComparator = counterComparator;
40		this.entity = entity;
41	}
42
43	/**
44	 * Creates a new composite comparator with a second search criterion.
45	 *
46	 * @param second
47	 *            second criterion comparator
48	 *
49	 * @return composite comparator
50	 */
51	public NodeComparator second(final Comparator<ICoverageNode> second) {
52		final Comparator<ICoverageNode> first = this;
53		return new NodeComparator(null, null) {
54
55			private static final long serialVersionUID = -5515272752138802838L;
56
57			@Override
58			public int compare(final ICoverageNode o1, final ICoverageNode o2) {
59				final int result = first.compare(o1, o2);
60				return result == 0 ? second.compare(o1, o2) : result;
61			}
62		};
63	}
64
65	/**
66	 * Returns a sorted copy of the given collection of {@link ICoverageNode}
67	 * elements.
68	 *
69	 * @param <T>
70	 *            actual type of the elements
71	 * @param summaries
72	 *            collection to create a copy of
73	 * @return sorted copy
74	 */
75	public <T extends ICoverageNode> List<T> sort(final Collection<T> summaries) {
76		final List<T> result = new ArrayList<T>(summaries);
77		Collections.sort(result, this);
78		return result;
79	}
80
81	public int compare(final ICoverageNode n1, final ICoverageNode n2) {
82		final ICounter c1 = n1.getCounter(entity);
83		final ICounter c2 = n2.getCounter(entity);
84		return counterComparator.compare(c1, c2);
85	}
86
87}
88