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