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
021package org.sonar.api.ce.measure.test;
022
023import com.google.common.base.Function;
024import com.google.common.base.Predicate;
025import com.google.common.collect.FluentIterable;
026import com.google.common.collect.ImmutableSet;
027import java.util.Arrays;
028import java.util.List;
029import java.util.Set;
030import javax.annotation.Nonnull;
031import javax.annotation.Nullable;
032import org.sonar.api.ce.measure.MeasureComputer;
033import org.sonar.api.measures.CoreMetrics;
034import org.sonar.api.measures.Metric;
035
036import static com.google.common.base.Preconditions.checkArgument;
037import static java.util.Objects.requireNonNull;
038
039public class TestMeasureComputerDefinition implements MeasureComputer.MeasureComputerDefinition {
040
041  private final Set<String> inputMetricKeys;
042  private final Set<String> outputMetrics;
043
044  private TestMeasureComputerDefinition(MeasureComputerDefinitionBuilderImpl builder) {
045    this.inputMetricKeys = ImmutableSet.copyOf(builder.inputMetricKeys);
046    this.outputMetrics = ImmutableSet.copyOf(builder.outputMetrics);
047  }
048
049  @Override
050  public Set<String> getInputMetrics() {
051    return inputMetricKeys;
052  }
053
054  @Override
055  public Set<String> getOutputMetrics() {
056    return outputMetrics;
057  }
058
059  public static class MeasureComputerDefinitionBuilderImpl implements Builder {
060
061    private String[] inputMetricKeys = new String[] {};
062    private String[] outputMetrics;
063
064    @Override
065    public Builder setInputMetrics(String... inputMetrics) {
066      this.inputMetricKeys = validateInputMetricKeys(inputMetrics);
067      return this;
068    }
069
070    @Override
071    public Builder setOutputMetrics(String... outputMetrics) {
072      this.outputMetrics = validateOutputMetricKeys(outputMetrics);
073      return this;
074    }
075
076    @Override
077    public MeasureComputer.MeasureComputerDefinition build() {
078      validateInputMetricKeys(this.inputMetricKeys);
079      validateOutputMetricKeys(this.outputMetrics);
080      return new TestMeasureComputerDefinition(this);
081    }
082
083    private static String[] validateInputMetricKeys(@Nullable String[] inputMetrics) {
084      requireNonNull(inputMetrics, "Input metrics cannot be null");
085      checkNotNull(inputMetrics);
086      return inputMetrics;
087    }
088
089    private static String[] validateOutputMetricKeys(@Nullable String[] outputMetrics) {
090      requireNonNull(outputMetrics, "Output metrics cannot be null");
091      checkArgument(outputMetrics.length > 0, "At least one output metric must be defined");
092      FluentIterable.from(CoreMetrics.getMetrics()).transform(MetricToKey.INSTANCE).filter(new MatchMetricKey(outputMetrics)).size();
093      checkNotNull(outputMetrics);
094      return outputMetrics;
095    }
096  }
097
098  private static void checkNotNull(String[] metrics) {
099    for (String metric : metrics) {
100      requireNonNull(metric, "Null metric is not allowed");
101    }
102  }
103
104  private enum MetricToKey implements Function<Metric, String> {
105    INSTANCE;
106
107    @Override
108    public String apply(@Nonnull Metric input) {
109      return input.getKey();
110    }
111  }
112
113  private static class MatchMetricKey implements Predicate<String> {
114
115    private final List<String> metrics;
116
117    public MatchMetricKey(String[] metrics) {
118      this.metrics = Arrays.asList(metrics);
119    }
120
121    @Override
122    public boolean apply(@Nonnull String metric) {
123      checkArgument(!metrics.contains(metric), "Core metrics are not allowed");
124      return true;
125    }
126  }
127}