package hudson.plugins.testabilityexplorer.report.costs; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; /** * Encapsulates the overall cost for a single testability run. * * @author reik.schatz */ public class CostSummary implements Serializable, TestabilityCost { public static final double WEIGHT_TO_EMPHASIZE_EXPENSIVE_METHODS = 1.5; private int m_excellent; private int m_good; private int m_needsWork; private int m_total; private List<ClassCost> m_costStack; public CostSummary(int excellent, int good, int needsWork, int total) { m_excellent = excellent; m_good = good; m_needsWork = needsWork; m_total = total; } public int getExcellent() { return m_excellent; } public int getGood() { return m_good; } public int getNeedsWork() { return m_needsWork; } public int getTotal() { return m_total; } public void addToCostStack(ClassCost classTestability) { if (m_costStack == null) { m_costStack = new ArrayList<ClassCost>(); } m_costStack.add(classTestability); } public Collection<ClassCost> getCostStack() { return m_costStack == null ? new ArrayList<ClassCost>() : Collections .unmodifiableCollection(m_costStack); } public int getNumberOfClasses() { return getExcellent() + getGood() + getNeedsWork(); } public CostSummary merge(CostSummary costs, double weight) { if (null != costs) { m_excellent += costs.getExcellent(); m_good += costs.getGood(); m_needsWork += costs.getNeedsWork(); if (m_costStack == null) { m_costStack = new ArrayList<ClassCost>(); } m_costStack.addAll(costs.getCostStack()); calculateTotal(weight); } return this; } protected void calculateTotal(double weight) { WeightedAverage total = weight < 0 ? new WeightedAverage( WEIGHT_TO_EMPHASIZE_EXPENSIVE_METHODS) : new WeightedAverage(weight); for (Iterator<ClassCost> iterator = m_costStack.iterator(); iterator.hasNext();) { ClassCost cost = iterator.next(); total.addValue(cost.getCost()); } m_total = Double.valueOf(total.getAverage()).intValue(); } /** * Sorts the all costs contained in this summary highest first. */ public void sort() { if (m_costStack != null) { Collections.sort(m_costStack, ClassCostComparator.getInstance()); for (ClassCost classCost : m_costStack) { classCost.sort(); } } } private class WeightedAverage { public static final double WEIGHT = 0.3; private final double weight; private double overallSum = 0; private double overallSqr = 0; public WeightedAverage() { this(WEIGHT); } public WeightedAverage(double weight) { this.weight = weight; } public void addValue(long value) { overallSqr += Math.pow(value, weight + 1); overallSum += Math.pow(value, weight); } public double getAverage() { return overallSqr / overallSum; } } }