From 51b039e64390e33984951cca7a722244cb136753 Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Wed, 19 Jul 2017 17:56:52 +0200 Subject: [PATCH] SONAR-9551 PropertyDefinition and ResourceTypeTree correctly handles APP qualifier --- .../sonar/api/config/PropertyDefinition.java | 11 +++--- .../org/sonar/api/resources/Qualifiers.java | 18 +++++----- .../sonar/api/resources/ResourceTypes.java | 31 +++++++--------- .../api/config/PropertyDefinitionTest.java | 4 +-- .../api/config/PropertyDefinitionsTest.java | 9 ++--- .../sonar/api/resources/QualifiersTest.java | 13 +++++++ .../api/resources/ResourceTypesTest.java | 36 +++++++++---------- 7 files changed, 65 insertions(+), 57 deletions(-) diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java index 510a9013d35..f9bd76d4618 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java @@ -92,7 +92,8 @@ import static org.sonar.api.PropertyType.SINGLE_SELECT_LIST; @ExtensionPoint public final class PropertyDefinition { - private static final Set SUPPORTED_QUALIFIERS = unmodifiableSet(new LinkedHashSet<>(asList(Qualifiers.PROJECT, Qualifiers.VIEW, Qualifiers.MODULE, Qualifiers.SUBVIEW))); + private static final Set SUPPORTED_QUALIFIERS = unmodifiableSet(new LinkedHashSet<>( + asList(Qualifiers.PROJECT, Qualifiers.VIEW, Qualifiers.MODULE, Qualifiers.SUBVIEW, Qualifiers.APP))); private String key; private String defaultValue; @@ -436,7 +437,7 @@ public final class PropertyDefinition { * See supported constant values in {@link Qualifiers}. By default property is available * only in General Settings. * - * @throws IllegalArgumentException only qualifiers {@link Qualifiers#PROJECT PROJECT}, {@link Qualifiers#MODULE MODULE}, + * @throws IllegalArgumentException only qualifiers {@link Qualifiers#PROJECT PROJECT}, {@link Qualifiers#MODULE MODULE}, {@link Qualifiers#APP APP}, * {@link Qualifiers#VIEW VIEW} and {@link Qualifiers#SUBVIEW SVW} are allowed. */ public Builder onQualifiers(String first, String... rest) { @@ -455,6 +456,8 @@ public final class PropertyDefinition { * See supported constant values in {@link Qualifiers}. By default property is available * only in General Settings. * + * @throws IllegalArgumentException only qualifiers {@link Qualifiers#PROJECT PROJECT}, {@link Qualifiers#MODULE MODULE}, {@link Qualifiers#APP APP}, + * {@link Qualifiers#VIEW VIEW} and {@link Qualifiers#SUBVIEW SVW} are allowed. * @throws IllegalArgumentException only qualifiers {@link Qualifiers#PROJECT PROJECT}, {@link Qualifiers#MODULE MODULE}, * {@link Qualifiers#VIEW VIEW} and {@link Qualifiers#SUBVIEW SVW} are allowed. */ @@ -474,7 +477,7 @@ public final class PropertyDefinition { * See supported constant values in {@link Qualifiers}. By default property is available * only in General Settings. * - * @throws IllegalArgumentException only qualifiers {@link Qualifiers#PROJECT PROJECT}, {@link Qualifiers#MODULE MODULE}, + * @throws IllegalArgumentException only qualifiers {@link Qualifiers#PROJECT PROJECT}, {@link Qualifiers#MODULE MODULE}, {@link Qualifiers#APP APP}, * {@link Qualifiers#VIEW VIEW} and {@link Qualifiers#SUBVIEW SVW} are allowed. */ public Builder onlyOnQualifiers(String first, String... rest) { @@ -493,7 +496,7 @@ public final class PropertyDefinition { * See supported constant values in {@link Qualifiers}. By default property is available * only in General Settings. * - * @throws IllegalArgumentException only qualifiers {@link Qualifiers#PROJECT PROJECT}, {@link Qualifiers#MODULE MODULE}, + * @throws IllegalArgumentException only qualifiers {@link Qualifiers#PROJECT PROJECT}, {@link Qualifiers#MODULE MODULE}, {@link Qualifiers#APP APP}, * {@link Qualifiers#VIEW VIEW} and {@link Qualifiers#SUBVIEW SVW} are allowed. */ public Builder onlyOnQualifiers(List qualifiers) { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Qualifiers.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Qualifiers.java index caa8e8af8dc..2ad2e7cfb41 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Qualifiers.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Qualifiers.java @@ -19,7 +19,7 @@ */ package org.sonar.api.resources; -import org.apache.commons.lang.StringUtils; +import java.util.Objects; /** * The qualifier determines the exact type of a resource. @@ -78,9 +78,9 @@ public final class Qualifiers { * @param resource not nullable */ public static boolean isView(final Resource resource, final boolean acceptSubViews) { - boolean isView = StringUtils.equals(VIEW, resource.getQualifier()); + boolean isView = Objects.equals(VIEW, resource.getQualifier()); if (!isView && acceptSubViews) { - isView = StringUtils.equals(SUBVIEW, resource.getQualifier()); + isView = Objects.equals(SUBVIEW, resource.getQualifier()); } return isView; @@ -90,16 +90,16 @@ public final class Qualifiers { * @param resource not nullable */ public static boolean isSubview(final Resource resource) { - return StringUtils.equals(SUBVIEW, resource.getScope()); + return Objects.equals(SUBVIEW, resource.getScope()); } /** * @param resource not nullable */ public static boolean isProject(final Resource resource, final boolean acceptModules) { - boolean isProject = StringUtils.equals(PROJECT, resource.getQualifier()); + boolean isProject = Objects.equals(PROJECT, resource.getQualifier()); if (!isProject && acceptModules) { - isProject = StringUtils.equals(MODULE, resource.getQualifier()); + isProject = Objects.equals(MODULE, resource.getQualifier()); } return isProject; } @@ -108,20 +108,20 @@ public final class Qualifiers { * @param resource not nullable */ public static boolean isModule(final Resource resource) { - return StringUtils.equals(MODULE, resource.getQualifier()); + return Objects.equals(MODULE, resource.getQualifier()); } /** * @param resource not nullable */ public static boolean isDirectory(final Resource resource) { - return StringUtils.equals(DIRECTORY, resource.getQualifier()); + return Objects.equals(DIRECTORY, resource.getQualifier()); } /** * @param resource not nullable */ public static boolean isFile(final Resource resource) { - return StringUtils.equals(FILE, resource.getQualifier()); + return Objects.equals(FILE, resource.getQualifier()); } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java index dcbfe98c801..8e2a1c578fe 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java @@ -28,8 +28,10 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.server.ServerSide; @@ -77,27 +79,18 @@ public class ResourceTypes { treeByQualifier = unmodifiableMap(new LinkedHashMap<>(treeMap)); typeByQualifier = unmodifiableMap(new LinkedHashMap<>(typeMap)); rootTypes = unmodifiableList(new ArrayList<>(rootsSet)); + orderedTypes = unmodifiableSet(orderedTypes(typeMap)); + } - List mutableOrderedTypes = new ArrayList<>(); - ResourceType view = null; - ResourceType subView = null; - for (ResourceType resourceType : typeByQualifier.values()) { - if (Qualifiers.VIEW.equals(resourceType.getQualifier())) { - view = resourceType; - } else if (Qualifiers.SUBVIEW.equals(resourceType.getQualifier())) { - subView = resourceType; - } else { - mutableOrderedTypes.add(resourceType); - } - } - if (subView != null) { - mutableOrderedTypes.add(0, subView); - } - if (view != null) { - mutableOrderedTypes.add(0, view); - } + private static Set orderedTypes(Map typeByQualifier) { + Map mutableTypesByQualifier = new LinkedHashMap<>(typeByQualifier); + ResourceType view = mutableTypesByQualifier.remove(Qualifiers.VIEW); + ResourceType subView = mutableTypesByQualifier.remove(Qualifiers.SUBVIEW); + ResourceType application = mutableTypesByQualifier.remove(Qualifiers.APP); - orderedTypes = unmodifiableSet(new LinkedHashSet<>(mutableOrderedTypes)); + return Stream.concat(Stream.of(view, subView, application), mutableTypesByQualifier.values().stream()) + .filter(Objects::nonNull) + .collect(Collectors.toCollection(LinkedHashSet::new)); } public ResourceType get(String qualifier) { diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionTest.java index 2ba172ed75b..e6541af8691 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionTest.java @@ -317,7 +317,7 @@ public class PropertyDefinitionTest { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Cannot be hidden and defining qualifiers on which to display"); - PropertyDefinition.builder("foo").name("foo").onQualifiers(Qualifiers.VIEW).hidden().build(); + PropertyDefinition.builder("foo").name("foo").onQualifiers(Qualifiers.PROJECT).hidden().build(); } @Test @@ -414,7 +414,7 @@ public class PropertyDefinitionTest { biConsumer.accept(builder, qualifier); fail("A IllegalArgumentException should have been thrown for qualifier " + qualifier); } catch (IllegalArgumentException e) { - assertThat(e).hasMessage("Qualifier must be one of [TRK, VW, BRC, SVW]"); + assertThat(e).hasMessage("Qualifier must be one of [TRK, VW, BRC, SVW, APP]"); } }); } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionsTest.java index 78e3150fd15..649ace7b722 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionsTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionsTest.java @@ -19,14 +19,13 @@ */ package org.sonar.api.config; +import java.util.Arrays; +import java.util.List; import org.junit.Test; import org.sonar.api.Properties; import org.sonar.api.Property; import org.sonar.api.resources.Qualifiers; -import java.util.Arrays; -import java.util.List; - import static org.assertj.core.api.Assertions.assertThat; public class PropertyDefinitionsTest { @@ -125,13 +124,15 @@ public class PropertyDefinitionsTest { PropertyDefinition.builder("global3").name("Global3").category("catGlobal2").build(), PropertyDefinition.builder("project").name("Project").category("catProject").onlyOnQualifiers(Qualifiers.PROJECT).build(), PropertyDefinition.builder("module").name("Module").category("catModule").onlyOnQualifiers(Qualifiers.MODULE).build(), - PropertyDefinition.builder("view").name("View").category("catView").onlyOnQualifiers(Qualifiers.VIEW).build() + PropertyDefinition.builder("view").name("View").category("catView").onlyOnQualifiers(Qualifiers.VIEW).build(), + PropertyDefinition.builder("app").name("Application").category("catApp").onlyOnQualifiers(Qualifiers.APP).build() ); assertThat(def.propertiesByCategory(null).keySet()).contains(new Category("catGlobal1"), new Category("catGlobal2")); assertThat(def.propertiesByCategory(Qualifiers.PROJECT).keySet()).containsOnly(new Category("catProject")); assertThat(def.propertiesByCategory(Qualifiers.MODULE).keySet()).containsOnly(new Category("catModule")); assertThat(def.propertiesByCategory(Qualifiers.VIEW).keySet()).containsOnly(new Category("catView")); + assertThat(def.propertiesByCategory(Qualifiers.APP).keySet()).containsOnly(new Category("catApp")); assertThat(def.propertiesByCategory("Unkown").keySet()).isEmpty(); } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/QualifiersTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/QualifiersTest.java index 112d1818408..9cdf2c05c7e 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/resources/QualifiersTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/QualifiersTest.java @@ -35,6 +35,15 @@ public class QualifiersTest { assertThat(Qualifiers.isProject(root, false)).isFalse(); } + @Test + public void application() { + View root = View.createRootApp(); + assertThat(Qualifiers.isView(root, true)).isFalse(); + assertThat(Qualifiers.isView(root, false)).isFalse(); + assertThat(Qualifiers.isProject(root, true)).isFalse(); + assertThat(Qualifiers.isProject(root, false)).isFalse(); + } + @Test public void testSubView() { View subview = View.createSubView(); @@ -80,6 +89,10 @@ public class QualifiersTest { return new View(Qualifiers.VIEW); } + static View createRootApp() { + return new View(Qualifiers.APP); + } + static View createSubView() { return new View(Qualifiers.SUBVIEW); } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/ResourceTypesTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/ResourceTypesTest.java index 5f5190650bd..93c76f897e6 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/resources/ResourceTypesTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/ResourceTypesTest.java @@ -19,11 +19,9 @@ */ package org.sonar.api.resources; -import com.google.common.base.Function; import com.google.common.collect.Collections2; -import org.junit.Test; - import java.util.Collection; +import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -36,6 +34,11 @@ public class ResourceTypesTest { .addRelations(Qualifiers.SUBVIEW, Qualifiers.PROJECT) .build(); + private ResourceTypeTree applicationTree = ResourceTypeTree.builder() + .addType(ResourceType.builder(Qualifiers.APP).setProperty("supportsMeasureFilters", "true").build()) + .addRelations(Qualifiers.APP, Qualifiers.PROJECT) + .build(); + private ResourceTypeTree defaultTree = ResourceTypeTree.builder() .addType(ResourceType.builder(Qualifiers.PROJECT).setProperty("supportsMeasureFilters", "true").build()) .addType(ResourceType.builder(Qualifiers.DIRECTORY).build()) @@ -44,7 +47,7 @@ public class ResourceTypesTest { .addRelations(Qualifiers.DIRECTORY, Qualifiers.FILE) .build(); - private ResourceTypes types = new ResourceTypes(new ResourceTypeTree[] {defaultTree, viewsTree}); + private ResourceTypes types = new ResourceTypes(new ResourceTypeTree[] {defaultTree, viewsTree, applicationTree}); @Test public void get() { @@ -56,34 +59,34 @@ public class ResourceTypesTest { @Test public void get_all() { - assertThat(qualifiers(types.getAll())).containsExactly(Qualifiers.PROJECT, Qualifiers.DIRECTORY, Qualifiers.FILE, Qualifiers.VIEW, Qualifiers.SUBVIEW); + assertThat(qualifiers(types.getAll())).containsExactly(Qualifiers.PROJECT, Qualifiers.DIRECTORY, Qualifiers.FILE, Qualifiers.VIEW, Qualifiers.SUBVIEW, Qualifiers.APP); } @Test public void get_all_ordered() { - assertThat(qualifiers(types.getAllOrdered())).containsExactly(Qualifiers.VIEW, Qualifiers.SUBVIEW, Qualifiers.PROJECT, Qualifiers.DIRECTORY, Qualifiers.FILE); + assertThat(qualifiers(types.getAllOrdered())).containsExactly(Qualifiers.VIEW, Qualifiers.SUBVIEW, Qualifiers.APP, Qualifiers.PROJECT, Qualifiers.DIRECTORY, Qualifiers.FILE); } @Test public void get_roots() { - assertThat(qualifiers(types.getRoots())).containsOnly(Qualifiers.PROJECT, Qualifiers.VIEW); + assertThat(qualifiers(types.getRoots())).containsOnly(Qualifiers.PROJECT, Qualifiers.VIEW, Qualifiers.APP); } @Test public void get_all_predicate() { Collection forFilters = types.getAll(ResourceTypes.AVAILABLE_FOR_FILTERS); - assertThat(qualifiers(forFilters)).containsOnly(Qualifiers.PROJECT, Qualifiers.VIEW).doesNotHaveDuplicates(); + assertThat(qualifiers(forFilters)).containsOnly(Qualifiers.PROJECT, Qualifiers.VIEW, Qualifiers.APP).doesNotHaveDuplicates(); } @Test public void get_all_with_property_key() { - assertThat(qualifiers(types.getAllWithPropertyKey("supportsMeasureFilters"))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT); + assertThat(qualifiers(types.getAllWithPropertyKey("supportsMeasureFilters"))).containsOnly(Qualifiers.APP, Qualifiers.VIEW, Qualifiers.PROJECT); } @Test public void get_all_with_property_value() { - assertThat(qualifiers(types.getAllWithPropertyValue("supportsMeasureFilters", "true"))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT); - assertThat(qualifiers(types.getAllWithPropertyValue("supportsMeasureFilters", true))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT); + assertThat(qualifiers(types.getAllWithPropertyValue("supportsMeasureFilters", "true"))).containsOnly(Qualifiers.APP, Qualifiers.VIEW, Qualifiers.PROJECT); + assertThat(qualifiers(types.getAllWithPropertyValue("supportsMeasureFilters", true))).containsOnly(Qualifiers.APP, Qualifiers.VIEW, Qualifiers.PROJECT); assertThat(qualifiers(types.getAllWithPropertyValue("supportsMeasureFilters", false))).containsOnly(Qualifiers.SUBVIEW, Qualifiers.DIRECTORY, Qualifiers.FILE); } @@ -104,17 +107,16 @@ public class ResourceTypesTest { @Test public void get_leaves_qualifiers() { assertThat(types.getLeavesQualifiers(Qualifiers.PROJECT)).containsExactly(Qualifiers.FILE); - assertThat(types.getLeavesQualifiers(Qualifiers.DIRECTORY)).containsExactly(Qualifiers.FILE); - assertThat(types.getLeavesQualifiers(Qualifiers.VIEW)).containsExactly(Qualifiers.PROJECT); - + assertThat(types.getLeavesQualifiers(Qualifiers.APP)).containsExactly(Qualifiers.PROJECT); assertThat(types.getLeavesQualifiers("xxx")).isEmpty(); } @Test public void get_tree() { assertThat(qualifiers(types.getTree(Qualifiers.VIEW).getTypes())).containsOnly(Qualifiers.VIEW, Qualifiers.SUBVIEW).doesNotHaveDuplicates(); + assertThat(qualifiers(types.getTree(Qualifiers.APP).getTypes())).containsOnly(Qualifiers.APP).doesNotHaveDuplicates(); assertThat(types.getTree("xxx")).isNull(); } @@ -136,10 +138,6 @@ public class ResourceTypesTest { } static Collection qualifiers(Collection types) { - return Collections2.transform(types, new Function() { - public String apply(ResourceType type) { - return type.getQualifier(); - } - }); + return Collections2.transform(types, ResourceType::getQualifier); } } -- 2.39.5