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;
021    
022    import org.apache.commons.lang.StringUtils;
023    import org.slf4j.Logger;
024    import org.slf4j.LoggerFactory;
025    import org.sonar.api.batch.Event;
026    import org.sonar.api.batch.SensorContext;
027    import org.sonar.api.batch.SonarIndex;
028    import org.sonar.api.batch.fs.InputDir;
029    import org.sonar.api.batch.fs.InputFile;
030    import org.sonar.api.batch.fs.InputPath;
031    import org.sonar.api.design.Dependency;
032    import org.sonar.api.measures.Measure;
033    import org.sonar.api.measures.MeasuresFilter;
034    import org.sonar.api.measures.Metric;
035    import org.sonar.api.resources.Directory;
036    import org.sonar.api.resources.File;
037    import org.sonar.api.resources.Project;
038    import org.sonar.api.resources.ProjectLink;
039    import org.sonar.api.resources.Qualifiers;
040    import org.sonar.api.resources.Resource;
041    import org.sonar.api.rules.Violation;
042    import org.sonar.api.utils.SonarException;
043    import org.sonar.core.measure.MeasurementFilters;
044    
045    import java.io.Serializable;
046    import java.util.Collection;
047    import java.util.Date;
048    import java.util.List;
049    import java.util.Set;
050    
051    public class DefaultSensorContext implements SensorContext {
052    
053      private static final Logger LOG = LoggerFactory.getLogger(DefaultSensorContext.class);
054    
055      private SonarIndex index;
056      private Project project;
057      private MeasurementFilters filters;
058    
059      public DefaultSensorContext(SonarIndex index, Project project, MeasurementFilters filters) {
060        this.index = index;
061        this.project = project;
062        this.filters = filters;
063      }
064    
065      public Project getProject() {
066        return project;
067      }
068    
069      public boolean index(Resource resource) {
070        // SONAR-5006
071        if (indexedByCore(resource)) {
072          logWarning();
073          return true;
074        }
075        return index.index(resource);
076      }
077    
078      private boolean indexedByCore(Resource resource) {
079        return StringUtils.equals(Qualifiers.DIRECTORY, resource.getQualifier()) ||
080          StringUtils.equals(Qualifiers.FILE, resource.getQualifier());
081      }
082    
083      @Override
084      public boolean index(Resource resource, Resource parentReference) {
085        // SONAR-5006
086        if (indexedByCore(resource)) {
087          logWarning();
088          return true;
089        }
090        return index.index(resource, parentReference);
091      }
092    
093      private void logWarning() {
094        if (LOG.isDebugEnabled()) {
095          LOG.debug("Plugins are no more responsible for indexing physical resources like directories and files. This is now handled by the platform.", new SonarException(
096            "Plugin should not index physical resources"));
097        }
098      }
099    
100      @Override
101      public boolean isExcluded(Resource reference) {
102        return index.isExcluded(reference);
103      }
104    
105      @Override
106      public boolean isIndexed(Resource reference, boolean acceptExcluded) {
107        return index.isIndexed(reference, acceptExcluded);
108      }
109    
110      @Override
111      public Resource getParent(Resource reference) {
112        return index.getParent(reference);
113      }
114    
115      @Override
116      public Collection<Resource> getChildren(Resource reference) {
117        return index.getChildren(reference);
118      }
119    
120      @Override
121      public <G extends Serializable> Measure<G> getMeasure(Metric<G> metric) {
122        return index.getMeasure(project, metric);
123      }
124    
125      @Override
126      public <M> M getMeasures(MeasuresFilter<M> filter) {
127        return index.getMeasures(project, filter);
128      }
129    
130      @Override
131      public Measure saveMeasure(Measure measure) {
132        return index.addMeasure(project, measure);
133      }
134    
135      @Override
136      public Measure saveMeasure(Metric metric, Double value) {
137        return index.addMeasure(project, new Measure(metric, value));
138      }
139    
140      @Override
141      public <G extends Serializable> Measure<G> getMeasure(Resource resource, Metric<G> metric) {
142        return index.getMeasure(resource, metric);
143      }
144    
145      @Override
146      public String saveResource(Resource resource) {
147        Resource persistedResource = index.addResource(resource);
148        if (persistedResource != null) {
149          return persistedResource.getEffectiveKey();
150        }
151        return null;
152      }
153    
154      public boolean saveResource(Resource resource, Resource parentReference) {
155        return index.index(resource, parentReference);
156      }
157    
158      @Override
159      public Resource getResource(Resource resource) {
160        return index.getResource(resource);
161      }
162    
163      @Override
164      public <M> M getMeasures(Resource resource, MeasuresFilter<M> filter) {
165        return index.getMeasures(resource, filter);
166      }
167    
168      @Override
169      public Measure saveMeasure(Resource resource, Metric metric, Double value) {
170        return saveMeasure(resource, new Measure(metric, value));
171      }
172    
173      @Override
174      public Measure saveMeasure(Resource resource, Measure measure) {
175        if (filters.accept(resource, measure)) {
176          return index.addMeasure(resourceOrProject(resource), measure);
177        } else {
178          return measure;
179        }
180      }
181    
182      public void saveViolation(Violation violation, boolean force) {
183        if (violation.getResource() == null) {
184          violation.setResource(resourceOrProject(violation.getResource()));
185        }
186        index.addViolation(violation, force);
187      }
188    
189      public void saveViolation(Violation violation) {
190        saveViolation(violation, false);
191      }
192    
193      public void saveViolations(Collection<Violation> violations) {
194        if (violations != null) {
195          for (Violation violation : violations) {
196            saveViolation(violation);
197          }
198        }
199      }
200    
201      public Dependency saveDependency(Dependency dependency) {
202        return index.addDependency(dependency);
203      }
204    
205      public Set<Dependency> getDependencies() {
206        return index.getDependencies();
207      }
208    
209      public Collection<Dependency> getIncomingDependencies(Resource to) {
210        return index.getIncomingEdges(resourceOrProject(to));
211      }
212    
213      public Collection<Dependency> getOutgoingDependencies(Resource from) {
214        return index.getOutgoingEdges(resourceOrProject(from));
215      }
216    
217      public void saveSource(Resource reference, String source) {
218        // useless since 4.2.
219      }
220    
221      public void saveLink(ProjectLink link) {
222        index.addLink(link);
223      }
224    
225      public void deleteLink(String key) {
226        index.deleteLink(key);
227      }
228    
229      public List<Event> getEvents(Resource resource) {
230        return index.getEvents(resource);
231      }
232    
233      public Event createEvent(Resource resource, String name, String description, String category, Date date) {
234        return index.addEvent(resource, name, description, category, date);
235      }
236    
237      public void deleteEvent(Event event) {
238        index.deleteEvent(event);
239      }
240    
241      private Resource resourceOrProject(Resource resource) {
242        if (resource == null) {
243          return project;
244        }
245        Resource indexedResource = getResource(resource);
246        return indexedResource != null ? indexedResource : resource;
247      }
248    
249      @Override
250      public Measure saveMeasure(InputFile inputFile, Metric metric, Double value) {
251        return saveMeasure(getResource(inputFile), metric, value);
252      }
253    
254      @Override
255      public Measure saveMeasure(InputFile inputFile, Measure measure) {
256        return saveMeasure(getResource(inputFile), measure);
257      }
258    
259      @Override
260      public Resource getResource(InputPath inputPath) {
261        Resource r;
262        if (inputPath instanceof InputDir) {
263          r = Directory.create(((InputDir) inputPath).relativePath());
264        } else if (inputPath instanceof InputFile) {
265          r = File.create(((InputFile) inputPath).relativePath());
266        } else {
267          throw new IllegalArgumentException("Unknow input path type: " + inputPath);
268        }
269        return getResource(r);
270      }
271    }