diff options
19 files changed, 131 insertions, 39 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/LanguageParamUtils.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/LanguageParamUtils.java index fe7d71ff613..b82fc64edba 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/LanguageParamUtils.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/LanguageParamUtils.java @@ -17,7 +17,7 @@ * 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.server.qualityprofile.ws; +package org.sonar.server.component.ws; import com.google.common.collect.Collections2; import org.sonar.api.resources.Language; @@ -27,13 +27,13 @@ import org.sonar.core.util.NonNullInputFunction; import java.util.Arrays; import java.util.Collection; -class LanguageParamUtils { +public class LanguageParamUtils { private LanguageParamUtils() { // Utility class } - static String getExampleValue(Languages languages) { + public static String getExampleValue(Languages languages) { Language[] languageArray = languages.all(); if (languageArray.length > 0) { return languageArray[0].getKey(); @@ -42,7 +42,7 @@ class LanguageParamUtils { } } - static Collection<String> getLanguageKeys(Languages languages) { + public static Collection<String> getLanguageKeys(Languages languages) { return Collections2.transform(Arrays.asList(languages.all()), new NonNullInputFunction<Language, String>() { @Override public String doApply(Language input) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java index ad46f1d3a50..106817ee760 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Set; import javax.annotation.Nonnull; import org.sonar.api.i18n.I18n; +import org.sonar.api.resources.Languages; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.ResourceTypes; import org.sonar.api.server.ws.Request; @@ -48,6 +49,7 @@ import static java.lang.String.format; import static org.sonar.server.component.ResourceTypeFunctions.RESOURCE_TYPE_TO_QUALIFIER; import static org.sonar.server.ws.WsUtils.checkRequest; import static org.sonar.server.ws.WsUtils.writeProtobuf; +import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_LANGUAGE; import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_QUALIFIERS; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER; @@ -58,12 +60,14 @@ public class SearchAction implements ComponentsWsAction { private final ResourceTypes resourceTypes; private final I18n i18n; private final UserSession userSession; + private final Languages languages; - public SearchAction(DbClient dbClient, ResourceTypes resourceTypes, I18n i18n, UserSession userSession) { + public SearchAction(DbClient dbClient, ResourceTypes resourceTypes, I18n i18n, UserSession userSession, Languages languages) { this.dbClient = dbClient; this.resourceTypes = resourceTypes; this.i18n = i18n; this.userSession = userSession; + this.languages = languages; } @Override @@ -81,6 +85,13 @@ public class SearchAction implements ComponentsWsAction { .setRequired(true) .setExampleValue(format("%s,%s", Qualifiers.PROJECT, Qualifiers.MODULE)) .setDescription("Comma-separated list of component qualifiers. Possible values are " + buildQualifiersDescription()); + + action + .createParam(PARAM_LANGUAGE) + .setDescription("Language key. If provided, only components for the given language are returned.") + .setExampleValue(LanguageParamUtils.getExampleValue(languages)) + .setPossibleValues(LanguageParamUtils.getLanguageKeys(languages)) + .setSince("5.4"); } @Override @@ -109,6 +120,7 @@ public class SearchAction implements ComponentsWsAction { private static SearchWsRequest toSearchWsRequest(Request request) { return new SearchWsRequest() .setQualifiers(request.mandatoryParamAsStrings(PARAM_QUALIFIERS)) + .setLanguage(request.param(PARAM_LANGUAGE)) .setQuery(request.param(Param.TEXT_QUERY)) .setPage(request.mandatoryParamAsInt(Param.PAGE)) .setPageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE)); @@ -147,6 +159,7 @@ public class SearchAction implements ComponentsWsAction { private ComponentQuery buildQuery(SearchWsRequest request, List<String> qualifiers) { return new ComponentQuery( request.getQuery(), + request.getLanguage(), qualifiers.toArray(new String[qualifiers.size()])); } @@ -185,12 +198,16 @@ public class SearchAction implements ComponentsWsAction { @Override public WsComponents.Component apply(@Nonnull ComponentDto dto) { - return WsComponents.Component.newBuilder() + WsComponents.Component.Builder builder = WsComponents.Component.newBuilder() .setId(dto.uuid()) .setKey(dto.key()) .setName(dto.name()) - .setQualifier(dto.qualifier()) - .build(); + .setQualifier(dto.qualifier()); + if (dto.language() != null) { + builder.setLanguage(dto.language()); + } + + return builder.build(); } } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ActivityAction.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ActivityAction.java index e7b483eed85..96257566307 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ActivityAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ActivityAction.java @@ -160,7 +160,7 @@ public class ActivityAction implements CeWsAction { query.setComponentUuid(componentUuid); } if (componentQuery != null) { - ComponentQuery componentDtoQuery = new ComponentQuery(componentQuery, Qualifiers.PROJECT, Qualifiers.VIEW); + ComponentQuery componentDtoQuery = new ComponentQuery(componentQuery, null, Qualifiers.PROJECT, Qualifiers.VIEW); List<ComponentDto> componentDtos = dbClient.componentDao().selectByQuery(dbSession, componentDtoQuery, 0, CeActivityQuery.MAX_COMPONENT_UUIDS); query.setComponentUuids(Lists.transform(componentDtos, ComponentDtoFunctions.toUuid())); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java index 28f096e8d3a..10aa71531f1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java @@ -32,6 +32,7 @@ import org.sonar.core.permission.GlobalPermissions; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.qualityprofile.QualityProfileDto; +import org.sonar.server.component.ws.LanguageParamUtils; import org.sonarqube.ws.MediaTypes; import org.sonar.server.qualityprofile.QProfileExporters; import org.sonar.server.qualityprofile.QProfileFactory; diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ExportAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ExportAction.java index da8f1393c55..cbf98d46ac2 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ExportAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ExportAction.java @@ -37,6 +37,7 @@ import org.sonar.api.server.ws.WebService.NewAction; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.qualityprofile.QualityProfileDto; +import org.sonar.server.component.ws.LanguageParamUtils; import org.sonar.server.exceptions.NotFoundException; import org.sonarqube.ws.MediaTypes; import org.sonar.server.qualityprofile.QProfileBackuper; diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ProjectAssociationActions.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ProjectAssociationActions.java index 037b02cf0ba..49fda68b539 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ProjectAssociationActions.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ProjectAssociationActions.java @@ -28,6 +28,7 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.NewAction; import org.sonar.server.component.ComponentService; +import org.sonar.server.component.ws.LanguageParamUtils; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.qualityprofile.QProfile; import org.sonar.server.qualityprofile.QProfileLookup; diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileIdentificationParamUtils.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileIdentificationParamUtils.java index 36297c5ece9..e135f6b58c7 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileIdentificationParamUtils.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileIdentificationParamUtils.java @@ -25,6 +25,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.WebService.NewAction; import org.sonar.db.DbSession; import org.sonar.db.qualityprofile.QualityProfileDto; +import org.sonar.server.component.ws.LanguageParamUtils; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.qualityprofile.QProfileFactory; diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java index 6e55813f892..6b63aa04fbc 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java @@ -28,6 +28,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.NewAction; +import org.sonar.server.component.ws.LanguageParamUtils; import org.sonar.server.qualityprofile.QProfile; import org.sonarqube.ws.QualityProfiles; import org.sonarqube.ws.QualityProfiles.SearchWsResponse; diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SetDefaultAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SetDefaultAction.java index e0032982045..d7b014304c9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SetDefaultAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SetDefaultAction.java @@ -26,6 +26,7 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.NewAction; import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.component.ws.LanguageParamUtils; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.qualityprofile.QProfile; import org.sonar.server.qualityprofile.QProfileFactory; diff --git a/server/sonar-server/src/main/resources/org/sonar/server/component/ws/search-components-example.json b/server/sonar-server/src/main/resources/org/sonar/server/component/ws/search-components-example.json index 80a9ad94cca..1053ac8d311 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/component/ws/search-components-example.json +++ b/server/sonar-server/src/main/resources/org/sonar/server/component/ws/search-components-example.json @@ -15,7 +15,8 @@ "id": "file-uuid", "key": "file-key", "qualifier": "FIL", - "name": "File Name" + "name": "File Name", + "language": "java" }, { "id": "module-uuid", diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java index 6020baaa32e..d8362cf0a83 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java @@ -24,6 +24,8 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.sonar.api.i18n.I18n; +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Languages; import org.sonar.api.resources.ResourceTypes; import org.sonar.api.server.ws.RailsHandler; import org.sonar.api.server.ws.WebService; @@ -34,7 +36,9 @@ import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.WsTester; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class ComponentsWsTest { @Rule @@ -44,10 +48,13 @@ public class ComponentsWsTest { @Before public void setUp() { + Languages languages = mock(Languages.class, RETURNS_DEEP_STUBS); + when(languages.all()).thenReturn(new Language[0]); + WsTester tester = new WsTester(new ComponentsWs( new AppAction(mock(DbClient.class), mock(Durations.class), mock(I18n.class), userSessionRule, mock(ComponentFinder.class)), new SearchViewComponentsAction(mock(DbClient.class), userSessionRule, mock(ComponentFinder.class)), - new SearchAction(mock(org.sonar.db.DbClient.class), mock(ResourceTypes.class), mock(I18n.class), userSessionRule) + new SearchAction(mock(org.sonar.db.DbClient.class), mock(ResourceTypes.class), mock(I18n.class), userSessionRule, languages) )); controller = tester.controller("api/components"); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java index 5d557311a73..c54d3a9c5ce 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java @@ -23,20 +23,20 @@ package org.sonar.server.component.ws; import com.google.common.base.Joiner; import java.io.IOException; import java.io.InputStream; -import java.util.List; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Languages; import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.ResourceType; -import org.sonar.api.resources.ResourceTypes; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.System2; import org.sonar.core.permission.GlobalPermissions; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDbTester; import org.sonar.db.component.ComponentDto; +import org.sonar.db.component.ResourceTypesRule; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.UnauthorizedException; @@ -47,7 +47,6 @@ import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.MediaTypes; import org.sonarqube.ws.WsComponents.SearchWsResponse; -import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -56,8 +55,9 @@ import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newModuleDto; import static org.sonar.db.component.ComponentTesting.newProjectDto; import static org.sonar.db.component.ComponentTesting.newView; -import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_QUALIFIERS; import static org.sonar.test.JsonAssert.assertJson; +import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_LANGUAGE; +import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_QUALIFIERS; public class SearchActionTest { @Rule @@ -70,15 +70,17 @@ public class SearchActionTest { I18nRule i18n = new I18nRule(); WsActionTester ws; - ResourceTypes resourceTypes; + ResourceTypesRule resourceTypes = new ResourceTypesRule(); + Languages languages; @Before public void setUp() { userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - resourceTypes = mock(ResourceTypes.class); - when(resourceTypes.getAll()).thenReturn(resourceTypes()); + resourceTypes.setAllQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE, Qualifiers.DIRECTORY, Qualifiers.FILE); + languages = mock(Languages.class); + when(languages.all()).thenReturn(javaLanguage()); - ws = new WsActionTester(new SearchAction(db.getDbClient(), resourceTypes, i18n, userSession)); + ws = new WsActionTester(new SearchAction(db.getDbClient(), resourceTypes, i18n, userSession, languages)); } @@ -88,24 +90,21 @@ public class SearchActionTest { ComponentDto project = componentDb.insertComponent( newProjectDto("project-uuid") .setName("Project Name") - .setKey("project-key") - ); + .setKey("project-key")); ComponentDto module = componentDb.insertComponent( newModuleDto("module-uuid", project) .setName("Module Name") - .setKey("module-key") - ); + .setKey("module-key")); componentDb.insertComponent( newDirectory(module, "path/to/directoy") .setUuid("directory-uuid") .setKey("directory-key") - .setName("Directory Name") - ); + .setName("Directory Name")); componentDb.insertComponent( newFileDto(module, "file-uuid") .setKey("file-key") - .setName("File Name") - ); + .setLanguage("java") + .setName("File Name")); db.commit(); String response = newRequest(Qualifiers.PROJECT, Qualifiers.MODULE, Qualifiers.DIRECTORY, Qualifiers.FILE) @@ -152,6 +151,21 @@ public class SearchActionTest { } @Test + public void search_with_language() throws IOException { + componentDb.insertComponent(newProjectDto().setKey("java-project").setLanguage("java")); + componentDb.insertComponent(newProjectDto().setKey("cpp-project").setLanguage("cpp")); + db.commit(); + + InputStream responseStream = newRequest(Qualifiers.PROJECT) + .setParam(PARAM_LANGUAGE, "java") + .execute().getInputStream(); + SearchWsResponse response = SearchWsResponse.parseFrom(responseStream); + + assertThat(response.getComponentsCount()).isEqualTo(1); + assertThat(response.getComponentsList().get(0).getKey()).isEqualTo("java-project"); + } + + @Test public void fail_if_unknown_qualifier_provided() { expectedException.expect(BadRequestException.class); expectedException.expectMessage("The 'qualifier' parameter must be one of [BRC, DIR, FIL, TRK]. 'Unknown-Qualifier' was passed."); @@ -181,11 +195,22 @@ public class SearchActionTest { .setParam(PARAM_QUALIFIERS, Joiner.on(",").join(qualifiers)); } - private static List<ResourceType> resourceTypes() { - return asList( - ResourceType.builder(Qualifiers.PROJECT).build(), - ResourceType.builder(Qualifiers.MODULE).build(), - ResourceType.builder(Qualifiers.DIRECTORY).build(), - ResourceType.builder(Qualifiers.FILE).build()); + private static Language[] javaLanguage() { + return new Language[] {new Language() { + @Override + public String getKey() { + return "java"; + } + + @Override + public String getName() { + return "Java"; + } + + @Override + public String[] getFileSuffixes() { + return new String[0]; + } + }}; } } diff --git a/sonar-db/src/main/java/org/sonar/db/component/ComponentQuery.java b/sonar-db/src/main/java/org/sonar/db/component/ComponentQuery.java index 57d4536f968..142d98ce781 100644 --- a/sonar-db/src/main/java/org/sonar/db/component/ComponentQuery.java +++ b/sonar-db/src/main/java/org/sonar/db/component/ComponentQuery.java @@ -30,8 +30,10 @@ import static org.sonar.db.WildcardPosition.AFTER; public class ComponentQuery { private final String nameOrKeyQuery; private final String[] qualifiers; + private final String language; - public ComponentQuery(@Nullable String nameOrKeyQuery, String... qualifiers) { + public ComponentQuery(@Nullable String nameOrKeyQuery, String language, String... qualifiers) { + this.language = language; checkArgument(qualifiers.length > 0, "At least one qualifier must be provided"); this.nameOrKeyQuery = nameOrKeyQuery; @@ -56,4 +58,9 @@ public class ComponentQuery { public String getNameOrKeyQueryToSqlForProjectKey() { return buildLikeValue(nameOrKeyQuery, AFTER); } + + @CheckForNull + public String getLanguage() { + return language; + } } diff --git a/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml b/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml index f88928f83ca..0618022f2f8 100644 --- a/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml +++ b/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml @@ -283,6 +283,9 @@ <foreach collection="query.qualifiers" item="qualifier" open="(" close=")" separator=","> #{qualifier} </foreach> + <if test="query.language!=null"> + AND p.language = #{query.language} + </if> <if test="query.nameOrKeyQuery!=null"> AND (exists ( select 1 diff --git a/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java b/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java index 5cf3d42c5f7..3c3491ca31e 100644 --- a/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java @@ -683,7 +683,7 @@ public class ComponentDaoTest { db.commit(); componentDb.indexProjects(); - ComponentQuery query = new ComponentQuery("oJect", Qualifiers.PROJECT); + ComponentQuery query = new ComponentQuery("oJect", null, Qualifiers.PROJECT); List<ComponentDto> result = underTest.selectByQuery(dbSession, query, 1, 3); assertThat(result).hasSize(3); @@ -697,7 +697,7 @@ public class ComponentDaoTest { db.commit(); componentDb.indexProjects(); - ComponentQuery query = new ComponentQuery("-\\_%/-", Qualifiers.PROJECT); + ComponentQuery query = new ComponentQuery("-\\_%/-", null, Qualifiers.PROJECT); List<ComponentDto> result = underTest.selectByQuery(dbSession, query, 0, 10); assertThat(result).hasSize(1); @@ -711,7 +711,7 @@ public class ComponentDaoTest { db.commit(); componentDb.indexProjects(); - ComponentQuery query = new ComponentQuery("project-_%-", Qualifiers.PROJECT); + ComponentQuery query = new ComponentQuery("project-_%-", null, Qualifiers.PROJECT); List<ComponentDto> result = underTest.selectByQuery(dbSession, query, 0, 10); assertThat(result).hasSize(1); @@ -719,6 +719,19 @@ public class ComponentDaoTest { } @Test + public void select_by_query_filter_on_language() { + componentDb.insertComponent(newProjectDto().setKey("java-project-key").setLanguage("java")); + componentDb.insertComponent(newProjectDto().setKey("cpp-project-key").setLanguage("cpp")); + db.commit(); + + ComponentQuery query = new ComponentQuery(null, "java", Qualifiers.PROJECT); + List<ComponentDto> result = underTest.selectByQuery(dbSession, query, 0, 10); + + assertThat(result).hasSize(1); + assertThat(result.get(0).key()).isEqualTo("java-project-key"); + } + + @Test public void select_direct_children_of_a_project() { ComponentDto project = newProjectDto().setKey("project-key").setUuid("project-uuid"); SnapshotDto projectSnapshot = componentDb.insertProjectAndSnapshot(project); diff --git a/sonar-db/src/test/java/org/sonar/db/component/ComponentQueryTest.java b/sonar-db/src/test/java/org/sonar/db/component/ComponentQueryTest.java index 7ba69c6f7b9..94dbecd7e22 100644 --- a/sonar-db/src/test/java/org/sonar/db/component/ComponentQueryTest.java +++ b/sonar-db/src/test/java/org/sonar/db/component/ComponentQueryTest.java @@ -35,6 +35,6 @@ public class ComponentQueryTest { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("At least one qualifier must be provided"); - underTest = new ComponentQuery(null); + underTest = new ComponentQuery(null, "java"); } } diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsWsParameters.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsWsParameters.java index 9467eb8adc9..b9739c4480e 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsWsParameters.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsWsParameters.java @@ -30,6 +30,7 @@ public class ComponentsWsParameters { // parameters public static final String PARAM_QUALIFIERS = "qualifiers"; + public static final String PARAM_LANGUAGE = "language"; public static final String PARAM_BASE_COMPONENT_ID = "baseComponentId"; public static final String PARAM_BASE_COMPONENT_KEY = "baseComponentKey"; public static final String PARAM_STRATEGY = "strategy"; diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchWsRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchWsRequest.java index f537c1d22ac..0d381aedb40 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchWsRequest.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchWsRequest.java @@ -31,6 +31,7 @@ public class SearchWsRequest { private Integer page; private Integer pageSize; private String query; + private String language; public List<String> getQualifiers() { return qualifiers; @@ -70,4 +71,14 @@ public class SearchWsRequest { this.query = query; return this; } + + @CheckForNull + public String getLanguage() { + return language; + } + + public SearchWsRequest setLanguage(@Nullable String language) { + this.language = language; + return this; + } } diff --git a/sonar-ws/src/main/protobuf/ws-components.proto b/sonar-ws/src/main/protobuf/ws-components.proto index aad40d8cab2..03ded8c9bb7 100644 --- a/sonar-ws/src/main/protobuf/ws-components.proto +++ b/sonar-ws/src/main/protobuf/ws-components.proto @@ -47,4 +47,5 @@ message Component { optional string description = 5; optional string qualifier = 6; optional string path = 7; + optional string language = 8; } |