2 * SonarQube, open source software quality management tool.
3 * Copyright (C) 2008-2014 SonarSource
4 * mailto:contact AT sonarsource DOT com
6 * SonarQube is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * SonarQube is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 package org.sonar.server.computation.measure.api;
23 import com.google.common.base.Function;
24 import com.google.common.base.Optional;
25 import com.google.common.base.Predicates;
26 import com.google.common.collect.FluentIterable;
27 import java.util.HashSet;
28 import java.util.List;
30 import javax.annotation.CheckForNull;
31 import javax.annotation.Nonnull;
32 import javax.annotation.Nullable;
33 import org.sonar.api.ce.measure.Component;
34 import org.sonar.api.ce.measure.Issue;
35 import org.sonar.api.ce.measure.Measure;
36 import org.sonar.api.ce.measure.MeasureComputer;
37 import org.sonar.api.ce.measure.Settings;
38 import org.sonar.core.issue.DefaultIssue;
39 import org.sonar.server.computation.component.SettingsRepository;
40 import org.sonar.server.computation.issue.ComponentIssuesRepository;
41 import org.sonar.server.computation.measure.MeasureRepository;
42 import org.sonar.server.computation.metric.Metric;
43 import org.sonar.server.computation.metric.MetricRepository;
45 import static com.google.common.base.Preconditions.checkArgument;
46 import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
48 public class MeasureComputerImplementationContext implements MeasureComputer.Implementation.Context {
50 private final MeasureComputer measureComputer;
51 private final SettingsRepository settings;
52 private final MeasureRepository measureRepository;
53 private final MetricRepository metricRepository;
55 private final org.sonar.server.computation.component.Component internalComponent;
56 private final Component component;
57 private final List<DefaultIssue> componentIssues;
59 private final Set<String> allowedMetrics;
61 public MeasureComputerImplementationContext(org.sonar.server.computation.component.Component component, MeasureComputer measureComputer,
62 SettingsRepository settings, MeasureRepository measureRepository, MetricRepository metricRepository, ComponentIssuesRepository componentIssuesRepository) {
63 this.measureComputer = measureComputer;
64 this.settings = settings;
65 this.internalComponent = component;
66 this.measureRepository = measureRepository;
67 this.metricRepository = metricRepository;
68 this.component = newComponent(component);
69 this.componentIssues = componentIssuesRepository.getIssues(component);
70 this.allowedMetrics = allowedMetric(measureComputer);
73 private Component newComponent(org.sonar.server.computation.component.Component component) {
74 return new ComponentImpl(
76 Component.Type.valueOf(component.getType().name()),
77 component.getType() == org.sonar.server.computation.component.Component.Type.FILE ?
78 new ComponentImpl.FileAttributesImpl(component.getFileAttributes().getLanguageKey(), component.getFileAttributes().isUnitTest()) :
82 private static Set<String> allowedMetric(MeasureComputer measureComputer) {
83 Set<String> allowedMetrics = new HashSet<>();
84 allowedMetrics.addAll(measureComputer.getInputMetrics());
85 allowedMetrics.addAll(measureComputer.getOutputMetrics());
86 return allowedMetrics;
90 public Component getComponent() {
95 public Settings getSettings() {
96 return new Settings() {
99 public String getString(String key) {
100 return getComponentSettings().getString(key);
104 public String[] getStringArray(String key) {
105 return getComponentSettings().getStringArray(key);
110 private org.sonar.api.config.Settings getComponentSettings() {
111 return settings.getSettings(internalComponent);
116 public Measure getMeasure(String metric) {
117 validateInputMetric(metric);
118 Optional<org.sonar.server.computation.measure.Measure> measure = measureRepository.getRawMeasure(internalComponent, metricRepository.getByKey(metric));
119 if (measure.isPresent()) {
120 return new MeasureImpl(measure.get());
126 public Iterable<Measure> getChildrenMeasures(String metric) {
127 validateInputMetric(metric);
128 return FluentIterable.from(internalComponent.getChildren())
129 .transform(new ComponentToMeasure(metricRepository.getByKey(metric)))
130 .transform(ToMeasureAPI.INSTANCE)
131 .filter(Predicates.notNull());
135 public void addMeasure(String metricKey, int value) {
136 Metric metric = metricRepository.getByKey(metricKey);
137 validateAddMeasure(metric);
138 measureRepository.add(internalComponent, metric, newMeasureBuilder().create(value));
142 public void addMeasure(String metricKey, double value) {
143 Metric metric = metricRepository.getByKey(metricKey);
144 validateAddMeasure(metric);
145 measureRepository.add(internalComponent, metric, newMeasureBuilder().create(value));
149 public void addMeasure(String metricKey, long value) {
150 Metric metric = metricRepository.getByKey(metricKey);
151 validateAddMeasure(metric);
152 measureRepository.add(internalComponent, metric, newMeasureBuilder().create(value));
156 public void addMeasure(String metricKey, String value) {
157 Metric metric = metricRepository.getByKey(metricKey);
158 validateAddMeasure(metric);
159 measureRepository.add(internalComponent, metric, newMeasureBuilder().create(value));
162 private void validateInputMetric(String metric) {
163 checkArgument(allowedMetrics.contains(metric), "Only metrics in %s can be used to load measures", measureComputer.getInputMetrics());
166 private void validateAddMeasure(Metric metric) {
167 checkArgument(measureComputer.getOutputMetrics().contains(metric.getKey()), "Only metrics in %s can be used to add measures", measureComputer.getOutputMetrics());
168 if (measureRepository.getRawMeasure(internalComponent, metric).isPresent()) {
169 throw new UnsupportedOperationException(String.format("A measure on metric '%s' already exists on component '%s'", metric.getKey(), internalComponent.getKey()));
174 public List<? extends Issue> getIssues() {
175 return componentIssues;
178 private class ComponentToMeasure implements Function<org.sonar.server.computation.component.Component, Optional<org.sonar.server.computation.measure.Measure>> {
180 private final Metric metric;
182 public ComponentToMeasure(Metric metric) {
183 this.metric = metric;
187 public Optional<org.sonar.server.computation.measure.Measure> apply(@Nonnull org.sonar.server.computation.component.Component input) {
188 return measureRepository.getRawMeasure(input, metric);
192 private enum ToMeasureAPI implements Function<Optional<org.sonar.server.computation.measure.Measure>, Measure> {
197 public Measure apply(@Nonnull Optional<org.sonar.server.computation.measure.Measure> input) {
198 return input.isPresent() ? new MeasureImpl(input.get()) : null;