001/*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube 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 * SonarQube 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 License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019 */
020package org.sonar.api.measures;
021
022import org.apache.commons.lang.StringUtils;
023
024import javax.annotation.Nullable;
025
026import java.util.Collection;
027
028/**
029 * An utility class to manipulate measures
030 *
031 * @since 1.10
032 */
033public final class MeasureUtils {
034
035  /**
036   * Class cannot be instantiated, it should only be access through static methods
037   */
038  private MeasureUtils() {
039  }
040
041  /**
042   * Return true if all measures have numeric value
043   *
044   * @param measures the measures
045   * @return true if all measures numeric values
046   */
047  public static boolean haveValues(Measure... measures) {
048    if (measures == null || measures.length == 0) {
049      return false;
050    }
051    for (Measure measure : measures) {
052      if (!hasValue(measure)) {
053        return false;
054      }
055    }
056    return true;
057  }
058
059  /**
060   * Get the value of a measure, or alternatively a default value
061   *
062   * @param measure      the measure
063   * @param defaultValue the default value
064   * @return <code>defaultValue</code> if measure is null or has no values.
065   */
066
067  public static Double getValue(Measure measure, @Nullable Double defaultValue) {
068    if (MeasureUtils.hasValue(measure)) {
069      return measure.getValue();
070    }
071    return defaultValue;
072  }
073
074  public static Long getValueAsLong(Measure measure, Long defaultValue) {
075    if (MeasureUtils.hasValue(measure)) {
076      return measure.getValue().longValue();
077    }
078    return defaultValue;
079  }
080
081  public static Double getVariation(Measure measure, int periodIndex) {
082    return getVariation(measure, periodIndex, null);
083  }
084
085  public static Double getVariation(Measure measure, int periodIndex, @Nullable Double defaultValue) {
086    Double result = null;
087    if (measure != null) {
088      result = measure.getVariation(periodIndex);
089    }
090    return result != null ? result : defaultValue;
091  }
092
093  public static Long getVariationAsLong(Measure measure, int periodIndex) {
094    return getVariationAsLong(measure, periodIndex, null);
095  }
096
097  public static Long getVariationAsLong(Measure measure, int periodIndex, @Nullable Long defaultValue) {
098    Double result = null;
099    if (measure != null) {
100      result = measure.getVariation(periodIndex);
101    }
102    return result == null ? defaultValue : Long.valueOf(result.longValue());
103  }
104
105  /**
106   * Tests if a measure has a value
107   *
108   * @param measure the measure
109   * @return whether the measure has a value
110   */
111  public static boolean hasValue(Measure measure) {
112    return measure != null && measure.getValue() != null;
113  }
114
115  /**
116   * Tests if a measure has a data field
117   *
118   * @param measure the measure
119   * @return whether the measure has a data field
120   */
121  public static boolean hasData(Measure measure) {
122    return measure != null && StringUtils.isNotBlank(measure.getData());
123  }
124
125  /**
126   * Sums a series of measures
127   *
128   * @param zeroIfNone whether to return 0 or null in case measures is null
129   * @param measures   the series of measures
130   * @return the sum of the measure series
131   */
132  public static Double sum(boolean zeroIfNone, Collection<Measure> measures) {
133    if (measures != null) {
134      return sum(zeroIfNone, measures.toArray(new Measure[measures.size()]));
135    }
136    return zeroIfNone(zeroIfNone);
137  }
138
139  /**
140   * Sums a series of measures
141   *
142   * @param zeroIfNone whether to return 0 or null in case measures is null
143   * @param measures   the series of measures
144   * @return the sum of the measure series
145   */
146  public static Double sum(boolean zeroIfNone, Measure... measures) {
147    if (measures == null) {
148      return zeroIfNone(zeroIfNone);
149    }
150    Double sum = 0d;
151    boolean hasValue = false;
152    for (Measure measure : measures) {
153      if (measure != null && measure.getValue() != null) {
154        hasValue = true;
155        sum += measure.getValue();
156      }
157    }
158
159    if (hasValue) {
160      return sum;
161    }
162    return zeroIfNone(zeroIfNone);
163  }
164
165  /**
166   * Sums a series of measures for the given variation index
167   *
168   * @param zeroIfNone whether to return 0 or null in case measures is null
169   * @param variationIndex the index of the variation to use
170   * @param measures   the series of measures
171   * @return the sum of the variations for the measure series
172   */
173  public static Double sumOnVariation(boolean zeroIfNone, int variationIndex, Collection<Measure> measures) {
174    if (measures == null) {
175      return zeroIfNone(zeroIfNone);
176    }
177    Double sum = 0d;
178    for (Measure measure : measures) {
179      Double var = measure.getVariation(variationIndex);
180      if (var != null) {
181        sum += var;
182      }
183    }
184    return sum;
185  }
186
187  private static Double zeroIfNone(boolean zeroIfNone) {
188    return zeroIfNone ? 0d : null;
189  }
190}