org.sonar.scanner.bootstrap.AbstractExtensionDictionary Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sonar-scanner-engine Show documentation
Show all versions of sonar-scanner-engine Show documentation
Open source platform for continuous inspection of code quality
/*
* SonarQube
* Copyright (C) 2009-2023 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.sonar.scanner.bootstrap;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.apache.commons.lang.ClassUtils;
import org.sonar.api.batch.DependedUpon;
import org.sonar.api.batch.DependsUpon;
import org.sonar.api.batch.Phase;
import org.sonar.api.utils.AnnotationUtils;
import org.sonar.api.utils.dag.DirectAcyclicGraph;
import org.sonar.core.platform.ExtensionContainer;
public abstract class AbstractExtensionDictionary {
private final ExtensionContainer componentContainer;
protected AbstractExtensionDictionary(ExtensionContainer componentContainer) {
this.componentContainer = componentContainer;
}
public Collection select(Class type, boolean sort, @Nullable ExtensionMatcher matcher) {
List result = getFilteredExtensions(type, matcher);
if (sort) {
return sort(result);
}
return result;
}
private static Phase.Name evaluatePhase(Object extension) {
Phase phaseAnnotation = AnnotationUtils.getAnnotation(extension, Phase.class);
if (phaseAnnotation != null) {
return phaseAnnotation.name();
}
return Phase.Name.DEFAULT;
}
protected List getFilteredExtensions(Class type, @Nullable ExtensionMatcher matcher) {
List result = new ArrayList<>();
for (T extension : getExtensions(type)) {
if (shouldKeep(type, extension, matcher)) {
result.add(extension);
}
}
return result;
}
private List getExtensions(Class type) {
List extensions = new ArrayList<>();
completeScannerExtensions(componentContainer, extensions, type);
return extensions;
}
private static void completeScannerExtensions(ExtensionContainer container, List extensions, Class type) {
extensions.addAll(container.getComponentsByType(type));
ExtensionContainer parentContainer = container.getParent();
if (parentContainer != null) {
completeScannerExtensions(parentContainer, extensions, type);
}
}
protected Collection sort(Collection extensions) {
DirectAcyclicGraph 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 List