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     */
020    package org.sonar.api.measures;
021    
022    import org.apache.commons.lang.StringUtils;
023    
024    import javax.annotation.Nullable;
025    
026    import java.util.Collection;
027    
028    /**
029     * An utility class to manipulate measures
030     *
031     * @since 1.10
032     */
033    public 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    }