]> source.dussan.org Git - sonarqube.git/blob
44516db373a0a62a602debace43de539ca9ae2ec
[sonarqube.git] /
1 /*
2  * SonarQube, open source software quality management tool.
3  * Copyright (C) 2008-2014 SonarSource
4  * mailto:contact AT sonarsource DOT com
5  *
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.
10  *
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.
15  *
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.
19  */
20
21 package org.sonar.server.computation.measure.api;
22
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;
29 import java.util.Set;
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;
44
45 import static com.google.common.base.Preconditions.checkArgument;
46 import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
47
48 public class MeasureComputerImplementationContext implements MeasureComputer.Implementation.Context {
49
50   private final MeasureComputer measureComputer;
51   private final SettingsRepository settings;
52   private final MeasureRepository measureRepository;
53   private final MetricRepository metricRepository;
54
55   private final org.sonar.server.computation.component.Component internalComponent;
56   private final Component component;
57   private final List<DefaultIssue> componentIssues;
58
59   private final Set<String> allowedMetrics;
60
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);
71   }
72
73   private Component newComponent(org.sonar.server.computation.component.Component component) {
74     return new ComponentImpl(
75       component.getKey(),
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()) :
79         null);
80   }
81
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;
87   }
88
89   @Override
90   public Component getComponent() {
91     return component;
92   }
93
94   @Override
95   public Settings getSettings() {
96     return new Settings() {
97       @Override
98       @CheckForNull
99       public String getString(String key) {
100         return getComponentSettings().getString(key);
101       }
102
103       @Override
104       public String[] getStringArray(String key) {
105         return getComponentSettings().getStringArray(key);
106       }
107     };
108   }
109
110   private org.sonar.api.config.Settings getComponentSettings() {
111     return settings.getSettings(internalComponent);
112   }
113
114   @Override
115   @CheckForNull
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());
121     }
122     return null;
123   }
124
125   @Override
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());
132   }
133
134   @Override
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));
139   }
140
141   @Override
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));
146   }
147
148   @Override
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));
153   }
154
155   @Override
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));
160   }
161
162   private void validateInputMetric(String metric) {
163     checkArgument(allowedMetrics.contains(metric), "Only metrics in %s can be used to load measures", measureComputer.getInputMetrics());
164   }
165
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()));
170     }
171   }
172
173   @Override
174   public List<? extends Issue> getIssues() {
175     return componentIssues;
176   }
177
178   private class ComponentToMeasure implements Function<org.sonar.server.computation.component.Component, Optional<org.sonar.server.computation.measure.Measure>> {
179
180     private final Metric metric;
181
182     public ComponentToMeasure(Metric metric) {
183       this.metric = metric;
184     }
185
186     @Override
187     public Optional<org.sonar.server.computation.measure.Measure> apply(@Nonnull org.sonar.server.computation.component.Component input) {
188       return measureRepository.getRawMeasure(input, metric);
189     }
190   }
191
192   private enum ToMeasureAPI implements Function<Optional<org.sonar.server.computation.measure.Measure>, Measure> {
193     INSTANCE;
194
195     @Nullable
196     @Override
197     public Measure apply(@Nonnull Optional<org.sonar.server.computation.measure.Measure> input) {
198       return input.isPresent() ? new MeasureImpl(input.get()) : null;
199     }
200   }
201
202 }