org.sonarsource.sonarlint.core.analysis.container.analysis.sensor.SensorsExecutor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sonarlint-core Show documentation
Show all versions of sonarlint-core Show documentation
Common library used by some SonarLint flavors
/*
* SonarLint Core - Analysis Engine
* Copyright (C) 2016-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonarsource.sonarlint.core.analysis.container.analysis.sensor;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.sonar.api.batch.DependedUpon;
import org.sonar.api.batch.DependsUpon;
import org.sonar.api.batch.Phase;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.utils.AnnotationUtils;
import org.sonar.api.utils.dag.DirectAcyclicGraph;
import org.sonarsource.sonarlint.core.analysis.sonarapi.DefaultSensorContext;
import org.sonarsource.sonarlint.core.analysis.sonarapi.DefaultSensorDescriptor;
import org.sonarsource.sonarlint.core.commons.log.SonarLintLogger;
import org.sonarsource.sonarlint.core.commons.progress.ProgressMonitor;
import static java.util.Arrays.asList;
/**
* Execute Sensors.
*/
public class SensorsExecutor {
private static final SonarLintLogger LOG = SonarLintLogger.get();
private final SensorOptimizer sensorOptimizer;
private final ProgressMonitor progress;
private final Sensor[] sensors;
private final DefaultSensorContext context;
// constructor used when no sensor is found
public SensorsExecutor(DefaultSensorContext context, SensorOptimizer sensorOptimizer, ProgressMonitor progress) {
this(context, sensorOptimizer, progress, new Sensor[0]);
}
public SensorsExecutor(DefaultSensorContext context, SensorOptimizer sensorOptimizer, ProgressMonitor progress, Sensor[] sensors) {
this.context = context;
this.sensors = sensors;
this.sensorOptimizer = sensorOptimizer;
this.progress = progress;
}
public void execute() {
for (Sensor sensor : sort(asList(sensors))) {
progress.checkCancel();
var descriptor = new DefaultSensorDescriptor();
sensor.describe(descriptor);
if (sensorOptimizer.shouldExecute(descriptor)) {
executeSensor(context, sensor, descriptor);
}
}
}
private static void executeSensor(SensorContext context, Sensor sensor, DefaultSensorDescriptor descriptor) {
var sensorName = descriptor.name() != null ? descriptor.name() : describe(sensor);
LOG.debug("Execute Sensor: {}", sensorName);
try {
sensor.execute(context);
} catch (Throwable t) {
LOG.error("Error executing sensor: '{}'", sensorName, t);
}
}
static String describe(Object o) {
try {
if (o.getClass().getMethod("toString").getDeclaringClass() != Object.class) {
var str = o.toString();
if (str != null) {
return str;
}
}
} catch (Exception e) {
// fallback
}
return o.getClass().getName();
}
private static Collection sort(Collection extensions) {
var dag = new DirectAcyclicGraph();
for (T extension : extensions) {
dag.add(extension);
for (Object dependency : getDependencies(extension)) {
dag.add(extension, dependency);
}
for (Object generates : getDependents(extension)) {
dag.add(generates, extension);
}
completePhaseDependencies(dag, extension);
}
List sortedList = dag.sort();
return (Collection) sortedList.stream()
.filter(extensions::contains)
.collect(Collectors.toList());
}
/**
* Extension dependencies
*/
private static List