aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-core
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2018-06-14 16:53:47 +0200
committerSonarTech <sonartech@sonarsource.com>2018-06-21 20:21:31 +0200
commitb1ee6a846be4e4a48ec4cdc5841ca53886c029f9 (patch)
tree233bc7c1657ab70e6de9e1ce6ccfcaf5dfcb2f0e /sonar-core
parent81a06e86f6aab48131591675ccc0dd54261c0e4f (diff)
downloadsonarqube-b1ee6a846be4e4a48ec4cdc5841ca53886c029f9.tar.gz
sonarqube-b1ee6a846be4e4a48ec4cdc5841ca53886c029f9.zip
SONAR-10690 Core Extension installed at level 1 2 3 and 4
Diffstat (limited to 'sonar-core')
-rw-r--r--sonar-core/src/main/java/org/sonar/core/extension/CoreExtensionsInstaller.java55
-rw-r--r--sonar-core/src/main/java/org/sonar/core/extension/PlatformLevel.java22
-rw-r--r--sonar-core/src/main/java/org/sonar/core/extension/PlatformLevelPredicates.java66
-rw-r--r--sonar-core/src/test/java/org/sonar/core/extension/CoreExtensionsInstallerTest.java24
4 files changed, 138 insertions, 29 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/extension/CoreExtensionsInstaller.java b/sonar-core/src/main/java/org/sonar/core/extension/CoreExtensionsInstaller.java
index a9b175f353e..2e154769a55 100644
--- a/sonar-core/src/main/java/org/sonar/core/extension/CoreExtensionsInstaller.java
+++ b/sonar-core/src/main/java/org/sonar/core/extension/CoreExtensionsInstaller.java
@@ -44,6 +44,14 @@ public abstract class CoreExtensionsInstaller {
private final CoreExtensionRepository coreExtensionRepository;
private final Class<? extends Annotation> supportedAnnotationType;
+ public static Predicate<Object> noExtensionFilter() {
+ return t -> true;
+ }
+
+ public static Predicate<Object> noAdditionalSideFilter() {
+ return t -> true;
+ }
+
protected CoreExtensionsInstaller(SonarRuntime sonarRuntime, CoreExtensionRepository coreExtensionRepository,
Class<? extends Annotation> supportedAnnotationType) {
this.sonarRuntime = sonarRuntime;
@@ -51,18 +59,25 @@ public abstract class CoreExtensionsInstaller {
this.supportedAnnotationType = supportedAnnotationType;
}
- public void install(ComponentContainer container, Predicate<Object> extensionFilter) {
+ /**
+ * @param container the container into which extensions will be installed
+ * @param extensionFilter filters extensions added to {@link CoreExtension.Context}. When it returns false, the
+ * extension is ignored as if it had never been added to the context.
+ * @param additionalSideFilter applied on top of filtering on {@link #supportedAnnotationType} to decide whether
+ * extension should be added to container as an object or only as a PropertyDefinition.
+ */
+ public void install(ComponentContainer container, Predicate<Object> extensionFilter, Predicate<Object> additionalSideFilter) {
coreExtensionRepository.loadedCoreExtensions()
- .forEach(coreExtension -> install(container, extensionFilter, coreExtension));
+ .forEach(coreExtension -> install(container, extensionFilter, additionalSideFilter, coreExtension));
}
- private void install(ComponentContainer container, Predicate<Object> extensionFilter, CoreExtension coreExtension) {
+ private void install(ComponentContainer container, Predicate<Object> extensionFilter, Predicate<Object> additionalSideFilter, CoreExtension coreExtension) {
String coreExtensionName = coreExtension.getName();
try {
- List<Object> providerKeys = addDeclaredExtensions(container, extensionFilter, coreExtension);
- addProvidedExtensions(container, extensionFilter, coreExtensionName, providerKeys);
+ List<Object> providerKeys = addDeclaredExtensions(container, extensionFilter, additionalSideFilter, coreExtension);
+ addProvidedExtensions(container, additionalSideFilter, coreExtensionName, providerKeys);
- LOG.info("Installed core extension: " + coreExtensionName);
+ LOG.debug("Installed core extension: " + coreExtensionName);
coreExtensionRepository.installed(coreExtension);
} catch (Exception e) {
throw new RuntimeException("Failed to load core extension " + coreExtensionName, e);
@@ -70,36 +85,36 @@ public abstract class CoreExtensionsInstaller {
}
private List<Object> addDeclaredExtensions(ComponentContainer container, Predicate<Object> extensionFilter,
- CoreExtension coreExtension) {
- ContextImpl context = new ContextImpl(container, extensionFilter, coreExtension.getName());
+ Predicate<Object> additionalSideFilter, CoreExtension coreExtension) {
+ ContextImpl context = new ContextImpl(container, extensionFilter, additionalSideFilter, coreExtension.getName());
coreExtension.load(context);
return context.getProviders();
}
- private void addProvidedExtensions(ComponentContainer container, Predicate<Object> extensionFilter,
+ private void addProvidedExtensions(ComponentContainer container, Predicate<Object> additionalSideFilter,
String extensionCategory, List<Object> providerKeys) {
providerKeys.stream()
.map(providerKey -> (ExtensionProvider) container.getComponentByKey(providerKey))
- .forEach(provider -> addFromProvider(container, extensionFilter, extensionCategory, provider));
+ .forEach(provider -> addFromProvider(container, additionalSideFilter, extensionCategory, provider));
}
- private void addFromProvider(ComponentContainer container, Predicate<Object> extensionFilter,
+ private void addFromProvider(ComponentContainer container, Predicate<Object> additionalSideFilter,
String extensionCategory, ExtensionProvider provider) {
Object obj = provider.provide();
if (obj != null) {
if (obj instanceof Iterable) {
for (Object ext : (Iterable) obj) {
- addSupportedExtension(container, extensionFilter, extensionCategory, ext);
+ addSupportedExtension(container, additionalSideFilter, extensionCategory, ext);
}
} else {
- addSupportedExtension(container, extensionFilter, extensionCategory, obj);
+ addSupportedExtension(container, additionalSideFilter, extensionCategory, obj);
}
}
}
- private <T> boolean addSupportedExtension(ComponentContainer container, Predicate<Object> extensionFilter,
+ private <T> boolean addSupportedExtension(ComponentContainer container, Predicate<Object> additionalSideFilter,
String extensionCategory, T component) {
- if (hasSupportedAnnotation(component) && extensionFilter.test(component)) {
+ if (hasSupportedAnnotation(component) && additionalSideFilter.test(component)) {
container.addExtension(extensionCategory, component);
return true;
}
@@ -113,12 +128,15 @@ public abstract class CoreExtensionsInstaller {
private class ContextImpl implements CoreExtension.Context {
private final ComponentContainer container;
private final Predicate<Object> extensionFilter;
+ private final Predicate<Object> additionalSideFilter;
private final String extensionCategory;
private final List<Object> providers = new ArrayList<>();
- public ContextImpl(ComponentContainer container, Predicate<Object> extensionFilter, String extensionCategory) {
+ public ContextImpl(ComponentContainer container, Predicate<Object> extensionFilter,
+ Predicate<Object> additionalSideFilter, String extensionCategory) {
this.container = container;
this.extensionFilter = extensionFilter;
+ this.additionalSideFilter = additionalSideFilter;
this.extensionCategory = extensionCategory;
}
@@ -136,8 +154,11 @@ public abstract class CoreExtensionsInstaller {
@Override
public CoreExtension.Context addExtension(Object component) {
requireNonNull(component, "component can't be null");
+ if (!extensionFilter.test(component)) {
+ return this;
+ }
- if (!addSupportedExtension(container, extensionFilter, extensionCategory, component)) {
+ if (!addSupportedExtension(container, additionalSideFilter, extensionCategory, component)) {
container.declareExtension(extensionCategory, component);
} else if (ExtensionProviderSupport.isExtensionProvider(component)) {
providers.add(component);
diff --git a/sonar-core/src/main/java/org/sonar/core/extension/PlatformLevel.java b/sonar-core/src/main/java/org/sonar/core/extension/PlatformLevel.java
index 6396deac9fe..60f81b16324 100644
--- a/sonar-core/src/main/java/org/sonar/core/extension/PlatformLevel.java
+++ b/sonar-core/src/main/java/org/sonar/core/extension/PlatformLevel.java
@@ -1,3 +1,22 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.core.extension;
import java.lang.annotation.Documented;
@@ -10,5 +29,8 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface PlatformLevel {
+ /**
+ * Supported values are: 1, 2, 3 and 4.
+ */
int value() default 4;
}
diff --git a/sonar-core/src/main/java/org/sonar/core/extension/PlatformLevelPredicates.java b/sonar-core/src/main/java/org/sonar/core/extension/PlatformLevelPredicates.java
index bda0f9cfcbc..c3f5479b17c 100644
--- a/sonar-core/src/main/java/org/sonar/core/extension/PlatformLevelPredicates.java
+++ b/sonar-core/src/main/java/org/sonar/core/extension/PlatformLevelPredicates.java
@@ -1,4 +1,68 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.core.extension;
-public class PlatformLevelPredicates {
+import java.util.function.Predicate;
+import javax.annotation.Nullable;
+import org.sonar.api.utils.AnnotationUtils;
+
+public final class PlatformLevelPredicates {
+ private PlatformLevelPredicates() {
+ // prevents instantiation
+ }
+
+ public static Predicate<Object> hasPlatformLevel(int i) {
+ checkSupportedLevel(i, null);
+ return o -> {
+ PlatformLevel platformLevel = AnnotationUtils.getAnnotation(o, PlatformLevel.class);
+ return platformLevel != null && checkSupportedLevel(platformLevel.value(), o) == i;
+ };
+ }
+
+ private static int checkSupportedLevel(int i, @Nullable Object annotatedObject) {
+ boolean supported = i >= 1 && i <= 4;
+ if (supported) {
+ return i;
+ }
+
+ throw new IllegalArgumentException(buildErrorMsgFrom(annotatedObject));
+ }
+
+ private static String buildErrorMsgFrom(@Nullable Object annotatedObject) {
+ String baseErrorMsg = "Only level 1, 2, 3 and 4 are supported";
+ if (annotatedObject == null) {
+ return baseErrorMsg;
+ } else if (annotatedObject instanceof Class) {
+ return String.format("Invalid value for annotation %s on class '%s'. %s",
+ PlatformLevel.class.getName(), ((Class) annotatedObject).getName(),
+ baseErrorMsg);
+ } else {
+ return String.format("Invalid value for annotation %s on object of type %s. %s",
+ PlatformLevel.class.getName(), annotatedObject.getClass().getName(), baseErrorMsg);
+ }
+ }
+
+ public static Predicate<Object> hasPlatformLevel4OrNone() {
+ return o -> {
+ PlatformLevel platformLevel = AnnotationUtils.getAnnotation(o, PlatformLevel.class);
+ return platformLevel == null || checkSupportedLevel(platformLevel.value(), o) == 4;
+ };
+ }
}
diff --git a/sonar-core/src/test/java/org/sonar/core/extension/CoreExtensionsInstallerTest.java b/sonar-core/src/test/java/org/sonar/core/extension/CoreExtensionsInstallerTest.java
index d9d03370863..aa63f2a0d32 100644
--- a/sonar-core/src/test/java/org/sonar/core/extension/CoreExtensionsInstallerTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/extension/CoreExtensionsInstallerTest.java
@@ -55,6 +55,8 @@ import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.sonar.core.extension.CoreExtensionsInstaller.noAdditionalSideFilter;
+import static org.sonar.core.extension.CoreExtensionsInstaller.noExtensionFilter;
import static org.sonar.core.platform.ComponentContainer.COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER;
@RunWith(DataProviderRunner.class)
@@ -72,7 +74,7 @@ public class CoreExtensionsInstallerTest {
public void install_has_no_effect_if_CoreExtensionRepository_has_no_loaded_CoreExtension() {
ComponentContainer container = new ComponentContainer();
- underTest.install(container, t -> true);
+ underTest.install(container, noExtensionFilter(), noAdditionalSideFilter());
assertAddedExtensions(container, 0);
}
@@ -88,7 +90,7 @@ public class CoreExtensionsInstallerTest {
when(coreExtensionRepository.loadedCoreExtensions()).thenReturn(coreExtensions.stream());
ComponentContainer container = new ComponentContainer();
- underTest.install(container, t -> true);
+ underTest.install(container, noExtensionFilter(), noAdditionalSideFilter());
inOrder.verify(coreExtension1).load(contextCaptor.capture());
inOrder.verify(coreExtension2).load(contextCaptor.capture());
@@ -106,7 +108,7 @@ public class CoreExtensionsInstallerTest {
when(coreExtensionRepository.loadedCoreExtensions()).thenReturn(Stream.of(coreExtension1, coreExtension2));
ComponentContainer container = new ComponentContainer();
- underTest.install(container, t -> true);
+ underTest.install(container, noExtensionFilter(), noAdditionalSideFilter());
verify(coreExtension1).load(contextCaptor.capture());
verify(coreExtension2).load(contextCaptor.capture());
@@ -122,7 +124,7 @@ public class CoreExtensionsInstallerTest {
when(coreExtensionRepository.loadedCoreExtensions()).thenReturn(Stream.of(coreExtension1, coreExtension2));
ComponentContainer container = new ComponentContainer();
- underTest.install(container, t -> true);
+ underTest.install(container, noExtensionFilter(), noAdditionalSideFilter());
verify(coreExtension1).load(contextCaptor.capture());
verify(coreExtension2).load(contextCaptor.capture());
@@ -140,7 +142,7 @@ public class CoreExtensionsInstallerTest {
ComponentContainer container = new ComponentContainer();
container.add(configuration);
- underTest.install(container, t -> true);
+ underTest.install(container, noExtensionFilter(), noAdditionalSideFilter());
verify(coreExtension1).load(contextCaptor.capture());
verify(coreExtension2).load(contextCaptor.capture());
@@ -157,7 +159,7 @@ public class CoreExtensionsInstallerTest {
when(coreExtensionRepository.loadedCoreExtensions()).thenReturn(Stream.of(coreExtension));
ComponentContainer container = new ComponentContainer();
- underTest.install(container, t -> true);
+ underTest.install(container, noExtensionFilter(), noAdditionalSideFilter());
assertAddedExtensions(container, WestSideClass.class, Latitude.class);
assertPropertyDefinitions(container);
@@ -171,7 +173,7 @@ public class CoreExtensionsInstallerTest {
when(coreExtensionRepository.loadedCoreExtensions()).thenReturn(Stream.of(coreExtension));
ComponentContainer container = new ComponentContainer();
- underTest.install(container, t -> t != Latitude.class);
+ underTest.install(container, noExtensionFilter(), t -> t != Latitude.class);
assertAddedExtensions(container, WestSideClass.class);
assertPropertyDefinitions(container);
@@ -186,7 +188,7 @@ public class CoreExtensionsInstallerTest {
when(coreExtensionRepository.loadedCoreExtensions()).thenReturn(Stream.of(coreExtension));
ComponentContainer container = new ComponentContainer();
- underTest.install(container, t -> true);
+ underTest.install(container, noExtensionFilter(), noAdditionalSideFilter());
assertAddedExtensions(container, WestSidePropertyDefinition.class, LatitudePropertyDefinition.class);
assertPropertyDefinitions(container, "westKey", "eastKey", "otherKey", "latitudeKey", "blankKey");
@@ -201,7 +203,7 @@ public class CoreExtensionsInstallerTest {
when(coreExtensionRepository.loadedCoreExtensions()).thenReturn(Stream.of(coreExtension));
ComponentContainer container = new ComponentContainer();
- underTest.install(container, t -> false);
+ underTest.install(container, noExtensionFilter(), t -> false);
assertAddedExtensions(container, 0);
assertPropertyDefinitions(container, "westKey", "eastKey", "otherKey", "latitudeKey", "blankKey");
@@ -217,7 +219,7 @@ public class CoreExtensionsInstallerTest {
when(coreExtensionRepository.loadedCoreExtensions()).thenReturn(Stream.of(coreExtension));
ComponentContainer container = new ComponentContainer();
- underTest.install(container, t -> true);
+ underTest.install(container, noExtensionFilter(), noAdditionalSideFilter());
assertAddedExtensions(container, 0);
assertPropertyDefinitions(container, coreExtension, propertyDefinitionNoCategory, propertyDefinitionWithCategory);
@@ -231,7 +233,7 @@ public class CoreExtensionsInstallerTest {
when(coreExtensionRepository.loadedCoreExtensions()).thenReturn(Stream.of(coreExtension));
ComponentContainer container = new ComponentContainer();
- underTest.install(container, t -> true);
+ underTest.install(container, noExtensionFilter(), noAdditionalSideFilter());
assertAddedExtensions(container, WestSideProvider.class, WestSideProvided.class, PartiallyWestSideProvider.class);
assertPropertyDefinitions(container);