From 48835a873353be8fdd48ca57313f6a74ddaf15f7 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Thu, 27 Aug 2015 16:05:18 +0200 Subject: [PATCH] SONAR-6730 Move RangeDistrubtionBuilder to API and allow constructor to take bottom limits --- .../formula/DistributionFormula.java | 3 +- .../ce/measure}/RangeDistributionBuilder.java | 55 +++++++++--- .../measures/RangeDistributionBuilder.java | 14 ++-- .../RangeDistributionBuilderTest.java | 84 +++++++++++++++---- 4 files changed, 123 insertions(+), 33 deletions(-) rename {server/sonar-server/src/main/java/org/sonar/server/computation/formula => sonar-plugin-api/src/main/java/org/sonar/api/ce/measure}/RangeDistributionBuilder.java (79%) rename {server/sonar-server/src/test/java/org/sonar/server/computation/formula => sonar-plugin-api/src/test/java/org/sonar/api/ce/measure}/RangeDistributionBuilderTest.java (60%) diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/formula/DistributionFormula.java b/server/sonar-server/src/main/java/org/sonar/server/computation/formula/DistributionFormula.java index cdeca703326..a2b3b4745b0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/formula/DistributionFormula.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/formula/DistributionFormula.java @@ -21,6 +21,7 @@ package org.sonar.server.computation.formula; import com.google.common.base.Optional; +import org.sonar.api.ce.measure.RangeDistributionBuilder; import org.sonar.server.computation.component.Component; import org.sonar.server.computation.component.CrawlerDepthLimit; import org.sonar.server.computation.measure.Measure; @@ -81,7 +82,7 @@ public class DistributionFormula implements Formula getValue() { if (initialized) { - return distribution.build(); + return Optional.fromNullable(distribution.build()); } return Optional.absent(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/formula/RangeDistributionBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/RangeDistributionBuilder.java similarity index 79% rename from server/sonar-server/src/main/java/org/sonar/server/computation/formula/RangeDistributionBuilder.java rename to sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/RangeDistributionBuilder.java index a78418ace64..06408466db6 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/formula/RangeDistributionBuilder.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/RangeDistributionBuilder.java @@ -18,9 +18,8 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.server.computation.formula; +package org.sonar.api.ce.measure; -import com.google.common.base.Optional; import com.google.common.collect.Multiset; import com.google.common.collect.TreeMultiset; import java.util.Arrays; @@ -29,6 +28,7 @@ import java.util.Comparator; import java.util.Map; import java.util.Set; import java.util.TreeMap; +import javax.annotation.CheckForNull; import org.sonar.api.utils.KeyValueFormat; /** @@ -45,16 +45,51 @@ public class RangeDistributionBuilder { private Number[] bottomLimits; private boolean isValid = true; + public RangeDistributionBuilder() { + // Nothing to be done here, bottom limits will be automatically calculated when adding the first value + } + + /** + * RangeDistributionBuilder for a defined range + * Each entry is initialized at zero + * + * @param bottomLimits the bottom limits of ranges to be used + */ + public RangeDistributionBuilder(Number[] bottomLimits) { + init(bottomLimits); + } + + /** + * Increments an entry by 1 + * + * @param value the value to use to pick the entry to increment + */ + public RangeDistributionBuilder add(Number value) { + return add(value, 1); + } + + /** + * Increments an entry + * + * @param value the value to use to pick the entry to increment + * @param count the number by which to increment + */ + public RangeDistributionBuilder add(Number value, int count) { + if (greaterOrEqualsThan(value, bottomLimits[0])) { + addValue(value, count); + isEmpty = false; + } + return this; + } + /** * Adds an existing Distribution to the current one. * It will create the entries if they don't exist. * Can be used to add the values of children resources for example *

- * Since 2.2, the distribution returned will be invalidated in case the - * measure given does not use the same bottom limits + * The returned distribution will be invalidated in case the given value does not use the same bottom limits * * @param data the data to add to the current one - * @return the current object */ public RangeDistributionBuilder add(String data) { Map map = KeyValueFormat.parse(data, KeyValueFormat.newDoubleConverter(), KeyValueFormat.newDoubleConverter()); @@ -141,11 +176,12 @@ public class RangeDistributionBuilder { * * @return the built measure */ - public Optional build() { + @CheckForNull + public String build() { if (isValid) { - return Optional.of(KeyValueFormat.format(toMap())); + return KeyValueFormat.format(toMap()); } - return Optional.absent(); + return null; } private Map toMap() { @@ -153,8 +189,7 @@ public class RangeDistributionBuilder { return Collections.emptyMap(); } Map map = new TreeMap<>(); - for (int i = 0; i < bottomLimits.length; i++) { - Number value = bottomLimits[i]; + for (Number value : bottomLimits) { map.put(value, distributionSet.count(value)); } return map; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/RangeDistributionBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/RangeDistributionBuilder.java index 26d82c1fdcf..6e2fd0049b7 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/RangeDistributionBuilder.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/RangeDistributionBuilder.java @@ -19,6 +19,11 @@ */ package org.sonar.api.measures; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import javax.annotation.Nullable; import org.apache.commons.collections.SortedBag; import org.apache.commons.collections.Transformer; import org.apache.commons.collections.bag.TransformedSortedBag; @@ -27,13 +32,6 @@ import org.apache.commons.lang.NumberUtils; import org.sonar.api.utils.KeyValueFormat; import org.sonar.api.utils.SonarException; -import javax.annotation.Nullable; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Map; -import java.util.Set; - /** * Utility to build a distribution based on defined ranges *

@@ -41,7 +39,9 @@ import java.util.Set; * with pre-defined ranges of complexity.

* * @since 1.10 + * @deprecated since 5.2 use {@link org.sonar.api.ce.measure.RangeDistributionBuilder instead} */ +@Deprecated public class RangeDistributionBuilder implements MeasureBuilder { private Metric metric; diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/formula/RangeDistributionBuilderTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/RangeDistributionBuilderTest.java similarity index 60% rename from server/sonar-server/src/test/java/org/sonar/server/computation/formula/RangeDistributionBuilderTest.java rename to sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/RangeDistributionBuilderTest.java index ea8dfbc7900..f59ee7b963e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/formula/RangeDistributionBuilderTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/ce/measure/RangeDistributionBuilderTest.java @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.server.computation.formula; +package org.sonar.api.ce.measure; import org.junit.Test; @@ -26,57 +26,104 @@ import static org.assertj.core.api.Assertions.assertThat; public class RangeDistributionBuilderTest { + @Test + public void work_on_an_limits_array_copy() { + Integer[] limits = new Integer[] {4, 2, 0}; + RangeDistributionBuilder builder = new RangeDistributionBuilder(limits); + builder.add(3.2).add(2.0).add(6.2).build(); + + assertThat(limits[0]).isEqualTo(4); + assertThat(limits[1]).isEqualTo(2); + assertThat(limits[2]).isEqualTo(0); + } + @Test public void build_integer_distribution() { + RangeDistributionBuilder builder = new RangeDistributionBuilder(new Integer[] {0, 2, 4}); + String data = builder + .add(3.2) + .add(2.0) + .add(6.2) + .build(); + + assertThat(data).isEqualTo("0=0;2=2;4=1"); + } + + @Test + public void build_double_distribution() { + RangeDistributionBuilder builder = new RangeDistributionBuilder(new Double[] {0.0, 2.0, 4.0}); + String data = builder + .add(3.2) + .add(2.0) + .add(6.2) + .build(); + + assertThat(data).isEqualTo("0=0;2=2;4=1"); + } + + @Test + public void value_lesser_than_minimum_is_ignored() { + RangeDistributionBuilder builder = new RangeDistributionBuilder(new Integer[] {0, 2, 4}); + String data = builder + .add(3.2) + .add(2.0) + .add(-3.0) + .build(); + + assertThat(data).isEqualTo("0=0;2=2;4=0"); + } + + @Test + public void add_existing_integer_distribution() { RangeDistributionBuilder builder = new RangeDistributionBuilder(); String data = builder .add("0=0;2=2;4=1") .add("0=1;2=2;4=2") - .build().get(); + .build(); assertThat(data).isEqualTo("0=1;2=4;4=3"); } @Test - public void build_double_distribution() { + public void add_existing_double_distribution() { RangeDistributionBuilder builder = new RangeDistributionBuilder(); String data = builder .add("0.5=0;1.9=2;4.5=1") .add("0.5=1;1.9=3;4.5=1") - .build().get(); + .build(); assertThat(data).isEqualTo("0.5=1;1.9=5;4.5=2"); } @Test - public void add_distribution_measure_with_identical_limits() { + public void add_distribution_with_identical_limits() { RangeDistributionBuilder builder = new RangeDistributionBuilder(); String data = builder .add("0=1;2=0") .add("0=3;2=5") - .build().get(); + .build(); assertThat(data).isEqualTo("0=4;2=5"); } @Test - public void add_distribution_measure_with_different_int_limits() { + public void add_distribution_with_different_int_limits() { RangeDistributionBuilder builder = new RangeDistributionBuilder(); assertThat(builder .add("0=1") .add("0=3;2=5") - .build().isPresent()).isFalse(); + .build()).isNull(); } @Test - public void add_distribution_measure_with_different_double_limits() { + public void add_distribution_with_different_double_limits() { RangeDistributionBuilder builder = new RangeDistributionBuilder(); assertThat(builder .add("0.0=3;3.0=5") .add("0.0=3;3.0=5;6.0=9") - .build().isPresent()).isFalse(); + .build()).isNull(); } @Test @@ -85,7 +132,7 @@ public class RangeDistributionBuilderTest { String data = builder .add("0.5=3;3.5=5;6.5=9") .add("0.5=0;3.5=2;6.5=1") - .build().get(); + .build(); assertThat(data).isEqualTo("0.5=3;3.5=7;6.5=10"); } @@ -96,23 +143,30 @@ public class RangeDistributionBuilderTest { String data = builder .add("0=3;3=5;6=9") .add("0=0;3=2;6=1") - .build().get(); + .build(); assertThat(data).isEqualTo("0=3;3=7;6=10"); } + @Test - public void return_empty_string_when_empty_data() { + public void is_empty_is_true_when_no_data() { RangeDistributionBuilder builder = new RangeDistributionBuilder(); assertThat(builder.isEmpty()).isTrue(); - assertThat(builder.build().get()).isEmpty(); + } + + @Test + public void is_empty_is_true_when_no_data_on_distribution_with_limits() { + RangeDistributionBuilder builder = new RangeDistributionBuilder(new Integer[] {4, 2, 0}); + + assertThat(builder.isEmpty()).isTrue(); } @Test public void aggregate_empty_distribution() { RangeDistributionBuilder builder = new RangeDistributionBuilder(); - String distribution = builder.build().get(); + String distribution = builder.build(); assertThat(distribution).isEmpty(); } -- 2.39.5