diff options
4 files changed, 101 insertions, 48 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/api/MeasureComputerImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/api/MeasureComputerImpl.java index 02ac2759a52..1712950e7a0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/api/MeasureComputerImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/api/MeasureComputerImpl.java @@ -22,9 +22,11 @@ package org.sonar.server.computation.measure.api; import com.google.common.collect.ImmutableSet; import java.util.Set; +import javax.annotation.Nullable; import org.sonar.api.ce.measure.MeasureComputer; import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; public class MeasureComputerImpl implements MeasureComputer { @@ -88,41 +90,57 @@ public class MeasureComputerImpl implements MeasureComputer { public static class MeasureComputerBuilderImpl implements MeasureComputerBuilder { - private String[] inputMetricKeys; + private String[] inputMetricKeys = new String[] {}; private String[] outputMetrics; private Implementation measureComputerImplementation; @Override public MeasureComputerBuilder setInputMetrics(String... inputMetrics) { - checkArgument(inputMetrics != null && inputMetrics.length > 0, "At least one input metric must be defined"); - this.inputMetricKeys = inputMetrics; + this.inputMetricKeys = validateInputMetricKeys(inputMetrics); return this; } @Override public MeasureComputerBuilder setOutputMetrics(String... outputMetrics) { - checkArgument(outputMetrics != null && outputMetrics.length > 0, "At least one output metric must be defined"); - this.outputMetrics = outputMetrics; + this.outputMetrics = validateOutputMetricKeys(outputMetrics); return this; } @Override public MeasureComputerBuilder setImplementation(Implementation impl) { - checkImplementation(impl); - this.measureComputerImplementation = impl; + this.measureComputerImplementation = validateImplementation(impl); return this; } @Override public MeasureComputer build() { - checkArgument(this.inputMetricKeys != null, "At least one input metric must be defined"); - checkArgument(this.outputMetrics != null, "At least one output metric must be defined"); - checkImplementation(this.measureComputerImplementation); + validateInputMetricKeys(this.inputMetricKeys); + validateOutputMetricKeys(this.outputMetrics); + validateImplementation(this.measureComputerImplementation); return new MeasureComputerImpl(this); } - private static void checkImplementation(Implementation impl) { - checkArgument(impl != null, "The implementation is missing"); + private static String[] validateInputMetricKeys(@Nullable String[] inputMetrics) { + requireNonNull(inputMetrics, "Input metrics cannot be null"); + checkNotNull(inputMetrics); + return inputMetrics; + } + + private static String[] validateOutputMetricKeys(@Nullable String[] outputMetrics) { + checkArgument(outputMetrics != null && outputMetrics.length > 0, "At least one output metric must be defined"); + checkNotNull(outputMetrics); + return outputMetrics; + } + + private static Implementation validateImplementation(Implementation impl) { + return requireNonNull(impl, "The implementation is missing"); } } + + private static void checkNotNull(String[] metrics){ + for (String metric : metrics) { + requireNonNull(metric, "Null metric is not allowed"); + } + } + } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/api/MeasureComputerImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/api/MeasureComputerImplTest.java index a813d8efd65..98eb6b04987 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/api/MeasureComputerImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/api/MeasureComputerImplTest.java @@ -75,20 +75,30 @@ public class MeasureComputerImplTest { } @Test - public void fail_with_IAE_when_no_input_metrics() throws Exception { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("At least one input metric must be defined"); + public void input_metrics_can_be_empty() throws Exception { + MeasureComputer measureComputer = new MeasureComputerImpl.MeasureComputerBuilderImpl() + .setInputMetrics() + .setOutputMetrics("comment_density_1", "comment_density_2") + .setImplementation(DEFAULT_MEASURE_COMPUTER_IMPLEMENTATION) + .build(); - new MeasureComputerImpl.MeasureComputerBuilderImpl() + assertThat(measureComputer.getInputMetrics()).isEmpty(); + } + + @Test + public void input_metrics_is_empty_when_not_set() throws Exception { + MeasureComputer measureComputer = new MeasureComputerImpl.MeasureComputerBuilderImpl() .setOutputMetrics("comment_density_1", "comment_density_2") .setImplementation(DEFAULT_MEASURE_COMPUTER_IMPLEMENTATION) .build(); + + assertThat(measureComputer.getInputMetrics()).isEmpty(); } @Test - public void fail_with_IAE_when_null_input_metrics() throws Exception { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("At least one input metric must be defined"); + public void fail_with_NPE_when_null_input_metrics() throws Exception { + thrown.expect(NullPointerException.class); + thrown.expectMessage("Input metrics cannot be null"); new MeasureComputerImpl.MeasureComputerBuilderImpl() .setInputMetrics(null) @@ -97,12 +107,12 @@ public class MeasureComputerImplTest { } @Test - public void fail_with_IAE_with_empty_input_metrics() throws Exception { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("At least one input metric must be defined"); + public void fail_with_NPE_when_one_input_metric_is_null() throws Exception { + thrown.expect(NullPointerException.class); + thrown.expectMessage("Null metric is not allowed"); new MeasureComputerImpl.MeasureComputerBuilderImpl() - .setInputMetrics() + .setInputMetrics("ncloc", null) .setOutputMetrics("comment_density_1", "comment_density_2") .setImplementation(DEFAULT_MEASURE_COMPUTER_IMPLEMENTATION); } @@ -130,6 +140,17 @@ public class MeasureComputerImplTest { } @Test + public void fail_with_NPE_when_one_output_metric_is_null() throws Exception { + thrown.expect(NullPointerException.class); + thrown.expectMessage("Null metric is not allowed"); + + new MeasureComputerImpl.MeasureComputerBuilderImpl() + .setInputMetrics("ncloc", "comment") + .setOutputMetrics("comment_density_1", null) + .setImplementation(DEFAULT_MEASURE_COMPUTER_IMPLEMENTATION); + } + + @Test public void fail_with_IAE_with_empty_output_metrics() throws Exception { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("At least one output metric must be defined"); @@ -142,7 +163,7 @@ public class MeasureComputerImplTest { @Test public void fail_with_IAE_when_no_implementation() throws Exception { - thrown.expect(IllegalArgumentException.class); + thrown.expect(NullPointerException.class); thrown.expectMessage("The implementation is missing"); new MeasureComputerImpl.MeasureComputerBuilderImpl() @@ -153,7 +174,7 @@ public class MeasureComputerImplTest { @Test public void fail_with_IAE_when_null_implementation() throws Exception { - thrown.expect(IllegalArgumentException.class); + thrown.expect(NullPointerException.class); thrown.expectMessage("The implementation is missing"); new MeasureComputerImpl.MeasureComputerBuilderImpl() diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/MeasureComputer.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/MeasureComputer.java index 32d5d90e469..d62851006a6 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/MeasureComputer.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/MeasureComputer.java @@ -48,24 +48,29 @@ public interface MeasureComputer { interface MeasureComputerBuilder { /** - * @throws IllegalStateException if there's not at least one input metrics - */ + * Input metrics can be empty (for instance when only issues are needed) + * @throws NullPointerException if inputMetrics is null + * @throws NullPointerException if the metrics contains a {@code null} + * */ MeasureComputerBuilder setInputMetrics(String... inputMetrics); /** - * @throws IllegalStateException if there's not at least one output metrics + * @throws IllegalArgumentException if there's not at least one output metrics + * @throws NullPointerException if the metrics contains a {@code null} */ MeasureComputerBuilder setOutputMetrics(String... outMetrics); /** - * @throws IllegalStateException if there's no implementation + * @throws NullPointerException if there's no implementation */ MeasureComputerBuilder setImplementation(Implementation impl); /** - * @throws IllegalStateException if there's not at least one input metrics - * @throws IllegalStateException if there's not at least one output metrics - * @throws IllegalStateException if there's no implementation + * @throws NullPointerException if inputMetrics is null + * @throws NullPointerException if inputs metrics contains a {@code null} + * @throws IllegalArgumentException if there's not at least one output metrics + * @throws NullPointerException if outputs metrics contains a {@code null} + * @throws NullPointerException if there's no implementation */ MeasureComputer build(); } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/MeasureComputerImpl.java b/sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/MeasureComputerImpl.java index 653499c6efe..b661247a517 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/MeasureComputerImpl.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/MeasureComputerImpl.java @@ -22,9 +22,11 @@ package org.sonar.api.test.ce.measure; import com.google.common.collect.ImmutableSet; import java.util.Set; +import javax.annotation.Nullable; import org.sonar.api.ce.measure.MeasureComputer; import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; public class MeasureComputerImpl implements MeasureComputer { @@ -64,49 +66,56 @@ public class MeasureComputerImpl implements MeasureComputer { public static class MeasureComputerBuilderImpl implements MeasureComputerBuilder { - private String[] inputMetricKeys; + private String[] inputMetricKeys = new String[] {}; private String[] outputMetrics; private Implementation measureComputerImplementation; @Override public MeasureComputerBuilder setInputMetrics(String... inputMetrics) { - this.inputMetricKeys = inputMetrics; - checkInputMetricKeys(); + this.inputMetricKeys = validateInputMetricKeys(inputMetrics); return this; } @Override public MeasureComputerBuilder setOutputMetrics(String... outputMetrics) { - this.outputMetrics = outputMetrics; - checkOutputMetricKeys(); + this.outputMetrics = validateOutputMetricKeys(outputMetrics); return this; } @Override public MeasureComputerBuilder setImplementation(Implementation impl) { - this.measureComputerImplementation = impl; - checkImplementation(); + this.measureComputerImplementation = validateImplementation(impl); return this; } @Override public MeasureComputer build() { - checkInputMetricKeys(); - checkOutputMetricKeys(); - checkImplementation(); + validateInputMetricKeys(this.inputMetricKeys); + validateOutputMetricKeys(this.outputMetrics); + validateImplementation(this.measureComputerImplementation); return new MeasureComputerImpl(this); } - private void checkInputMetricKeys(){ - checkArgument(this.inputMetricKeys != null && inputMetricKeys.length > 0, "At least one input metrics must be defined"); + private static String[] validateInputMetricKeys(@Nullable String[] inputMetrics) { + requireNonNull(inputMetrics, "Input metrics cannot be null"); + checkNotNull(inputMetrics); + return inputMetrics; } - private void checkOutputMetricKeys(){ - checkArgument(this.outputMetrics != null && outputMetrics.length > 0, "At least one output metrics must be defined"); + private static String[] validateOutputMetricKeys(@Nullable String[] outputMetrics) { + checkArgument(outputMetrics != null && outputMetrics.length > 0, "At least one output metric must be defined"); + checkNotNull(outputMetrics); + return outputMetrics; } - private void checkImplementation(){ - checkArgument(this.measureComputerImplementation != null, "The implementation is missing"); + private static Implementation validateImplementation(Implementation impl) { + return requireNonNull(impl, "The implementation is missing"); + } + } + + private static void checkNotNull(String[] metrics){ + for (String metric : metrics) { + requireNonNull(metric, "Null metric is not allowed"); } } } |