aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ws/LanguageParamUtils.java (renamed from server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/LanguageParamUtils.java)8
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java25
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ws/ActivityAction.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java1
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ExportAction.java1
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ProjectAssociationActions.java1
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileIdentificationParamUtils.java1
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java1
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SetDefaultAction.java1
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/component/ws/search-components-example.json3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java9
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java71
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ComponentQuery.java9
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml3
-rw-r--r--sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java19
-rw-r--r--sonar-db/src/test/java/org/sonar/db/component/ComponentQueryTest.java2
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsWsParameters.java1
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchWsRequest.java11
-rw-r--r--sonar-ws/src/main/protobuf/ws-components.proto1
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;
}