]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-17150 fix SSF-39
authorBenjamin Campomenosi <109955405+benjamin-campomenosi-sonarsource@users.noreply.github.com>
Thu, 11 Aug 2022 07:12:25 +0000 (09:12 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 11 Aug 2022 20:03:47 +0000 (20:03 +0000)
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleRepositoryDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleRepositoryMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleRepositoryMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleRepositoryDaoTest.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RepositoriesAction.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/RepositoriesActionTest.java

index e08d821f929b23466e77591ad7f2a134b1902870..2c6136a94ac7f76930e4e46c03dccad518ee1684 100644 (file)
@@ -21,16 +21,21 @@ package org.sonar.db.rule;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Locale;
 import java.util.Set;
+import javax.annotation.Nullable;
 import org.sonar.api.utils.System2;
 import org.sonar.db.Dao;
 import org.sonar.db.DatabaseUtils;
 import org.sonar.db.DbSession;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static org.apache.commons.lang.StringUtils.isBlank;
 
 public class RuleRepositoryDao implements Dao {
 
+  private static final String PERCENT_SIGN = "%";
+
   private final System2 system2;
 
   public RuleRepositoryDao(System2 system2) {
@@ -49,12 +54,9 @@ public class RuleRepositoryDao implements Dao {
     return dbSession.getMapper(RuleRepositoryMapper.class).selectAllKeys();
   }
 
-  /**
-   * @return a non-null list ordered by key (as implemented by database, order may
-   * depend on case sensitivity)
-   */
-  public List<RuleRepositoryDto> selectByLanguage(DbSession dbSession, String language) {
-    return dbSession.getMapper(RuleRepositoryMapper.class).selectByLanguage(language);
+  public List<RuleRepositoryDto> selectByQueryAndLanguage(DbSession dbSession, @Nullable String query, @Nullable String language){
+    String queryUpgraded = toLowerCaseAndSurroundWithPercentSigns(query);
+    return dbSession.getMapper(RuleRepositoryMapper.class).selectByQueryAndLanguage(queryUpgraded,language);
   }
 
   public void insert(DbSession dbSession, Collection<RuleRepositoryDto> dtos) {
@@ -76,4 +78,9 @@ public class RuleRepositoryDao implements Dao {
     checkArgument(keys.size() < DatabaseUtils.PARTITION_SIZE_FOR_ORACLE, "too many rule repositories: %s", keys.size());
     dbSession.getMapper(RuleRepositoryMapper.class).deleteIfKeyNotIn(keys);
   }
+
+  private static String toLowerCaseAndSurroundWithPercentSigns(@Nullable String query) {
+    return isBlank(query) ? PERCENT_SIGN : (PERCENT_SIGN + query.toLowerCase(Locale.ENGLISH) + PERCENT_SIGN);
+  }
+
 }
index 2f0aeb989b1155abc1421c45bb33fa8c09277b87..6a2c9d2c119c75464ed055e0d5fd3ccebbd43c58 100644 (file)
@@ -23,6 +23,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 import org.apache.ibatis.annotations.Param;
 
 public interface RuleRepositoryMapper {
@@ -31,7 +32,7 @@ public interface RuleRepositoryMapper {
 
   Set<String> selectAllKeys();
 
-  List<RuleRepositoryDto> selectByLanguage(@Param("language") String language);
+  List<RuleRepositoryDto> selectByQueryAndLanguage(@Param("query") String query,@Param("language") @Nullable String language);
 
   @CheckForNull
   RuleRepositoryDto selectByKey(@Param("key") String key);
index 962dd8a1a1a64fbeba38c79bedfd5af13e801c20..da15614c902519eace0dc5aa9d7ebd6cb6817ae9 100644 (file)
     from rule_repositories
   </select>
 
-  <select id="selectByLanguage" parameterType="String" resultType="org.sonar.db.rule.RuleRepositoryDto">
+  <select id="selectByQueryAndLanguage" parameterType="String" resultType="org.sonar.db.rule.RuleRepositoryDto">
     select <include refid="sqlColumns"/>
     from rule_repositories
-    where language = #{language}
+    where
+    ( lower(kee) like #{query}
+    or lower(name) like #{query} )
+    <if test="language != null and language != ''">
+      and language = #{language}
+    </if>
     order by kee
   </select>
 
index b75e26632cce10c0f1f30dfe428cc5770a12f2e7..66b76b8d32d42766622eacdf0d5a43da2c8fefbb 100644 (file)
@@ -123,18 +123,34 @@ public class RuleRepositoryDaoTest {
   }
 
   @Test
-  public void selectByLanguage() {
+  public void selectByQueryAndLanguage_shouldMatchOnlyOnKeeOrName(){
     DbSession dbSession = dbTester.getSession();
-    RuleRepositoryDto dto1 = new RuleRepositoryDto("findbugs", "java", "Findbugs");
-    RuleRepositoryDto dto2 = new RuleRepositoryDto("java", "java", "Java");
+    RuleRepositoryDto dto1 = new RuleRepositoryDto("a_findbugs", "java", "Findbugs");
+    RuleRepositoryDto dto2 = new RuleRepositoryDto("jdk", "java", "Java");
     RuleRepositoryDto dto3 = new RuleRepositoryDto("cobol-lint", "cobol", "Cobol Lint");
-    underTest.insert(dbSession, asList(dto1, dto2, dto3));
+    underTest.insert(dbSession, asList(dto1,dto2,dto3));
 
-    assertThat(underTest.selectByLanguage(dbSession, "java")).extracting(RuleRepositoryDto::getKey)
-      // ordered by key
-      .containsExactly("findbugs", "java");
+    List<RuleRepositoryDto> ruleRepositoryDtos = underTest.selectByQueryAndLanguage(dbSession, "%a%",null);
+
+    assertThat(ruleRepositoryDtos).extracting(RuleRepositoryDto::getName)
+      .containsExactlyInAnyOrder("Java","Findbugs");
   }
 
+  @Test
+  public void selectByQueryAndLanguage_whenSeveralRepoMatchingForDifferentLanguages_matchOnlyTheRepoOfTheChosenLanguage(){
+    DbSession dbSession = dbTester.getSession();
+    RuleRepositoryDto dto1 = new RuleRepositoryDto("findbugs", "java", "Findbugsa");
+    RuleRepositoryDto dto2 = new RuleRepositoryDto("java", "java", "Java");
+    RuleRepositoryDto dto3 = new RuleRepositoryDto("cobol-bug", "cobol", "Cobol Lint");
+    underTest.insert(dbSession, asList(dto1,dto2,dto3));
+
+    List<RuleRepositoryDto> ruleRepositoryDtos = underTest.selectByQueryAndLanguage(dbSession, "%bug%", "java");
+
+    assertThat(ruleRepositoryDtos).extracting(RuleRepositoryDto::getKey)
+      .containsExactly("findbugs");
+  }
+
+
   @Test
   public void selectAllKeys() {
     DbSession dbSession = dbTester.getSession();
@@ -147,14 +163,33 @@ public class RuleRepositoryDaoTest {
   }
 
   @Test
-  public void selectByLanguage_returns_empty_list_if_no_results() {
+  public void selectByQueryAndLanguage_returnsEmptyList_when_thereIsNoResults() {
     DbSession dbSession = dbTester.getSession();
     RuleRepositoryDto dto1 = new RuleRepositoryDto("findbugs", "java", "Findbugs");
     underTest.insert(dbSession, asList(dto1));
 
-    assertThat(underTest.selectByLanguage(dbSession, "missing")).isEmpty();
+    assertThat(underTest.selectByQueryAndLanguage(dbSession, "missing", null)).isEmpty();
   }
 
+  @Test
+  public void selectByQueryAndLanguage_shouldBeCaseInsensitive(){
+    DbSession dbSession = dbTester.getSession();
+    RuleRepositoryDto dto1 = new RuleRepositoryDto("FINDBUGS", "java", "repoFB");
+    RuleRepositoryDto dto2 = new RuleRepositoryDto("cobol-lint", "cobol", "Cobol Lint");
+    RuleRepositoryDto dto3 = new RuleRepositoryDto("openjdk", "java", "JaVa");
+    underTest.insert(dbSession, asList(dto1,dto2,dto3));
+
+    assertThat(underTest.selectByQueryAndLanguage(dbSession,"bug", null))
+      .extracting(RuleRepositoryDto::getKey).contains("FINDBUGS");
+    assertThat(underTest.selectByQueryAndLanguage(dbSession,"COBOL", null))
+      .extracting(RuleRepositoryDto::getKey).contains("cobol-lint");
+    assertThat(underTest.selectByQueryAndLanguage(dbSession,"jAvA", null))
+      .extracting(RuleRepositoryDto::getKey).contains("openjdk");
+
+  }
+
+
+
   private long selectCreatedAtByKey(DbSession dbSession, String key) {
     return (long) dbTester.selectFirst(dbSession, "select created_at as \"created_at\" from rule_repositories where kee='" + key + "'")
       .get("created_at");
index 77df6a5bacf4cc021c9ba32552f7185a996eba19..9318866b87e47118a6973a1b2f416f0704416571 100644 (file)
@@ -21,7 +21,6 @@ package org.sonar.server.rule.ws;
 
 import com.google.common.io.Resources;
 import java.util.Collection;
-import java.util.regex.Pattern;
 import javax.annotation.Nullable;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
@@ -29,12 +28,10 @@ import org.sonar.api.server.ws.WebService;
 import org.sonar.api.server.ws.WebService.NewAction;
 import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.core.util.stream.MoreCollectors;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.rule.RuleRepositoryDto;
 
-import static org.apache.commons.lang.StringUtils.isEmpty;
 
 /**
  * @since 5.1
@@ -42,7 +39,6 @@ import static org.apache.commons.lang.StringUtils.isEmpty;
 public class RepositoriesAction implements RulesWsAction {
 
   private static final String LANGUAGE = "language";
-  private static final String MATCH_ALL = ".*";
 
   private final DbClient dbClient;
 
@@ -86,19 +82,12 @@ public class RepositoriesAction implements RulesWsAction {
   }
 
   private Collection<RuleRepositoryDto> listMatchingRepositories(@Nullable String query, @Nullable String languageKey) {
-    Pattern pattern = Pattern.compile(query == null ? MATCH_ALL : MATCH_ALL + Pattern.quote(query) + MATCH_ALL, Pattern.CASE_INSENSITIVE);
-
-    return selectFromDb(languageKey).stream()
-      .filter(r -> pattern.matcher(r.getKey()).matches() || pattern.matcher(r.getName()).matches())
-      .collect(MoreCollectors.toList());
+    return selectFromDb(languageKey,  query);
   }
 
-  private Collection<RuleRepositoryDto> selectFromDb(@Nullable String language) {
+  private Collection<RuleRepositoryDto> selectFromDb(@Nullable String language, @Nullable  String query) {
     try (DbSession dbSession = dbClient.openSession(false)) {
-      if (isEmpty(language)) {
-        return dbClient.ruleRepositoryDao().selectAll(dbSession);
-      }
-      return dbClient.ruleRepositoryDao().selectByLanguage(dbSession, language);
+      return dbClient.ruleRepositoryDao().selectByQueryAndLanguage(dbSession, query, language);
     }
   }
 }
index 5ca37024fd4d82ecaea857ec2af3feebff89052f..5c55915196e318af74e3bce4c73911f3255c56ac 100644 (file)
@@ -65,6 +65,19 @@ public class RepositoriesActionTest {
     newRequest().setParam("q", "sonar").execute().assertJson(this.getClass(), "repositories_sonar.json");
   }
 
+  @Test
+  public void filter_repository_by_query(){
+    newRequest().setParam("q", "xo").execute().assertJson(this.getClass(),"repositories_xoo.json");
+    newRequest().setParam("q","w").execute().assertJson(this.getClass(),"repositories_common.json");
+  }
+
+
+  @Test
+  public void filter_repository_by_query_and_language(){
+    newRequest().setParam("q","ava").setParam("language","ws").execute().assertJson(this.getClass(),"repositories_java.json");
+    newRequest().setParam("q","w").setParam("language","ws").execute().assertJson(this.getClass(),"repositories_common.json");
+  }
+
   @Test
   public void do_not_consider_query_as_regexp_when_filtering_repositories_by_name() {
     // invalid regexp : do not fail. Query is not a regexp.