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 package org.sonar.batch.scan2;
021
022 import com.google.common.base.Strings;
023 import org.sonar.api.batch.bootstrap.ProjectDefinition;
024 import org.sonar.api.batch.fs.FileSystem;
025 import org.sonar.api.batch.fs.InputFile;
026 import org.sonar.api.batch.measure.Metric;
027 import org.sonar.api.batch.rule.ActiveRules;
028 import org.sonar.api.batch.rule.internal.DefaultActiveRule;
029 import org.sonar.api.batch.sensor.issue.Issue;
030 import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
031 import org.sonar.api.batch.sensor.measure.Measure;
032 import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
033 import org.sonar.api.config.Settings;
034 import org.sonar.api.rule.RuleKey;
035 import org.sonar.api.utils.MessageException;
036 import org.sonar.batch.duplication.BlockCache;
037 import org.sonar.batch.duplication.DuplicationCache;
038 import org.sonar.batch.index.ComponentDataCache;
039 import org.sonar.batch.issue.IssueFilters;
040 import org.sonar.batch.scan.SensorContextAdaptor;
041 import org.sonar.core.component.ComponentKeys;
042
043 import java.io.Serializable;
044
045 public class DefaultSensorContext extends BaseSensorContext {
046
047 private final AnalyzerMeasureCache measureCache;
048 private final AnalyzerIssueCache issueCache;
049 private final ProjectDefinition def;
050 private final ActiveRules activeRules;
051 private final IssueFilters issueFilters;
052
053 public DefaultSensorContext(ProjectDefinition def, AnalyzerMeasureCache measureCache, AnalyzerIssueCache issueCache,
054 Settings settings, FileSystem fs, ActiveRules activeRules, IssueFilters issueFilters, ComponentDataCache componentDataCache,
055 BlockCache blockCache, DuplicationCache duplicationCache) {
056 super(settings, fs, activeRules, componentDataCache, blockCache, duplicationCache);
057 this.def = def;
058 this.measureCache = measureCache;
059 this.issueCache = issueCache;
060 this.activeRules = activeRules;
061 this.issueFilters = issueFilters;
062 }
063
064 @Override
065 public Measure getMeasure(String metricKey) {
066 return measureCache.byMetric(def.getKey(), def.getKey(), metricKey);
067 }
068
069 @Override
070 public <G extends Serializable> Measure<G> getMeasure(Metric<G> metric) {
071 return (Measure<G>) measureCache.byMetric(def.getKey(), def.getKey(), metric.key());
072 }
073
074 @Override
075 public Measure getMeasure(InputFile file, String metricKey) {
076 return measureCache.byMetric(def.getKey(), ComponentKeys.createEffectiveKey(def.getKey(), file), metricKey);
077 }
078
079 @Override
080 public <G extends Serializable> Measure<G> getMeasure(InputFile file, Metric<G> metric) {
081 return (Measure<G>) measureCache.byMetric(def.getKey(), ComponentKeys.createEffectiveKey(def.getKey(), file), metric.key());
082 }
083
084 @Override
085 public void addMeasure(Measure<?> measure) {
086 InputFile inputFile = measure.inputFile();
087 if (inputFile != null) {
088 measureCache.put(def.getKey(), ComponentKeys.createEffectiveKey(def.getKey(), inputFile), (DefaultMeasure) measure);
089 } else {
090 measureCache.put(def.getKey(), def.getKey(), (DefaultMeasure) measure);
091 }
092 }
093
094 @Override
095 public boolean addIssue(Issue issue) {
096 String resourceKey;
097 if (issue.inputPath() != null) {
098 resourceKey = ComponentKeys.createEffectiveKey(def.getKey(), issue.inputPath());
099 } else {
100 resourceKey = def.getKey();
101 }
102 RuleKey ruleKey = issue.ruleKey();
103 DefaultActiveRule activeRule = (DefaultActiveRule) activeRules.find(ruleKey);
104 if (activeRule == null) {
105 // rule does not exist or is not enabled -> ignore the issue
106 return false;
107 }
108 if (Strings.isNullOrEmpty(activeRule.name()) && Strings.isNullOrEmpty(issue.message())) {
109 throw MessageException.of(String.format("The rule '%s' has no name and the related issue has no message.", ruleKey));
110 }
111
112 updateIssue((DefaultIssue) issue, activeRule);
113
114 if (issueFilters.accept(SensorContextAdaptor.toDefaultIssue(def.getKey(), resourceKey, issue), null)) {
115 issueCache.put(def.getKey(), resourceKey, (DefaultIssue) issue);
116 return true;
117 }
118
119 return false;
120 }
121
122 private void updateIssue(DefaultIssue issue, DefaultActiveRule activeRule) {
123 if (Strings.isNullOrEmpty(issue.message())) {
124 issue.setMessage(activeRule.name());
125 }
126
127 if (issue.severity() == null) {
128 issue.setSeverity(activeRule.severity());
129 }
130 }
131
132 }