001/* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2012 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * Sonar is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020package org.sonar.plugins.core.timemachine; 021 022import org.apache.commons.lang.ArrayUtils; 023import org.sonar.api.batch.Decorator; 024import org.sonar.api.batch.DecoratorBarriers; 025import org.sonar.api.batch.DecoratorContext; 026import org.sonar.api.batch.DependedUpon; 027import org.sonar.api.measures.CoreMetrics; 028import org.sonar.api.measures.Measure; 029import org.sonar.api.measures.Metric; 030import org.sonar.api.resources.Project; 031import org.sonar.api.resources.Qualifiers; 032import org.sonar.api.resources.Resource; 033import org.sonar.api.resources.Scopes; 034 035import java.util.Arrays; 036import java.util.List; 037 038@DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE) 039public final class NewCoverageAggregator implements Decorator { 040 041 public boolean shouldExecuteOnProject(Project project) { 042 return true; 043 } 044 045 @DependedUpon 046 public List<Metric> generatesNewCoverageMetrics() { 047 return Arrays.asList( 048 CoreMetrics.NEW_LINES_TO_COVER, CoreMetrics.NEW_UNCOVERED_LINES, CoreMetrics.NEW_CONDITIONS_TO_COVER, CoreMetrics.NEW_UNCOVERED_CONDITIONS, 049 CoreMetrics.NEW_IT_LINES_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_LINES, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS); 050 } 051 052 public void decorate(Resource resource, DecoratorContext context) { 053 if (shouldDecorate(resource)) { 054 int maxPeriods = (Qualifiers.isView(resource, true) ? 3 : 5); 055 aggregate(context, CoreMetrics.NEW_LINES_TO_COVER, maxPeriods); 056 aggregate(context, CoreMetrics.NEW_UNCOVERED_LINES, maxPeriods); 057 aggregate(context, CoreMetrics.NEW_CONDITIONS_TO_COVER, maxPeriods); 058 aggregate(context, CoreMetrics.NEW_UNCOVERED_CONDITIONS, maxPeriods); 059 aggregate(context, CoreMetrics.NEW_IT_LINES_TO_COVER, maxPeriods); 060 aggregate(context, CoreMetrics.NEW_IT_UNCOVERED_LINES, maxPeriods); 061 aggregate(context, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER, maxPeriods); 062 aggregate(context, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS, maxPeriods); 063 } 064 } 065 066 void aggregate(DecoratorContext context, Metric metric, int maxPeriods) { 067 int[] variations = {0,0,0,0,0}; 068 boolean[] hasValues = {false,false,false,false,false}; 069 for (Measure child : context.getChildrenMeasures(metric)) { 070 for (int indexPeriod=1 ; indexPeriod<=maxPeriods ; indexPeriod++) { 071 Double variation = child.getVariation(indexPeriod); 072 if (variation!=null) { 073 variations[indexPeriod-1]=variations[indexPeriod-1] + variation.intValue(); 074 hasValues[indexPeriod-1]=true; 075 } 076 } 077 } 078 079 if (ArrayUtils.contains(hasValues, true)) { 080 Measure measure = new Measure(metric); 081 for (int index=0 ; index<5 ; index++) { 082 if (hasValues[index]) { 083 measure.setVariation(index+1, (double)variations[index]); 084 } 085 } 086 context.saveMeasure(measure); 087 } 088 } 089 090 boolean shouldDecorate(Resource resource) { 091 return Scopes.isHigherThan(resource, Scopes.FILE); 092 } 093}