*/
package org.sonar.server.platform;
+import org.sonar.server.qualityprofile.QProfileRuleLookup;
+
import org.apache.commons.configuration.BaseConfiguration;
import org.slf4j.LoggerFactory;
import org.sonar.api.config.EmailSettings;
servicesContainer.addSingleton(ListingWs.class);
// quality profiles
- servicesContainer.addSingleton(ProfileRules.class);
+ servicesContainer.addSingleton(QProfileRuleLookup.class);
servicesContainer.addSingleton(QProfiles.class);
servicesContainer.addSingleton(QProfileLookup.class);
servicesContainer.addSingleton(QProfileOperations.class);
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.server.qualityprofile;
+
+import org.sonar.server.rule.ActiveRuleDocument;
+import org.sonar.server.rule.ProfileRuleQuery;
+import org.sonar.server.rule.RuleDocument;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Maps;
+import org.apache.commons.lang.StringUtils;
+import org.elasticsearch.action.get.GetResponse;
+import org.elasticsearch.action.search.SearchRequestBuilder;
+import org.elasticsearch.common.collect.Lists;
+import org.elasticsearch.index.query.BoolFilterBuilder;
+import org.elasticsearch.index.query.FilterBuilder;
+import org.elasticsearch.index.query.MatchQueryBuilder.Operator;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.search.SearchHit;
+import org.elasticsearch.search.SearchHits;
+import org.elasticsearch.search.sort.SortOrder;
+import org.sonar.api.ServerExtension;
+import org.sonar.api.rules.Rule;
+import org.sonar.server.es.ESIndex;
+
+import javax.annotation.CheckForNull;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.elasticsearch.index.query.FilterBuilders.*;
+import static org.elasticsearch.index.query.QueryBuilders.multiMatchQuery;
+import static org.sonar.server.rule.RuleRegistry.INDEX_RULES;
+import static org.sonar.server.rule.RuleRegistry.TYPE_ACTIVE_RULE;
+import static org.sonar.server.rule.RuleRegistry.TYPE_RULE;
+
+public class QProfileRuleLookup implements ServerExtension {
+
+ private static final int PAGE_SIZE = 100;
+
+ private static final String FIELD_PARENT = "_parent";
+ private static final String FIELD_SOURCE = "_source";
+
+ private final ESIndex index;
+
+ public QProfileRuleLookup(ESIndex index) {
+ this.index = index;
+ }
+
+ @CheckForNull
+ public QProfileRule findByActiveRuleId(int activeRuleId) {
+ GetResponse activeRuleResponse = index.client().prepareGet(INDEX_RULES, TYPE_ACTIVE_RULE, Integer.toString(activeRuleId))
+ .setFields(FIELD_SOURCE, FIELD_PARENT)
+ .execute().actionGet();
+ Map<String, Object> activeRuleSource = activeRuleResponse.getSourceAsMap();
+ if (activeRuleSource != null) {
+ Map<String, Object> ruleSource = index.client().prepareGet(INDEX_RULES, TYPE_RULE, (String) activeRuleResponse.getField(FIELD_PARENT).getValue())
+ .execute().actionGet().getSourceAsMap();
+ if (ruleSource != null) {
+ return new QProfileRule(ruleSource, activeRuleSource);
+ }
+ }
+ return null;
+ }
+
+ @CheckForNull
+ public QProfileRule findByProfileIdAndRuleId(int profileId, int ruleId) {
+ Map<String, Object> ruleSource = index.client().prepareGet(INDEX_RULES, TYPE_RULE, Integer.toString(ruleId))
+ .execute().actionGet().getSourceAsMap();
+ if (ruleSource != null) {
+ SearchHits activeRuleHits = searchActiveRules(ProfileRuleQuery.create(profileId), newArrayList(ruleId), FIELD_SOURCE, FIELD_PARENT);
+ long resultSize = activeRuleHits.totalHits();
+ if (resultSize > 0) {
+ if (resultSize == 1) {
+ return new QProfileRule(ruleSource, activeRuleHits.getAt(0).sourceAsMap());
+ } else {
+ throw new IllegalStateException("There is more than one result.");
+ }
+ }
+ }
+ return null;
+ }
+
+ @CheckForNull
+ public QProfileRule findByRuleId(int ruleId) {
+ Map<String, Object> ruleSource = index.client().prepareGet(INDEX_RULES, TYPE_RULE, Integer.toString(ruleId))
+ .execute().actionGet().getSourceAsMap();
+ if (ruleSource != null) {
+ return new QProfileRule(ruleSource);
+ }
+ return null;
+ }
+
+ public QProfileRuleResult search(ProfileRuleQuery query, Paging paging) {
+ SearchHits ruleHits = searchRules(query, paging, ruleFilterForActiveRuleSearch(query).must(hasChildFilter(TYPE_ACTIVE_RULE, activeRuleFilter(query))));
+ List<Integer> ruleIds = Lists.newArrayList();
+ for (SearchHit ruleHit : ruleHits) {
+ ruleIds.add(Integer.valueOf(ruleHit.id()));
+ }
+
+ List<QProfileRule> result = Lists.newArrayList();
+ if (!ruleIds.isEmpty()) {
+ SearchHits activeRuleHits = searchActiveRules(query, ruleIds, FIELD_SOURCE, FIELD_PARENT);
+
+ Map<String, SearchHit> activeRuleByParent = Maps.newHashMap();
+ for (SearchHit activeRuleHit : activeRuleHits) {
+ activeRuleByParent.put((String) activeRuleHit.field(FIELD_PARENT).getValue(), activeRuleHit);
+ }
+
+ for (SearchHit ruleHit : ruleHits) {
+ result.add(new QProfileRule(ruleHit.sourceAsMap(), activeRuleByParent.get(ruleHit.id()).sourceAsMap()));
+ }
+ }
+ return new QProfileRuleResult(result, PagingResult.create(paging.pageSize(), paging.pageIndex(), ruleHits.getTotalHits()));
+ }
+
+ public List<Integer> searchProfileRuleIds(final ProfileRuleQuery query) {
+ return searchProfileRuleIds(query, PAGE_SIZE);
+ }
+
+ @VisibleForTesting
+ List<Integer> searchProfileRuleIds(final ProfileRuleQuery query, int pageSize) {
+ final List<Integer> activeRuleIds = newArrayList();
+ new Search(pageSize) {
+ @Override
+ public int search(int currentPage) {
+ Paging paging = Paging.create(pageSize, currentPage);
+ SearchHits ruleHits = searchRules(query, paging, ruleFilterForActiveRuleSearch(query).must(hasChildFilter(TYPE_ACTIVE_RULE, activeRuleFilter(query))));
+ List<Integer> ruleIds = Lists.newArrayList();
+ for (SearchHit ruleHit : ruleHits) {
+ ruleIds.add(Integer.valueOf(ruleHit.id()));
+ }
+
+ if (!ruleIds.isEmpty()) {
+ SearchHits activeRuleHits = searchActiveRules(query, ruleIds, ActiveRuleDocument.FIELD_ID);
+ for (SearchHit activeRuleHit : activeRuleHits) {
+ activeRuleIds.add((Integer) activeRuleHit.field(ActiveRuleDocument.FIELD_ID).getValue());
+ }
+ }
+ return ruleHits.getHits().length;
+ }
+ }.execute();
+ return activeRuleIds;
+ }
+
+ public long countProfileRules(ProfileRuleQuery query) {
+ return index.executeCount(
+ index.client()
+ .prepareCount(INDEX_RULES)
+ .setTypes(TYPE_ACTIVE_RULE)
+ .setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(),
+ activeRuleFilter(query).must(hasParentFilter(TYPE_RULE, ruleFilterForActiveRuleSearch(query)))))
+ );
+ }
+
+ public QProfileRuleResult searchInactives(ProfileRuleQuery query, Paging paging) {
+ SearchHits hits = searchRules(query, paging, ruleFilterForInactiveRuleSearch(query), FIELD_SOURCE, FIELD_PARENT);
+ List<QProfileRule> result = Lists.newArrayList();
+ for (SearchHit hit : hits.getHits()) {
+ result.add(new QProfileRule(hit.sourceAsMap()));
+ }
+ return new QProfileRuleResult(result, PagingResult.create(paging.pageSize(), paging.pageIndex(), hits.getTotalHits()));
+ }
+
+ public List<Integer> searchInactiveProfileRuleIds(final ProfileRuleQuery query) {
+ final List<Integer> ruleIds = newArrayList();
+
+ new Search(PAGE_SIZE) {
+ @Override
+ public int search(int currentPage) {
+ Paging paging = Paging.create(pageSize, currentPage);
+ SearchHits hits = searchRules(query, paging, ruleFilterForInactiveRuleSearch(query), RuleDocument.FIELD_ID);
+ for (SearchHit hit : hits.getHits()) {
+ ruleIds.add((Integer) hit.field(RuleDocument.FIELD_ID).getValue());
+ }
+ return hits.getHits().length;
+ }
+ }.execute();
+
+ return ruleIds;
+ }
+
+ public long countInactiveProfileRules(ProfileRuleQuery query) {
+ return index.executeCount(index.client().prepareCount(INDEX_RULES).setTypes(TYPE_RULE)
+ .setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(),
+ ruleFilterForInactiveRuleSearch(query))));
+ }
+
+ private SearchHits searchRules(ProfileRuleQuery query, Paging paging, FilterBuilder filterBuilder, String... fields) {
+ SearchRequestBuilder builder = index.client().prepareSearch(INDEX_RULES).setTypes(TYPE_RULE)
+ .setPostFilter(filterBuilder)
+ .setSize(paging.pageSize())
+ .setFrom(paging.offset());
+ if (fields.length > 0) {
+ builder.addFields(fields);
+ }
+ addOrder(query, builder);
+ return index.executeRequest(builder);
+ }
+
+ private SearchHits searchActiveRules(ProfileRuleQuery query, List<Integer> ruleIds, String... fields) {
+ SearchRequestBuilder activeRuleBuilder = index.client().prepareSearch(INDEX_RULES).setTypes(TYPE_ACTIVE_RULE)
+ .setPostFilter(boolFilter()
+ .must(
+ termFilter(ActiveRuleDocument.FIELD_PROFILE_ID, query.profileId()),
+ hasParentFilter(TYPE_RULE, termsFilter(RuleDocument.FIELD_ID, ruleIds))
+ ))
+ .setSize(ruleIds.size());
+ if (fields.length > 0) {
+ activeRuleBuilder.addFields(fields);
+ }
+ return index.executeRequest(activeRuleBuilder);
+ }
+
+ private BoolFilterBuilder activeRuleFilter(ProfileRuleQuery query) {
+ BoolFilterBuilder filter = boolFilter().must(termFilter(ActiveRuleDocument.FIELD_PROFILE_ID, query.profileId()));
+ addMustTermOrTerms(filter, ActiveRuleDocument.FIELD_SEVERITY, query.severities());
+ String inheritance = query.inheritance();
+ if (inheritance != null) {
+ addMustTermOrTerms(filter, ActiveRuleDocument.FIELD_INHERITANCE, newArrayList(inheritance));
+ } else if (query.noInheritance()) {
+ filter.mustNot(getTermOrTerms(ActiveRuleDocument.FIELD_INHERITANCE, newArrayList(QProfileRule.INHERITED, QProfileRule.OVERRIDES)));
+ }
+ return filter;
+ }
+
+ private BoolFilterBuilder ruleFilterForActiveRuleSearch(ProfileRuleQuery query) {
+ BoolFilterBuilder result = boolFilter();
+
+ if (StringUtils.isNotBlank(query.language())) {
+ result.must(termFilter(RuleDocument.FIELD_LANGUAGE, query.language()));
+ }
+
+ addMustTermOrTerms(result, RuleDocument.FIELD_REPOSITORY_KEY, query.repositoryKeys());
+ if (query.statuses().isEmpty()) {
+ result.mustNot(termFilter(RuleDocument.FIELD_STATUS, Rule.STATUS_REMOVED));
+ } else {
+ addMustTermOrTerms(result, RuleDocument.FIELD_STATUS, query.statuses());
+ }
+
+ for (String tag: query.tags()) {
+ result.must(
+ queryFilter(
+ multiMatchQuery(tag, RuleDocument.FIELD_ADMIN_TAGS, RuleDocument.FIELD_SYSTEM_TAGS)));
+ }
+
+ if (StringUtils.isNotBlank(query.nameOrKey())) {
+ result.must(
+ queryFilter(
+ multiMatchQuery(query.nameOrKey(), RuleDocument.FIELD_NAME, RuleDocument.FIELD_KEY)
+ .operator(Operator.AND)));
+ }
+
+ return result;
+ }
+
+ private BoolFilterBuilder ruleFilterForInactiveRuleSearch(ProfileRuleQuery query) {
+ BoolFilterBuilder filter = ruleFilterForActiveRuleSearch(query)
+ .mustNot(hasChildFilter(TYPE_ACTIVE_RULE, termFilter(ActiveRuleDocument.FIELD_PROFILE_ID, query.profileId())));
+ addMustTermOrTerms(filter, RuleDocument.FIELD_SEVERITY, query.severities());
+
+ for (String tag: query.tags()) {
+ filter.must(
+ queryFilter(
+ multiMatchQuery(tag, RuleDocument.FIELD_ADMIN_TAGS, RuleDocument.FIELD_SYSTEM_TAGS)));
+ }
+
+ return filter;
+ }
+
+ private void addMustTermOrTerms(BoolFilterBuilder filter, String field, Collection<String> terms) {
+ FilterBuilder termOrTerms = getTermOrTerms(field, terms);
+ if (termOrTerms != null) {
+ filter.must(termOrTerms);
+ }
+ }
+
+ private FilterBuilder getTermOrTerms(String field, Collection<String> terms) {
+ if (terms.isEmpty()) {
+ return null;
+ } else {
+ if (terms.size() == 1) {
+ return termFilter(field, terms.iterator().next());
+ } else {
+ return termsFilter(field, terms.toArray());
+ }
+ }
+ }
+
+ private void addOrder(ProfileRuleQuery query, SearchRequestBuilder builder) {
+ SortOrder sortOrder = query.asc() ? SortOrder.ASC : SortOrder.DESC;
+ if (query.sort().equals(ProfileRuleQuery.SORT_BY_RULE_NAME)) {
+ builder.addSort(RuleDocument.FIELD_NAME + ".raw", sortOrder);
+ } else if (query.sort().equals(ProfileRuleQuery.SORT_BY_CREATION_DATE)) {
+ builder.addSort(RuleDocument.FIELD_CREATED_AT, sortOrder);
+ }
+ }
+
+ private abstract static class Search {
+
+ int pageSize = 100;
+
+ protected Search(int pageSize) {
+ this.pageSize = pageSize;
+ }
+
+ abstract int search(int currentPage);
+
+ void execute() {
+ int currentPage = 1;
+ boolean hasNextPage = true;
+ while (hasNextPage) {
+ int resultSize = search(currentPage);
+ if (resultSize < pageSize) {
+ hasNextPage = false;
+ } else {
+ currentPage++;
+ }
+ }
+ }
+ }
+
+ public static class QProfileRuleResult {
+
+ private final List<QProfileRule> rules;
+ private final PagingResult paging;
+
+ public QProfileRuleResult(List<QProfileRule> rules, PagingResult paging) {
+ this.rules = rules;
+ this.paging = paging;
+ }
+
+ public List<QProfileRule> rules() {
+ return rules;
+ }
+
+ public PagingResult paging() {
+ return paging;
+ }
+ }
+}
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.rule.ProfileRuleQuery;
-import org.sonar.server.rule.ProfileRules;
import org.sonar.server.user.UserSession;
import org.sonar.server.util.RubyUtils;
import org.sonar.server.util.Validation;
private final QProfileOperations operations;
private final QProfileActiveRuleOperations activeRuleOperations;
private final QProfileRuleOperations ruleOperations;
- private final ProfileRules rules;
+ private final QProfileRuleLookup rules;
public QProfiles(QualityProfileDao qualityProfileDao, ActiveRuleDao activeRuleDao, RuleDao ruleDao, ResourceDao resourceDao,
QProfileProjectOperations projectOperations, QProfileProjectLookup projectLookup, QProfileBackup backup, QProfilePluginExporter exporter,
QProfileLookup profileLookup, QProfileOperations operations, QProfileActiveRuleOperations activeRuleOperations, QProfileRuleOperations ruleOperations,
- ProfileRules rules) {
+ QProfileRuleLookup rules) {
this.qualityProfileDao = qualityProfileDao;
this.activeRuleDao = activeRuleDao;
this.ruleDao = ruleDao;
return rules.findByProfileIdAndRuleId(profileId, ruleId);
}
- public ProfileRules.QProfileRuleResult searchProfileRules(ProfileRuleQuery query, Paging paging) {
+ public QProfileRuleLookup.QProfileRuleResult searchProfileRules(ProfileRuleQuery query, Paging paging) {
return rules.search(query, paging);
}
return rules.countProfileRules(query);
}
- public ProfileRules.QProfileRuleResult searchInactiveProfileRules(ProfileRuleQuery query, Paging paging) {
+ public QProfileRuleLookup.QProfileRuleResult searchInactiveProfileRules(ProfileRuleQuery query, Paging paging) {
return rules.searchInactives(query, paging);
}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.server.rule;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Maps;
-import org.apache.commons.lang.StringUtils;
-import org.elasticsearch.action.get.GetResponse;
-import org.elasticsearch.action.search.SearchRequestBuilder;
-import org.elasticsearch.common.collect.Lists;
-import org.elasticsearch.index.query.BoolFilterBuilder;
-import org.elasticsearch.index.query.FilterBuilder;
-import org.elasticsearch.index.query.MatchQueryBuilder.Operator;
-import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.search.SearchHit;
-import org.elasticsearch.search.SearchHits;
-import org.elasticsearch.search.sort.SortOrder;
-import org.sonar.api.ServerExtension;
-import org.sonar.api.rules.Rule;
-import org.sonar.server.es.ESIndex;
-import org.sonar.server.qualityprofile.Paging;
-import org.sonar.server.qualityprofile.PagingResult;
-import org.sonar.server.qualityprofile.QProfileRule;
-
-import javax.annotation.CheckForNull;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.elasticsearch.index.query.FilterBuilders.*;
-import static org.elasticsearch.index.query.QueryBuilders.multiMatchQuery;
-import static org.sonar.server.rule.RuleRegistry.INDEX_RULES;
-import static org.sonar.server.rule.RuleRegistry.TYPE_ACTIVE_RULE;
-import static org.sonar.server.rule.RuleRegistry.TYPE_RULE;
-
-public class ProfileRules implements ServerExtension {
-
- private static final int PAGE_SIZE = 100;
-
- private static final String FIELD_PARENT = "_parent";
- private static final String FIELD_SOURCE = "_source";
-
- private final ESIndex index;
-
- public ProfileRules(ESIndex index) {
- this.index = index;
- }
-
- @CheckForNull
- public QProfileRule findByActiveRuleId(int activeRuleId) {
- GetResponse activeRuleResponse = index.client().prepareGet(INDEX_RULES, TYPE_ACTIVE_RULE, Integer.toString(activeRuleId))
- .setFields(FIELD_SOURCE, FIELD_PARENT)
- .execute().actionGet();
- Map<String, Object> activeRuleSource = activeRuleResponse.getSourceAsMap();
- if (activeRuleSource != null) {
- Map<String, Object> ruleSource = index.client().prepareGet(INDEX_RULES, TYPE_RULE, (String) activeRuleResponse.getField(FIELD_PARENT).getValue())
- .execute().actionGet().getSourceAsMap();
- if (ruleSource != null) {
- return new QProfileRule(ruleSource, activeRuleSource);
- }
- }
- return null;
- }
-
- @CheckForNull
- public QProfileRule findByProfileIdAndRuleId(int profileId, int ruleId) {
- Map<String, Object> ruleSource = index.client().prepareGet(INDEX_RULES, TYPE_RULE, Integer.toString(ruleId))
- .execute().actionGet().getSourceAsMap();
- if (ruleSource != null) {
- SearchHits activeRuleHits = searchActiveRules(ProfileRuleQuery.create(profileId), newArrayList(ruleId), FIELD_SOURCE, FIELD_PARENT);
- long resultSize = activeRuleHits.totalHits();
- if (resultSize > 0) {
- if (resultSize == 1) {
- return new QProfileRule(ruleSource, activeRuleHits.getAt(0).sourceAsMap());
- } else {
- throw new IllegalStateException("There is more than one result.");
- }
- }
- }
- return null;
- }
-
- @CheckForNull
- public QProfileRule findByRuleId(int ruleId) {
- Map<String, Object> ruleSource = index.client().prepareGet(INDEX_RULES, TYPE_RULE, Integer.toString(ruleId))
- .execute().actionGet().getSourceAsMap();
- if (ruleSource != null) {
- return new QProfileRule(ruleSource);
- }
- return null;
- }
-
- public QProfileRuleResult search(ProfileRuleQuery query, Paging paging) {
- SearchHits ruleHits = searchRules(query, paging, ruleFilterForActiveRuleSearch(query).must(hasChildFilter(TYPE_ACTIVE_RULE, activeRuleFilter(query))));
- List<Integer> ruleIds = Lists.newArrayList();
- for (SearchHit ruleHit : ruleHits) {
- ruleIds.add(Integer.valueOf(ruleHit.id()));
- }
-
- List<QProfileRule> result = Lists.newArrayList();
- if (!ruleIds.isEmpty()) {
- SearchHits activeRuleHits = searchActiveRules(query, ruleIds, FIELD_SOURCE, FIELD_PARENT);
-
- Map<String, SearchHit> activeRuleByParent = Maps.newHashMap();
- for (SearchHit activeRuleHit : activeRuleHits) {
- activeRuleByParent.put((String) activeRuleHit.field(FIELD_PARENT).getValue(), activeRuleHit);
- }
-
- for (SearchHit ruleHit : ruleHits) {
- result.add(new QProfileRule(ruleHit.sourceAsMap(), activeRuleByParent.get(ruleHit.id()).sourceAsMap()));
- }
- }
- return new QProfileRuleResult(result, PagingResult.create(paging.pageSize(), paging.pageIndex(), ruleHits.getTotalHits()));
- }
-
- public List<Integer> searchProfileRuleIds(final ProfileRuleQuery query) {
- return searchProfileRuleIds(query, PAGE_SIZE);
- }
-
- @VisibleForTesting
- List<Integer> searchProfileRuleIds(final ProfileRuleQuery query, int pageSize) {
- final List<Integer> activeRuleIds = newArrayList();
- new Search(pageSize) {
- @Override
- public int search(int currentPage) {
- Paging paging = Paging.create(pageSize, currentPage);
- SearchHits ruleHits = searchRules(query, paging, ruleFilterForActiveRuleSearch(query).must(hasChildFilter(TYPE_ACTIVE_RULE, activeRuleFilter(query))));
- List<Integer> ruleIds = Lists.newArrayList();
- for (SearchHit ruleHit : ruleHits) {
- ruleIds.add(Integer.valueOf(ruleHit.id()));
- }
-
- if (!ruleIds.isEmpty()) {
- SearchHits activeRuleHits = searchActiveRules(query, ruleIds, ActiveRuleDocument.FIELD_ID);
- for (SearchHit activeRuleHit : activeRuleHits) {
- activeRuleIds.add((Integer) activeRuleHit.field(ActiveRuleDocument.FIELD_ID).getValue());
- }
- }
- return ruleHits.getHits().length;
- }
- }.execute();
- return activeRuleIds;
- }
-
- public long countProfileRules(ProfileRuleQuery query) {
- return index.executeCount(
- index.client()
- .prepareCount(INDEX_RULES)
- .setTypes(TYPE_ACTIVE_RULE)
- .setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(),
- activeRuleFilter(query).must(hasParentFilter(TYPE_RULE, ruleFilterForActiveRuleSearch(query)))))
- );
- }
-
- public QProfileRuleResult searchInactives(ProfileRuleQuery query, Paging paging) {
- SearchHits hits = searchRules(query, paging, ruleFilterForInactiveRuleSearch(query), FIELD_SOURCE, FIELD_PARENT);
- List<QProfileRule> result = Lists.newArrayList();
- for (SearchHit hit : hits.getHits()) {
- result.add(new QProfileRule(hit.sourceAsMap()));
- }
- return new QProfileRuleResult(result, PagingResult.create(paging.pageSize(), paging.pageIndex(), hits.getTotalHits()));
- }
-
- public List<Integer> searchInactiveProfileRuleIds(final ProfileRuleQuery query) {
- final List<Integer> ruleIds = newArrayList();
-
- new Search(PAGE_SIZE) {
- @Override
- public int search(int currentPage) {
- Paging paging = Paging.create(pageSize, currentPage);
- SearchHits hits = searchRules(query, paging, ruleFilterForInactiveRuleSearch(query), RuleDocument.FIELD_ID);
- for (SearchHit hit : hits.getHits()) {
- ruleIds.add((Integer) hit.field(RuleDocument.FIELD_ID).getValue());
- }
- return hits.getHits().length;
- }
- }.execute();
-
- return ruleIds;
- }
-
- public long countInactiveProfileRules(ProfileRuleQuery query) {
- return index.executeCount(index.client().prepareCount(INDEX_RULES).setTypes(TYPE_RULE)
- .setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(),
- ruleFilterForInactiveRuleSearch(query))));
- }
-
- private SearchHits searchRules(ProfileRuleQuery query, Paging paging, FilterBuilder filterBuilder, String... fields) {
- SearchRequestBuilder builder = index.client().prepareSearch(INDEX_RULES).setTypes(TYPE_RULE)
- .setPostFilter(filterBuilder)
- .setSize(paging.pageSize())
- .setFrom(paging.offset());
- if (fields.length > 0) {
- builder.addFields(fields);
- }
- addOrder(query, builder);
- return index.executeRequest(builder);
- }
-
- private SearchHits searchActiveRules(ProfileRuleQuery query, List<Integer> ruleIds, String... fields) {
- SearchRequestBuilder activeRuleBuilder = index.client().prepareSearch(INDEX_RULES).setTypes(TYPE_ACTIVE_RULE)
- .setPostFilter(boolFilter()
- .must(
- termFilter(ActiveRuleDocument.FIELD_PROFILE_ID, query.profileId()),
- hasParentFilter(TYPE_RULE, termsFilter(RuleDocument.FIELD_ID, ruleIds))
- ))
- .setSize(ruleIds.size());
- if (fields.length > 0) {
- activeRuleBuilder.addFields(fields);
- }
- return index.executeRequest(activeRuleBuilder);
- }
-
- private BoolFilterBuilder activeRuleFilter(ProfileRuleQuery query) {
- BoolFilterBuilder filter = boolFilter().must(termFilter(ActiveRuleDocument.FIELD_PROFILE_ID, query.profileId()));
- addMustTermOrTerms(filter, ActiveRuleDocument.FIELD_SEVERITY, query.severities());
- String inheritance = query.inheritance();
- if (inheritance != null) {
- addMustTermOrTerms(filter, ActiveRuleDocument.FIELD_INHERITANCE, newArrayList(inheritance));
- } else if (query.noInheritance()) {
- filter.mustNot(getTermOrTerms(ActiveRuleDocument.FIELD_INHERITANCE, newArrayList(QProfileRule.INHERITED, QProfileRule.OVERRIDES)));
- }
- return filter;
- }
-
- private BoolFilterBuilder ruleFilterForActiveRuleSearch(ProfileRuleQuery query) {
- BoolFilterBuilder result = boolFilter();
-
- if (StringUtils.isNotBlank(query.language())) {
- result.must(termFilter(RuleDocument.FIELD_LANGUAGE, query.language()));
- }
-
- addMustTermOrTerms(result, RuleDocument.FIELD_REPOSITORY_KEY, query.repositoryKeys());
- if (query.statuses().isEmpty()) {
- result.mustNot(termFilter(RuleDocument.FIELD_STATUS, Rule.STATUS_REMOVED));
- } else {
- addMustTermOrTerms(result, RuleDocument.FIELD_STATUS, query.statuses());
- }
-
- for (String tag: query.tags()) {
- result.must(
- queryFilter(
- multiMatchQuery(tag, RuleDocument.FIELD_ADMIN_TAGS, RuleDocument.FIELD_SYSTEM_TAGS)));
- }
-
- if (StringUtils.isNotBlank(query.nameOrKey())) {
- result.must(
- queryFilter(
- multiMatchQuery(query.nameOrKey(), RuleDocument.FIELD_NAME, RuleDocument.FIELD_KEY)
- .operator(Operator.AND)));
- }
-
- return result;
- }
-
- private BoolFilterBuilder ruleFilterForInactiveRuleSearch(ProfileRuleQuery query) {
- BoolFilterBuilder filter = ruleFilterForActiveRuleSearch(query)
- .mustNot(hasChildFilter(TYPE_ACTIVE_RULE, termFilter(ActiveRuleDocument.FIELD_PROFILE_ID, query.profileId())));
- addMustTermOrTerms(filter, RuleDocument.FIELD_SEVERITY, query.severities());
-
- for (String tag: query.tags()) {
- filter.must(
- queryFilter(
- multiMatchQuery(tag, RuleDocument.FIELD_ADMIN_TAGS, RuleDocument.FIELD_SYSTEM_TAGS)));
- }
-
- return filter;
- }
-
- private void addMustTermOrTerms(BoolFilterBuilder filter, String field, Collection<String> terms) {
- FilterBuilder termOrTerms = getTermOrTerms(field, terms);
- if (termOrTerms != null) {
- filter.must(termOrTerms);
- }
- }
-
- private FilterBuilder getTermOrTerms(String field, Collection<String> terms) {
- if (terms.isEmpty()) {
- return null;
- } else {
- if (terms.size() == 1) {
- return termFilter(field, terms.iterator().next());
- } else {
- return termsFilter(field, terms.toArray());
- }
- }
- }
-
- private void addOrder(ProfileRuleQuery query, SearchRequestBuilder builder) {
- SortOrder sortOrder = query.asc() ? SortOrder.ASC : SortOrder.DESC;
- if (query.sort().equals(ProfileRuleQuery.SORT_BY_RULE_NAME)) {
- builder.addSort(RuleDocument.FIELD_NAME + ".raw", sortOrder);
- } else if (query.sort().equals(ProfileRuleQuery.SORT_BY_CREATION_DATE)) {
- builder.addSort(RuleDocument.FIELD_CREATED_AT, sortOrder);
- }
- }
-
- private abstract static class Search {
-
- int pageSize = 100;
-
- protected Search(int pageSize) {
- this.pageSize = pageSize;
- }
-
- abstract int search(int currentPage);
-
- void execute() {
- int currentPage = 1;
- boolean hasNextPage = true;
- while (hasNextPage) {
- int resultSize = search(currentPage);
- if (resultSize < pageSize) {
- hasNextPage = false;
- } else {
- currentPage++;
- }
- }
- }
- }
-
- public static class QProfileRuleResult {
-
- private final List<QProfileRule> rules;
- private final PagingResult paging;
-
- public QProfileRuleResult(List<QProfileRule> rules, PagingResult paging) {
- this.rules = rules;
- this.paging = paging;
- }
-
- public List<QProfileRule> rules() {
- return rules;
- }
-
- public PagingResult paging() {
- return paging;
- }
- }
-}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.server.qualityprofile;
+
+import org.sonar.server.rule.ProfileRuleQuery;
+import org.sonar.server.rule.RuleRegistry;
+
+import org.sonar.server.qualityprofile.QProfileRuleLookup;
+import com.github.tlrx.elasticsearch.test.EsSetup;
+import org.apache.commons.io.IOUtils;
+import org.elasticsearch.client.Requests;
+import org.elasticsearch.common.settings.ImmutableSettings;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+import org.sonar.api.rule.Severity;
+import org.sonar.core.profiling.Profiling;
+import org.sonar.server.es.ESIndex;
+import org.sonar.server.es.ESNode;
+import org.sonar.server.qualityprofile.Paging;
+import org.sonar.server.qualityprofile.QProfileRule;
+import org.sonar.test.TestUtils;
+
+import java.util.List;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class QProfileRuleLookupTest {
+
+ private QProfileRuleLookup profileRules;
+ private EsSetup esSetup;
+
+ @Before
+ public void setUp() throws Exception {
+ esSetup = new EsSetup(ImmutableSettings.builder()
+ .loadFromUrl(ESNode.class.getResource("config/elasticsearch.json"))
+ .build()
+ );
+ esSetup.execute(EsSetup.deleteAll());
+
+ ESNode searchNode = mock(ESNode.class);
+ when(searchNode.client()).thenReturn(esSetup.client());
+
+ Settings settings = new Settings();
+ settings.setProperty("sonar.log.profilingLevel", "FULL");
+ ESIndex index = new ESIndex(searchNode, new Profiling(settings));
+ index.start();
+ RuleRegistry registry = new RuleRegistry(index, null, null, null);
+ registry.start();
+ profileRules = new QProfileRuleLookup(index);
+
+ esSetup.client().prepareBulk()
+ // On profile 1
+ .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("shared/rule25.json")))
+ .add(Requests.indexRequest().index("rules").type("active_rule").parent("25").source(testFileAsString("shared/active_rule25.json")))
+ // On profile 1 and 2
+ .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("shared/rule759.json")))
+ .add(Requests.indexRequest().index("rules").type("active_rule").parent("759").source(testFileAsString("shared/active_rule391.json")))
+ .add(Requests.indexRequest().index("rules").type("active_rule").parent("759").source(testFileAsString("shared/active_rule523.json")))
+ // On profile 1
+ .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("shared/rule1482.json")))
+ .add(Requests.indexRequest().index("rules").type("active_rule").parent("1482").source(testFileAsString("shared/active_rule2702.json")))
+ // Rules on no profile
+ .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("shared/rule944.json")))
+ .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("shared/rule719.json")))
+ // Removed rule
+ .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("shared/rule860.json")))
+ .setRefresh(true).execute().actionGet();
+ }
+
+ @After
+ public void tearDown() {
+ esSetup.terminate();
+ }
+
+ @Test
+ public void find_by_rule_id() {
+ assertThat(profileRules.findByRuleId(25)).isNotNull();
+ assertThat(profileRules.findByRuleId(9999)).isNull();
+ }
+
+ @Test
+ public void find_by_active_rule_id() {
+ assertThat(profileRules.findByActiveRuleId(391)).isNotNull();
+ assertThat(profileRules.findByActiveRuleId(9999)).isNull();
+ }
+
+ @Test
+ public void find_by_active_rule_id_with_inheritance() throws Exception {
+ esSetup.client().prepareBulk()
+ // Parent active rule
+ .add(Requests.indexRequest().index("rules").type("active_rule").parent("25").source(testFileAsString("find_active_rules_with_inheritance/active_rule25.json")))
+ // Child active rule
+ .add(Requests.indexRequest().index("rules").type("active_rule").parent("759").source(testFileAsString("find_active_rules_with_inheritance/active_rule391.json")))
+ .setRefresh(true)
+ .execute().actionGet();
+
+ QProfileRule child = profileRules.findByActiveRuleId(391);
+ assertThat(child.inheritance()).isEqualTo("INHERITED");
+ assertThat(child.activeRuleParentId()).isEqualTo(25);
+ }
+
+ @Test
+ public void find_by_profile_id_and_rule_id() {
+ // Rules on profiles
+ QProfileRule rule = profileRules.findByProfileIdAndRuleId(1, 759);
+ assertThat(rule).isNotNull();
+ assertThat(rule.key()).isEqualTo("UnusedNullCheckInEquals");
+ assertThat(rule.severity()).isEqualTo(Severity.MAJOR);
+
+ // Rules on no profiles
+ assertThat(profileRules.findByProfileIdAndRuleId(1, 944)).isNull();
+
+ // Not existing rule
+ assertThat(profileRules.findByProfileIdAndRuleId(1, 99999)).isNull();
+ }
+
+ @Test
+ public void find_profile_rules() {
+ Paging paging = Paging.create(10, 1);
+
+ // All rules for profile 1
+ List<QProfileRule> rules1 = profileRules.search(ProfileRuleQuery.create(1), paging).rules();
+ assertThat(rules1).hasSize(3);
+ assertThat(rules1.get(0).key()).isEqualTo("ArchitecturalConstraint");
+ assertThat(rules1.get(0).severity()).isEqualTo(Severity.CRITICAL);
+
+ // All rules for profile 2
+ List<QProfileRule> rules2 = profileRules.search(ProfileRuleQuery.create(2), paging).rules();
+ assertThat(rules2).hasSize(1);
+ assertThat(rules2.get(0).id()).isEqualTo(759);
+ assertThat(rules2.get(0).activeRuleId()).isEqualTo(523);
+
+ // Match on key
+ assertThat(profileRules.search(ProfileRuleQuery.create(1).setNameOrKey("DM_CONVERT_CASE"), paging).rules()).hasSize(1);
+
+ // Match on name
+ assertThat(profileRules.search(ProfileRuleQuery.create(1).setNameOrKey("Unused Check"), paging).rules()).hasSize(1);
+
+ // Match on repositoryKey
+ assertThat(profileRules.search(ProfileRuleQuery.create(1).addRepositoryKeys("findbugs"), paging).rules()).hasSize(1);
+
+ assertThat(profileRules.search(ProfileRuleQuery.create(1).addSeverities(Severity.CRITICAL), paging).rules()).hasSize(1);
+ // Active rule 25 is in MINOR (rule 25 is in INFO)
+ assertThat(profileRules.search(ProfileRuleQuery.create(1).addSeverities(Severity.INFO), paging).rules()).isEmpty();
+
+ // Match on key, rule has parameters
+ List<QProfileRule> rulesWParam = profileRules.search(ProfileRuleQuery.create(1).setNameOrKey("ArchitecturalConstraint"), paging).rules();
+ assertThat(rulesWParam).hasSize(1);
+ assertThat(rulesWParam.get(0).params()).hasSize(2);
+
+ // Inexistent profile
+ assertThat(profileRules.search(ProfileRuleQuery.create(3), paging).rules()).hasSize(0);
+
+ // Inexistent name/key
+ assertThat(profileRules.search(ProfileRuleQuery.create(1).setNameOrKey("polop"), paging).rules()).hasSize(0);
+ }
+
+ @Test
+ public void find_profile_rules_with_inheritance() {
+ Paging paging = Paging.create(10, 1);
+
+ List<QProfileRule> rules = profileRules.search(ProfileRuleQuery.create(1), paging).rules();
+ assertThat(rules).hasSize(3);
+
+ rules = profileRules.search(ProfileRuleQuery.create(1).setAnyInheritance(true), paging).rules();
+ assertThat(rules).hasSize(3);
+
+ rules = profileRules.search(ProfileRuleQuery.create(1).setInheritance(QProfileRule.INHERITED), paging).rules();
+ assertThat(rules).hasSize(1);
+ assertThat(rules.get(0).activeRuleId()).isEqualTo(391);
+
+ rules = profileRules.search(ProfileRuleQuery.create(1).setInheritance(QProfileRule.OVERRIDES), paging).rules();
+ assertThat(rules).hasSize(1);
+ assertThat(rules.get(0).activeRuleId()).isEqualTo(25);
+
+ rules = profileRules.search(ProfileRuleQuery.create(1).setNoInheritance(true), paging).rules();
+ assertThat(rules).hasSize(1);
+ assertThat(rules.get(0).activeRuleId()).isEqualTo(2702);
+ }
+
+ @Test
+ public void find_profile_rules_sorted_by_name() {
+ Paging paging = Paging.create(10, 1);
+
+ List<QProfileRule> rules = profileRules.search(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_RULE_NAME).setAsc(true), paging).rules();
+ assertThat(rules).hasSize(3);
+ assertThat(rules.get(0).name()).isEqualTo("Architectural constraint");
+ assertThat(rules.get(1).name()).isEqualTo("Internationalization - Consider using Locale parameterized version of invoked method");
+ assertThat(rules.get(2).name()).isEqualTo("Unused Null Check In Equals");
+
+ rules = profileRules.search(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_RULE_NAME).setAsc(false), paging).rules();
+ assertThat(rules).hasSize(3);
+ assertThat(rules.get(0).name()).isEqualTo("Unused Null Check In Equals");
+ assertThat(rules.get(1).name()).isEqualTo("Internationalization - Consider using Locale parameterized version of invoked method");
+ assertThat(rules.get(2).name()).isEqualTo("Architectural constraint");
+ }
+
+ @Test
+ public void find_profile_rules_sorted_by_creation_date() {
+ Paging paging = Paging.create(10, 1);
+
+ List<QProfileRule> rules = profileRules.search(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_CREATION_DATE).setAsc(true), paging).rules();
+ assertThat(rules).hasSize(3);
+ assertThat(rules.get(0).key()).isEqualTo("DM_CONVERT_CASE");
+ assertThat(rules.get(1).key()).isEqualTo("UnusedNullCheckInEquals");
+ assertThat(rules.get(2).key()).isEqualTo("ArchitecturalConstraint");
+
+ rules = profileRules.search(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_CREATION_DATE).setAsc(false), paging).rules();
+ assertThat(rules).hasSize(3);
+ assertThat(rules.get(0).key()).isEqualTo("ArchitecturalConstraint");
+ assertThat(rules.get(1).key()).isEqualTo("UnusedNullCheckInEquals");
+ assertThat(rules.get(2).key()).isEqualTo("DM_CONVERT_CASE");
+ }
+
+ @Test
+ public void find_profile_rules_with_paging() {
+ List<QProfileRule> rules = profileRules.search(ProfileRuleQuery.create(1), Paging.create(2, 1)).rules();
+ assertThat(rules).hasSize(2);
+ assertThat(rules.get(0).key()).isEqualTo("ArchitecturalConstraint");
+ assertThat(rules.get(1).key()).isEqualTo("DM_CONVERT_CASE");
+
+ rules = profileRules.search(ProfileRuleQuery.create(1), Paging.create(2, 2)).rules();
+ assertThat(rules).hasSize(1);
+ assertThat(rules.get(0).key()).isEqualTo("UnusedNullCheckInEquals");
+ }
+
+ @Test
+ public void find_profile_rule_ids() {
+ // All active rules for profile 1
+ List<Integer> result = profileRules.searchProfileRuleIds(ProfileRuleQuery.create(1));
+ assertThat(result).hasSize(3);
+ assertThat(result).containsOnly(25, 391, 2702);
+
+ assertThat(profileRules.searchProfileRuleIds(ProfileRuleQuery.create(1).addSeverities(Severity.CRITICAL))).hasSize(1);
+ assertThat(profileRules.searchProfileRuleIds(ProfileRuleQuery.create(1).addSeverities(Severity.INFO))).isEmpty();
+ }
+
+ @Test
+ public void find_profile_rule_ids_overriding_page_size() {
+ List<Integer> result = profileRules.searchProfileRuleIds(ProfileRuleQuery.create(1), 1);
+ assertThat(result).hasSize(3);
+ }
+
+ @Test
+ public void count_profile_rules() {
+ // All rules for profile 1
+ assertThat(profileRules.countProfileRules(ProfileRuleQuery.create(1))).isEqualTo(3);
+
+ // All rules for profile 2
+ assertThat(profileRules.countProfileRules(ProfileRuleQuery.create(2))).isEqualTo(1);
+
+ // Match on key
+ assertThat(profileRules.countProfileRules(ProfileRuleQuery.create(1).setNameOrKey("DM_CONVERT_CASE"))).isEqualTo(1);
+ }
+
+ @Test
+ public void find_inactive_profile_rules() {
+ Paging paging = Paging.create(10, 1);
+
+ // Search of inactive rule on profile 2
+ assertThat(profileRules.searchInactives(ProfileRuleQuery.create(2), paging).rules()).hasSize(4);
+
+ // Search of inactive rule on profile 1
+ assertThat(profileRules.searchInactives(ProfileRuleQuery.create(1), paging).rules()).hasSize(2);
+
+ // Match on key
+ assertThat(profileRules.searchInactives(ProfileRuleQuery.create(2).setNameOrKey("Boolean expressions"), paging).rules()).hasSize(1);
+
+ // Mach on severity
+ assertThat(profileRules.searchInactives(ProfileRuleQuery.create(2).addSeverities(Severity.INFO), paging).rules()).hasSize(1);
+ }
+
+ @Test
+ public void find_rules_with_tags() throws Exception {
+ esSetup.client().prepareBulk()
+ // id = 2303, tags = empty
+ .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_with_tags/tags_empty.json")))
+ // active rule with parent having no tag
+ .add(Requests.indexRequest().index("rules").type("active_rule").parent("2303").source(testFileAsString("find_inactive_rules_with_tags/active_rule_empty.json")))
+ // id = 2304, tags = taga
+ .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_with_tags/tags_a.json")))
+ // id = 2305, tags = taga, tagb
+ .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_with_tags/tags_ab.json")))
+ // id = 2306, tags = tagb, tagc
+ .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_with_tags/tags_bc.json")))
+ // id = 2307, tags = taga, tagc, tage
+ .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_with_tags/tags_ace.json")))
+ // active rule with parent having tags
+ .add(Requests.indexRequest().index("rules").type("active_rule").parent("2307").source(testFileAsString("find_inactive_rules_with_tags/active_rule_ace.json")))
+ .setRefresh(true)
+ .execute().actionGet();
+
+ Paging paging = Paging.create(10, 1);
+
+ // all rules
+ List<QProfileRule> rules = profileRules.searchInactives(ProfileRuleQuery.create(1).setLanguage("xoo"), paging).rules();
+ assertThat(rules).hasSize(5);
+
+ // check mapping is correctly loaded
+ assertThat(rules.get(0).systemTags()).containsOnly("taga");
+ assertThat(rules.get(0).adminTags()).isEmpty();
+ assertThat(rules.get(1).systemTags()).containsOnly("tagb");
+ assertThat(rules.get(1).adminTags()).containsOnly("taga");
+ assertThat(rules.get(2).systemTags()).containsOnly("taga", "tagc");
+ assertThat(rules.get(2).adminTags()).containsOnly("tage");
+ assertThat(rules.get(3).systemTags()).containsOnly("tagb", "tagc");
+ assertThat(rules.get(3).adminTags()).isEmpty();
+ assertThat(rules.get(4).systemTags()).isEmpty();
+ assertThat(rules.get(4).adminTags()).isEmpty();
+
+ // check search for inactive rules
+ assertThat(profileRules.searchInactiveProfileRuleIds(ProfileRuleQuery.create(2).setLanguage("xoo").addTags("taga")))
+ .hasSize(2).containsOnly(2304, 2305);
+ assertThat(profileRules.searchInactiveProfileRuleIds(ProfileRuleQuery.create(2).setLanguage("xoo").addTags("taga", "tagb")))
+ .hasSize(1).containsOnly(2305);
+
+ // check search for active rules
+ assertThat(profileRules.searchProfileRuleIds(ProfileRuleQuery.create(2).setLanguage("xoo").addTags("taga")))
+ .hasSize(1).containsOnly(2307);
+ assertThat(profileRules.searchProfileRuleIds(ProfileRuleQuery.create(2).setLanguage("xoo").addTags("tagb")))
+ .isEmpty();
+ }
+
+ @Test
+ public void find_inactive_profile_rules_sorted_by_name() {
+ Paging paging = Paging.create(10, 1);
+
+ List<QProfileRule> rules = profileRules.searchInactives(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_RULE_NAME).setAsc(true), paging).rules();
+ assertThat(rules).hasSize(2);
+ assertThat(rules.get(0).name()).isEqualTo("Boolean expressions should not be compared to true or false");
+ assertThat(rules.get(1).name()).isEqualTo("Double Checked Locking");
+
+ rules = profileRules.searchInactives(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_RULE_NAME).setAsc(false), paging).rules();
+ assertThat(rules).hasSize(2);
+ assertThat(rules.get(0).name()).isEqualTo("Double Checked Locking");
+ assertThat(rules.get(1).name()).isEqualTo("Boolean expressions should not be compared to true or false");
+ }
+
+ @Test
+ public void find_inactive_rules_sorted_ignoring_case() throws Exception {
+ esSetup.client().prepareBulk()
+ .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_sorted_ignoring_case/rule_A.json")))
+ .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_sorted_ignoring_case/rule_b.json")))
+ .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_sorted_ignoring_case/rule_C.json")))
+ .setRefresh(true)
+ .execute().actionGet();
+
+ Paging paging = Paging.create(10, 1);
+
+ List<QProfileRule> rules = profileRules.searchInactives(ProfileRuleQuery.create(1).setLanguage("xoo").setSort(ProfileRuleQuery.SORT_BY_RULE_NAME).setAsc(true), paging).rules();
+ assertThat(rules).hasSize(3);
+ assertThat(rules.get(0).name()).isEqualTo("A first rule");
+ assertThat(rules.get(1).name()).isEqualTo("b second rule");
+ assertThat(rules.get(2).name()).isEqualTo("C third rule");
+ }
+
+ @Test
+ public void find_inactive_profile_rules_sorted_by_creation_date() {
+ Paging paging = Paging.create(10, 1);
+
+ List<QProfileRule> rules = profileRules.searchInactives(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_CREATION_DATE).setAsc(true), paging).rules();
+ assertThat(rules).hasSize(2);
+ assertThat(rules.get(0).key()).isEqualTo("com.puppycrawl.tools.checkstyle.checks.coding.DoubleCheckedLockingCheck");
+ assertThat(rules.get(1).key()).isEqualTo("S1125");
+
+ rules = profileRules.searchInactives(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_CREATION_DATE).setAsc(false), paging).rules();
+ assertThat(rules).hasSize(2);
+ assertThat(rules.get(0).key()).isEqualTo("S1125");
+ assertThat(rules.get(1).key()).isEqualTo("com.puppycrawl.tools.checkstyle.checks.coding.DoubleCheckedLockingCheck");
+ }
+
+ @Test
+ public void find_inactive_profile_rule_ids() {
+ // Search of inactive rule on profile 2
+ assertThat(profileRules.searchInactiveProfileRuleIds(ProfileRuleQuery.create(2))).hasSize(4);
+
+ // Search of inactive rule on profile 1
+ assertThat(profileRules.searchInactiveProfileRuleIds(ProfileRuleQuery.create(1))).hasSize(2);
+
+ // Match on key
+ assertThat(profileRules.searchInactiveProfileRuleIds(ProfileRuleQuery.create(2).setNameOrKey("Boolean expressions"))).hasSize(1);
+
+ // Mach on severity
+ assertThat(profileRules.searchInactiveProfileRuleIds(ProfileRuleQuery.create(2).addSeverities(Severity.INFO))).hasSize(1);
+ }
+
+ @Test
+ public void count_inactive_profile_rules() {
+ // All rules for profile 1
+ assertThat(profileRules.countInactiveProfileRules(ProfileRuleQuery.create(2))).isEqualTo(4);
+
+ // All rules for profile 2
+ assertThat(profileRules.countInactiveProfileRules(ProfileRuleQuery.create(1))).isEqualTo(2);
+
+ // Match on key
+ assertThat(profileRules.countInactiveProfileRules(ProfileRuleQuery.create(2).setNameOrKey("Boolean expressions"))).isEqualTo(1);
+
+ // Mach on severity
+ assertThat(profileRules.countInactiveProfileRules(ProfileRuleQuery.create(2).addSeverities(Severity.INFO))).isEqualTo(1);
+ }
+
+ @Test
+ public void get_from_active_rule() {
+ assertThat(profileRules.findByActiveRuleId(391)).isNotNull();
+ }
+
+ @Test
+ public void get_from_rule() {
+ assertThat(profileRules.findByActiveRuleId(25)).isNotNull();
+ }
+
+ private String testFileAsString(String testFile) throws Exception {
+ return IOUtils.toString(TestUtils.getResource(getClass(), testFile).toURI());
+ }
+}
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.rule.ProfileRuleQuery;
-import org.sonar.server.rule.ProfileRules;
import org.sonar.server.user.UserSession;
import java.util.List;
QProfilePluginExporter exporter;
@Mock
- ProfileRules rules;
+ QProfileRuleLookup rules;
QProfiles qProfiles;
final int profileId = 42;
ProfileRuleQuery query = ProfileRuleQuery.create(profileId);
Paging paging = Paging.create(20, 1);
- ProfileRules.QProfileRuleResult result = mock(ProfileRules.QProfileRuleResult.class);
+ QProfileRuleLookup.QProfileRuleResult result = mock(QProfileRuleLookup.QProfileRuleResult.class);
when(rules.searchInactives(query, paging)).thenReturn(result);
assertThat(qProfiles.searchInactiveProfileRules(query, paging)).isEqualTo(result);
}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.server.rule;
-
-import com.github.tlrx.elasticsearch.test.EsSetup;
-import org.apache.commons.io.IOUtils;
-import org.elasticsearch.client.Requests;
-import org.elasticsearch.common.settings.ImmutableSettings;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.config.Settings;
-import org.sonar.api.rule.Severity;
-import org.sonar.core.profiling.Profiling;
-import org.sonar.server.es.ESIndex;
-import org.sonar.server.es.ESNode;
-import org.sonar.server.qualityprofile.Paging;
-import org.sonar.server.qualityprofile.QProfileRule;
-import org.sonar.test.TestUtils;
-
-import java.util.List;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ProfileRulesTest {
-
- private ProfileRules profileRules;
- private EsSetup esSetup;
-
- @Before
- public void setUp() throws Exception {
- esSetup = new EsSetup(ImmutableSettings.builder()
- .loadFromUrl(ESNode.class.getResource("config/elasticsearch.json"))
- .build()
- );
- esSetup.execute(EsSetup.deleteAll());
-
- ESNode searchNode = mock(ESNode.class);
- when(searchNode.client()).thenReturn(esSetup.client());
-
- Settings settings = new Settings();
- settings.setProperty("sonar.log.profilingLevel", "FULL");
- ESIndex index = new ESIndex(searchNode, new Profiling(settings));
- index.start();
- RuleRegistry registry = new RuleRegistry(index, null, null, null);
- registry.start();
- profileRules = new ProfileRules(index);
-
- esSetup.client().prepareBulk()
- // On profile 1
- .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("shared/rule25.json")))
- .add(Requests.indexRequest().index("rules").type("active_rule").parent("25").source(testFileAsString("shared/active_rule25.json")))
- // On profile 1 and 2
- .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("shared/rule759.json")))
- .add(Requests.indexRequest().index("rules").type("active_rule").parent("759").source(testFileAsString("shared/active_rule391.json")))
- .add(Requests.indexRequest().index("rules").type("active_rule").parent("759").source(testFileAsString("shared/active_rule523.json")))
- // On profile 1
- .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("shared/rule1482.json")))
- .add(Requests.indexRequest().index("rules").type("active_rule").parent("1482").source(testFileAsString("shared/active_rule2702.json")))
- // Rules on no profile
- .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("shared/rule944.json")))
- .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("shared/rule719.json")))
- // Removed rule
- .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("shared/rule860.json")))
- .setRefresh(true).execute().actionGet();
- }
-
- @After
- public void tearDown() {
- esSetup.terminate();
- }
-
- @Test
- public void find_by_rule_id() {
- assertThat(profileRules.findByRuleId(25)).isNotNull();
- assertThat(profileRules.findByRuleId(9999)).isNull();
- }
-
- @Test
- public void find_by_active_rule_id() {
- assertThat(profileRules.findByActiveRuleId(391)).isNotNull();
- assertThat(profileRules.findByActiveRuleId(9999)).isNull();
- }
-
- @Test
- public void find_by_active_rule_id_with_inheritance() throws Exception {
- esSetup.client().prepareBulk()
- // Parent active rule
- .add(Requests.indexRequest().index("rules").type("active_rule").parent("25").source(testFileAsString("find_active_rules_with_inheritance/active_rule25.json")))
- // Child active rule
- .add(Requests.indexRequest().index("rules").type("active_rule").parent("759").source(testFileAsString("find_active_rules_with_inheritance/active_rule391.json")))
- .setRefresh(true)
- .execute().actionGet();
-
- QProfileRule child = profileRules.findByActiveRuleId(391);
- assertThat(child.inheritance()).isEqualTo("INHERITED");
- assertThat(child.activeRuleParentId()).isEqualTo(25);
- }
-
- @Test
- public void find_by_profile_id_and_rule_id() {
- // Rules on profiles
- QProfileRule rule = profileRules.findByProfileIdAndRuleId(1, 759);
- assertThat(rule).isNotNull();
- assertThat(rule.key()).isEqualTo("UnusedNullCheckInEquals");
- assertThat(rule.severity()).isEqualTo(Severity.MAJOR);
-
- // Rules on no profiles
- assertThat(profileRules.findByProfileIdAndRuleId(1, 944)).isNull();
-
- // Not existing rule
- assertThat(profileRules.findByProfileIdAndRuleId(1, 99999)).isNull();
- }
-
- @Test
- public void find_profile_rules() {
- Paging paging = Paging.create(10, 1);
-
- // All rules for profile 1
- List<QProfileRule> rules1 = profileRules.search(ProfileRuleQuery.create(1), paging).rules();
- assertThat(rules1).hasSize(3);
- assertThat(rules1.get(0).key()).isEqualTo("ArchitecturalConstraint");
- assertThat(rules1.get(0).severity()).isEqualTo(Severity.CRITICAL);
-
- // All rules for profile 2
- List<QProfileRule> rules2 = profileRules.search(ProfileRuleQuery.create(2), paging).rules();
- assertThat(rules2).hasSize(1);
- assertThat(rules2.get(0).id()).isEqualTo(759);
- assertThat(rules2.get(0).activeRuleId()).isEqualTo(523);
-
- // Match on key
- assertThat(profileRules.search(ProfileRuleQuery.create(1).setNameOrKey("DM_CONVERT_CASE"), paging).rules()).hasSize(1);
-
- // Match on name
- assertThat(profileRules.search(ProfileRuleQuery.create(1).setNameOrKey("Unused Check"), paging).rules()).hasSize(1);
-
- // Match on repositoryKey
- assertThat(profileRules.search(ProfileRuleQuery.create(1).addRepositoryKeys("findbugs"), paging).rules()).hasSize(1);
-
- assertThat(profileRules.search(ProfileRuleQuery.create(1).addSeverities(Severity.CRITICAL), paging).rules()).hasSize(1);
- // Active rule 25 is in MINOR (rule 25 is in INFO)
- assertThat(profileRules.search(ProfileRuleQuery.create(1).addSeverities(Severity.INFO), paging).rules()).isEmpty();
-
- // Match on key, rule has parameters
- List<QProfileRule> rulesWParam = profileRules.search(ProfileRuleQuery.create(1).setNameOrKey("ArchitecturalConstraint"), paging).rules();
- assertThat(rulesWParam).hasSize(1);
- assertThat(rulesWParam.get(0).params()).hasSize(2);
-
- // Inexistent profile
- assertThat(profileRules.search(ProfileRuleQuery.create(3), paging).rules()).hasSize(0);
-
- // Inexistent name/key
- assertThat(profileRules.search(ProfileRuleQuery.create(1).setNameOrKey("polop"), paging).rules()).hasSize(0);
- }
-
- @Test
- public void find_profile_rules_with_inheritance() {
- Paging paging = Paging.create(10, 1);
-
- List<QProfileRule> rules = profileRules.search(ProfileRuleQuery.create(1), paging).rules();
- assertThat(rules).hasSize(3);
-
- rules = profileRules.search(ProfileRuleQuery.create(1).setAnyInheritance(true), paging).rules();
- assertThat(rules).hasSize(3);
-
- rules = profileRules.search(ProfileRuleQuery.create(1).setInheritance(QProfileRule.INHERITED), paging).rules();
- assertThat(rules).hasSize(1);
- assertThat(rules.get(0).activeRuleId()).isEqualTo(391);
-
- rules = profileRules.search(ProfileRuleQuery.create(1).setInheritance(QProfileRule.OVERRIDES), paging).rules();
- assertThat(rules).hasSize(1);
- assertThat(rules.get(0).activeRuleId()).isEqualTo(25);
-
- rules = profileRules.search(ProfileRuleQuery.create(1).setNoInheritance(true), paging).rules();
- assertThat(rules).hasSize(1);
- assertThat(rules.get(0).activeRuleId()).isEqualTo(2702);
- }
-
- @Test
- public void find_profile_rules_sorted_by_name() {
- Paging paging = Paging.create(10, 1);
-
- List<QProfileRule> rules = profileRules.search(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_RULE_NAME).setAsc(true), paging).rules();
- assertThat(rules).hasSize(3);
- assertThat(rules.get(0).name()).isEqualTo("Architectural constraint");
- assertThat(rules.get(1).name()).isEqualTo("Internationalization - Consider using Locale parameterized version of invoked method");
- assertThat(rules.get(2).name()).isEqualTo("Unused Null Check In Equals");
-
- rules = profileRules.search(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_RULE_NAME).setAsc(false), paging).rules();
- assertThat(rules).hasSize(3);
- assertThat(rules.get(0).name()).isEqualTo("Unused Null Check In Equals");
- assertThat(rules.get(1).name()).isEqualTo("Internationalization - Consider using Locale parameterized version of invoked method");
- assertThat(rules.get(2).name()).isEqualTo("Architectural constraint");
- }
-
- @Test
- public void find_profile_rules_sorted_by_creation_date() {
- Paging paging = Paging.create(10, 1);
-
- List<QProfileRule> rules = profileRules.search(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_CREATION_DATE).setAsc(true), paging).rules();
- assertThat(rules).hasSize(3);
- assertThat(rules.get(0).key()).isEqualTo("DM_CONVERT_CASE");
- assertThat(rules.get(1).key()).isEqualTo("UnusedNullCheckInEquals");
- assertThat(rules.get(2).key()).isEqualTo("ArchitecturalConstraint");
-
- rules = profileRules.search(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_CREATION_DATE).setAsc(false), paging).rules();
- assertThat(rules).hasSize(3);
- assertThat(rules.get(0).key()).isEqualTo("ArchitecturalConstraint");
- assertThat(rules.get(1).key()).isEqualTo("UnusedNullCheckInEquals");
- assertThat(rules.get(2).key()).isEqualTo("DM_CONVERT_CASE");
- }
-
- @Test
- public void find_profile_rules_with_paging() {
- List<QProfileRule> rules = profileRules.search(ProfileRuleQuery.create(1), Paging.create(2, 1)).rules();
- assertThat(rules).hasSize(2);
- assertThat(rules.get(0).key()).isEqualTo("ArchitecturalConstraint");
- assertThat(rules.get(1).key()).isEqualTo("DM_CONVERT_CASE");
-
- rules = profileRules.search(ProfileRuleQuery.create(1), Paging.create(2, 2)).rules();
- assertThat(rules).hasSize(1);
- assertThat(rules.get(0).key()).isEqualTo("UnusedNullCheckInEquals");
- }
-
- @Test
- public void find_profile_rule_ids() {
- // All active rules for profile 1
- List<Integer> result = profileRules.searchProfileRuleIds(ProfileRuleQuery.create(1));
- assertThat(result).hasSize(3);
- assertThat(result).containsOnly(25, 391, 2702);
-
- assertThat(profileRules.searchProfileRuleIds(ProfileRuleQuery.create(1).addSeverities(Severity.CRITICAL))).hasSize(1);
- assertThat(profileRules.searchProfileRuleIds(ProfileRuleQuery.create(1).addSeverities(Severity.INFO))).isEmpty();
- }
-
- @Test
- public void find_profile_rule_ids_overriding_page_size() {
- List<Integer> result = profileRules.searchProfileRuleIds(ProfileRuleQuery.create(1), 1);
- assertThat(result).hasSize(3);
- }
-
- @Test
- public void count_profile_rules() {
- // All rules for profile 1
- assertThat(profileRules.countProfileRules(ProfileRuleQuery.create(1))).isEqualTo(3);
-
- // All rules for profile 2
- assertThat(profileRules.countProfileRules(ProfileRuleQuery.create(2))).isEqualTo(1);
-
- // Match on key
- assertThat(profileRules.countProfileRules(ProfileRuleQuery.create(1).setNameOrKey("DM_CONVERT_CASE"))).isEqualTo(1);
- }
-
- @Test
- public void find_inactive_profile_rules() {
- Paging paging = Paging.create(10, 1);
-
- // Search of inactive rule on profile 2
- assertThat(profileRules.searchInactives(ProfileRuleQuery.create(2), paging).rules()).hasSize(4);
-
- // Search of inactive rule on profile 1
- assertThat(profileRules.searchInactives(ProfileRuleQuery.create(1), paging).rules()).hasSize(2);
-
- // Match on key
- assertThat(profileRules.searchInactives(ProfileRuleQuery.create(2).setNameOrKey("Boolean expressions"), paging).rules()).hasSize(1);
-
- // Mach on severity
- assertThat(profileRules.searchInactives(ProfileRuleQuery.create(2).addSeverities(Severity.INFO), paging).rules()).hasSize(1);
- }
-
- @Test
- public void find_rules_with_tags() throws Exception {
- esSetup.client().prepareBulk()
- // id = 2303, tags = empty
- .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_with_tags/tags_empty.json")))
- // active rule with parent having no tag
- .add(Requests.indexRequest().index("rules").type("active_rule").parent("2303").source(testFileAsString("find_inactive_rules_with_tags/active_rule_empty.json")))
- // id = 2304, tags = taga
- .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_with_tags/tags_a.json")))
- // id = 2305, tags = taga, tagb
- .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_with_tags/tags_ab.json")))
- // id = 2306, tags = tagb, tagc
- .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_with_tags/tags_bc.json")))
- // id = 2307, tags = taga, tagc, tage
- .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_with_tags/tags_ace.json")))
- // active rule with parent having tags
- .add(Requests.indexRequest().index("rules").type("active_rule").parent("2307").source(testFileAsString("find_inactive_rules_with_tags/active_rule_ace.json")))
- .setRefresh(true)
- .execute().actionGet();
-
- Paging paging = Paging.create(10, 1);
-
- // all rules
- List<QProfileRule> rules = profileRules.searchInactives(ProfileRuleQuery.create(1).setLanguage("xoo"), paging).rules();
- assertThat(rules).hasSize(5);
-
- // check mapping is correctly loaded
- assertThat(rules.get(0).systemTags()).containsOnly("taga");
- assertThat(rules.get(0).adminTags()).isEmpty();
- assertThat(rules.get(1).systemTags()).containsOnly("tagb");
- assertThat(rules.get(1).adminTags()).containsOnly("taga");
- assertThat(rules.get(2).systemTags()).containsOnly("taga", "tagc");
- assertThat(rules.get(2).adminTags()).containsOnly("tage");
- assertThat(rules.get(3).systemTags()).containsOnly("tagb", "tagc");
- assertThat(rules.get(3).adminTags()).isEmpty();
- assertThat(rules.get(4).systemTags()).isEmpty();
- assertThat(rules.get(4).adminTags()).isEmpty();
-
- // check search for inactive rules
- assertThat(profileRules.searchInactiveProfileRuleIds(ProfileRuleQuery.create(2).setLanguage("xoo").addTags("taga")))
- .hasSize(2).containsOnly(2304, 2305);
- assertThat(profileRules.searchInactiveProfileRuleIds(ProfileRuleQuery.create(2).setLanguage("xoo").addTags("taga", "tagb")))
- .hasSize(1).containsOnly(2305);
-
- // check search for active rules
- assertThat(profileRules.searchProfileRuleIds(ProfileRuleQuery.create(2).setLanguage("xoo").addTags("taga")))
- .hasSize(1).containsOnly(2307);
- assertThat(profileRules.searchProfileRuleIds(ProfileRuleQuery.create(2).setLanguage("xoo").addTags("tagb")))
- .isEmpty();
- }
-
- @Test
- public void find_inactive_profile_rules_sorted_by_name() {
- Paging paging = Paging.create(10, 1);
-
- List<QProfileRule> rules = profileRules.searchInactives(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_RULE_NAME).setAsc(true), paging).rules();
- assertThat(rules).hasSize(2);
- assertThat(rules.get(0).name()).isEqualTo("Boolean expressions should not be compared to true or false");
- assertThat(rules.get(1).name()).isEqualTo("Double Checked Locking");
-
- rules = profileRules.searchInactives(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_RULE_NAME).setAsc(false), paging).rules();
- assertThat(rules).hasSize(2);
- assertThat(rules.get(0).name()).isEqualTo("Double Checked Locking");
- assertThat(rules.get(1).name()).isEqualTo("Boolean expressions should not be compared to true or false");
- }
-
- @Test
- public void find_inactive_rules_sorted_ignoring_case() throws Exception {
- esSetup.client().prepareBulk()
- .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_sorted_ignoring_case/rule_A.json")))
- .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_sorted_ignoring_case/rule_b.json")))
- .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("find_inactive_rules_sorted_ignoring_case/rule_C.json")))
- .setRefresh(true)
- .execute().actionGet();
-
- Paging paging = Paging.create(10, 1);
-
- List<QProfileRule> rules = profileRules.searchInactives(ProfileRuleQuery.create(1).setLanguage("xoo").setSort(ProfileRuleQuery.SORT_BY_RULE_NAME).setAsc(true), paging).rules();
- assertThat(rules).hasSize(3);
- assertThat(rules.get(0).name()).isEqualTo("A first rule");
- assertThat(rules.get(1).name()).isEqualTo("b second rule");
- assertThat(rules.get(2).name()).isEqualTo("C third rule");
- }
-
- @Test
- public void find_inactive_profile_rules_sorted_by_creation_date() {
- Paging paging = Paging.create(10, 1);
-
- List<QProfileRule> rules = profileRules.searchInactives(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_CREATION_DATE).setAsc(true), paging).rules();
- assertThat(rules).hasSize(2);
- assertThat(rules.get(0).key()).isEqualTo("com.puppycrawl.tools.checkstyle.checks.coding.DoubleCheckedLockingCheck");
- assertThat(rules.get(1).key()).isEqualTo("S1125");
-
- rules = profileRules.searchInactives(ProfileRuleQuery.create(1).setSort(ProfileRuleQuery.SORT_BY_CREATION_DATE).setAsc(false), paging).rules();
- assertThat(rules).hasSize(2);
- assertThat(rules.get(0).key()).isEqualTo("S1125");
- assertThat(rules.get(1).key()).isEqualTo("com.puppycrawl.tools.checkstyle.checks.coding.DoubleCheckedLockingCheck");
- }
-
- @Test
- public void find_inactive_profile_rule_ids() {
- // Search of inactive rule on profile 2
- assertThat(profileRules.searchInactiveProfileRuleIds(ProfileRuleQuery.create(2))).hasSize(4);
-
- // Search of inactive rule on profile 1
- assertThat(profileRules.searchInactiveProfileRuleIds(ProfileRuleQuery.create(1))).hasSize(2);
-
- // Match on key
- assertThat(profileRules.searchInactiveProfileRuleIds(ProfileRuleQuery.create(2).setNameOrKey("Boolean expressions"))).hasSize(1);
-
- // Mach on severity
- assertThat(profileRules.searchInactiveProfileRuleIds(ProfileRuleQuery.create(2).addSeverities(Severity.INFO))).hasSize(1);
- }
-
- @Test
- public void count_inactive_profile_rules() {
- // All rules for profile 1
- assertThat(profileRules.countInactiveProfileRules(ProfileRuleQuery.create(2))).isEqualTo(4);
-
- // All rules for profile 2
- assertThat(profileRules.countInactiveProfileRules(ProfileRuleQuery.create(1))).isEqualTo(2);
-
- // Match on key
- assertThat(profileRules.countInactiveProfileRules(ProfileRuleQuery.create(2).setNameOrKey("Boolean expressions"))).isEqualTo(1);
-
- // Mach on severity
- assertThat(profileRules.countInactiveProfileRules(ProfileRuleQuery.create(2).addSeverities(Severity.INFO))).isEqualTo(1);
- }
-
- @Test
- public void get_from_active_rule() {
- assertThat(profileRules.findByActiveRuleId(391)).isNotNull();
- }
-
- @Test
- public void get_from_rule() {
- assertThat(profileRules.findByActiveRuleId(25)).isNotNull();
- }
-
- private String testFileAsString(String testFile) throws Exception {
- return IOUtils.toString(TestUtils.getResource(getClass(), testFile).toURI());
- }
-}
--- /dev/null
+{
+ "id": 25,
+ "severity": "MINOR",
+ "profileId": 1,
+ "inheritance": null
+}
--- /dev/null
+{
+ "id": 391,
+ "severity": "MINOR",
+ "profileId": 2,
+ "inheritance": "INHERITED",
+ "activeRuleParentId": 25
+}
--- /dev/null
+{
+ "id": 2303,
+ "key": "RuleA",
+ "language": "xoo",
+ "name": "A first rule",
+ "description": "First rule of Fight Club is: you do not talk about Fight Club.",
+ "parentKey": null,
+ "repositoryKey": "xoo",
+ "severity": "INFO",
+ "status": "READY",
+ "createdAt": "2013-12-04T10:24:09.000Z",
+ "updatedAt": "2013-12-12T15:19:59.000Z"
+}
--- /dev/null
+{
+ "id": 2305,
+ "key": "RuleC",
+ "language": "xoo",
+ "name": "C third rule",
+ "description": "Third rule of Fight Club: someone yells stop, goes limp, taps out, the fight is over.",
+ "parentKey": null,
+ "repositoryKey": "xoo",
+ "severity": "BLOCKER",
+ "status": "READY",
+ "createdAt": "2013-07-04T07:38:05.543Z",
+ "updatedAt": "2013-03-27T08:52:40.370Z"
+}
--- /dev/null
+{
+ "id": 2304,
+ "key": "Ruleb",
+ "language": "xoo",
+ "name": "b second rule",
+ "description": "Second rule of Fight Club is: you do NOT talk about Fight Club.",
+ "parentKey": null,
+ "repositoryKey": "xoo",
+ "severity": "MAJOR",
+ "status": "READY",
+ "createdAt": "2013-12-04T10:24:11.000Z",
+ "updatedAt": "2013-12-12T15:20:01.000Z"
+}
--- /dev/null
+{
+ "id": 2307,
+ "severity": "CRITICAL",
+ "profileId": 2,
+ "inheritance": null
+}
--- /dev/null
+{
+ "id": 2303,
+ "severity": "INFO",
+ "profileId": 2,
+ "inheritance": null
+}
--- /dev/null
+{
+ "id": 2304,
+ "key": "RuleWithTagA",
+ "language": "xoo",
+ "name": "Rule with tag taga",
+ "description": "This rule has tag 'taga'",
+ "parentKey": null,
+ "repositoryKey": "xoo",
+ "severity": "INFO",
+ "status": "READY",
+ "systemTags": ["taga"],
+ "createdAt": "2013-12-04T10:24:09.000Z",
+ "updatedAt": "2013-12-12T15:19:59.000Z"
+}
--- /dev/null
+{
+ "id": 2305,
+ "key": "RuleWithTagsAB",
+ "language": "xoo",
+ "name": "Rule with tags taga and tagb",
+ "description": "This rule has tags 'taga' and 'tagb'",
+ "parentKey": null,
+ "repositoryKey": "xoo",
+ "severity": "INFO",
+ "status": "READY",
+ "systemTags": ["tagb"],
+ "adminTags": ["taga"],
+ "createdAt": "2013-12-04T10:24:09.000Z",
+ "updatedAt": "2013-12-12T15:19:59.000Z"
+}
--- /dev/null
+{
+ "id": 2307,
+ "key": "RuleWithTagsACE",
+ "language": "xoo",
+ "name": "Rule with tags taga, tagc and tage",
+ "description": "This rule has tags 'taga', 'tagc' and 'tage'",
+ "parentKey": null,
+ "repositoryKey": "xoo",
+ "severity": "INFO",
+ "status": "READY",
+ "systemTags": ["taga", "tagc"],
+ "adminTags": ["tage"],
+ "createdAt": "2013-12-04T10:24:09.000Z",
+ "updatedAt": "2013-12-12T15:19:59.000Z"
+}
--- /dev/null
+{
+ "id": 2306,
+ "key": "RuleWithTagsBC",
+ "language": "xoo",
+ "name": "Rule with tags tagb and tagc",
+ "description": "This rule has tags 'tagb' and 'tagc'",
+ "parentKey": null,
+ "repositoryKey": "xoo",
+ "severity": "INFO",
+ "status": "READY",
+ "systemTags": ["tagb", "tagc"],
+ "createdAt": "2013-12-04T10:24:09.000Z",
+ "updatedAt": "2013-12-12T15:19:59.000Z"
+}
--- /dev/null
+{
+ "id": 2303,
+ "key": "RuleWithoutTags",
+ "language": "xoo",
+ "name": "Rule without tags",
+ "description": "This rule has no tag",
+ "parentKey": null,
+ "repositoryKey": "xoo",
+ "severity": "INFO",
+ "status": "READY",
+ "createdAt": "2013-12-04T10:24:09.000Z",
+ "updatedAt": "2013-12-12T15:19:59.000Z"
+}
--- /dev/null
+{
+ "id": 25,
+ "severity": "MINOR",
+ "profileId": 1,
+ "inheritance": "OVERRIDES"
+}
--- /dev/null
+{
+ "id": 2702,
+ "severity": "CRITICAL",
+ "profileId": 1,
+ "inheritance": null,
+ "params": [
+ {
+ "key": "fromClasses",
+ "value": "**.core.**"
+ },
+ {
+ "key": "toClasses",
+ "value": "**.server.**"
+ }
+ ]
+}
--- /dev/null
+{
+ "id": 391,
+ "severity": "MAJOR",
+ "profileId": 1,
+ "inheritance": "INHERITED"
+}
--- /dev/null
+{
+ "id": 523,
+ "severity": "MAJOR",
+ "profileId": 2,
+ "inheritance": null
+}
--- /dev/null
+{
+ "id": 1482,
+ "key": "ArchitecturalConstraint",
+ "language": "java",
+ "name": "Architectural constraint",
+ "description": "<p>A source code comply to an architectural model when it fully\n\tadheres to a set of architectural constraints. A constraint allows to\n\tdeny references between classes by pattern.</p>\n<p>You can for instance use this rule to :</p>\n<ul>\n\t<li>forbid access to **.web.** from **.dao.** classes</li>\n\t<li>forbid access to java.util.Vector, java.util.Hashtable and\n\t\tjava.util.Enumeration from any classes</li>\n\t<li>forbid access to java.sql.** from **.ui.** and **.web.**\n\t\tclasses</li>\n</ul>",
+ "parentKey": null,
+ "repositoryKey": "squid",
+ "severity": "MAJOR",
+ "status": "READY",
+ "createdAt": "2013-12-11T13:48:00.799Z",
+ "updatedAt": "2013-12-13T17:26:35.767Z",
+ "params": [
+ {
+ "key": "toClasses",
+ "type": "STRING",
+ "defaultValue": "",
+ "description": "Mandatory. Ex : java.util.Vector, java.util.Hashtable, java.util.Enumeration"
+ },
+ {
+ "key": "fromClasses",
+ "type": "STRING",
+ "defaultValue": "",
+ "description": "Optional. If this property is not defined, all classes should adhere to this constraint. Ex : **.web.**"
+ }
+ ]
+}
--- /dev/null
+{
+ "id": 25,
+ "key": "DM_CONVERT_CASE",
+ "language": "java",
+ "name": "Internationalization - Consider using Locale parameterized version of invoked method",
+ "description": "<p> A String is being converted to upper or lowercase, using the platform's default encoding. This may\n result in improper conversions when used with international characters. Use the </p>\n <table><tr><td>String.toUpperCase( Locale l )</td></tr><tr><td>String.toLowerCase( Locale l )</td></tr></table>\n <p>versions instead.</p>",
+ "parentKey": null,
+ "repositoryKey": "findbugs",
+ "severity": "INFO",
+ "status": "READY",
+ "createdAt": "2013-12-04T10:24:09.000Z",
+ "updatedAt": "2013-12-12T15:19:59.000Z"
+}
--- /dev/null
+{
+ "id": 719,
+ "key": "com.puppycrawl.tools.checkstyle.checks.coding.DoubleCheckedLockingCheck",
+ "language": "java",
+ "name": "Double Checked Locking",
+ "description": null,
+ "parentKey": null,
+ "repositoryKey": "checkstyle",
+ "severity": "MAJOR",
+ "status": "READY",
+ "cardinality": "SINGLE",
+ "createdAt": "2013-07-04T07:38:05.543Z",
+ "updatedAt": "2013-03-27T08:52:40.370Z"
+}
--- /dev/null
+{
+ "id": 759,
+ "key": "UnusedNullCheckInEquals",
+ "language": "java",
+ "name": "Unused Null Check In Equals",
+ "description": "After checking an object reference for null, you should invoke equals() on that object rather than passing it to another object's equals() method.",
+ "parentKey": null,
+ "repositoryKey": "pmd",
+ "severity": "MAJOR",
+ "status": "READY",
+ "createdAt": "2013-12-04T10:24:11.000Z",
+ "updatedAt": "2013-12-12T15:20:01.000Z"
+}
--- /dev/null
+{
+ "id": 860,
+ "key": "Snippet",
+ "language": null,
+ "name": null,
+ "description": null,
+ "parentKey": null,
+ "repositoryKey": "squid",
+ "severity": "MAJOR",
+ "status": "REMOVED",
+ "cardinality": "MULTIPLE",
+ "createdAt": "2013-07-04T07:38:05.543Z",
+ "updatedAt": "2013-03-27T08:52:40.370Z"
+}
--- /dev/null
+{
+ "id": 944,
+ "key": "S1125",
+ "language": "java",
+ "name": "Boolean expressions should not be compared to true or false",
+ "description": "<p> Boolean expressions should not be compared against boolean literals, as their value can be directly used. </p> <p>The following code:</p> <pre> if (booleanVariable == true) { /* ... */ } // Non-Compliant if (booleanVariable != true) { /* ... */ } // Non-Compliant </pre> <p>should be refactored into:</p> <pre> if (booleanVariable) { /* ... */ } // Compliant if (!booleanVariable) { /* ... */ } // Compliant </pre>",
+ "parentKey": null,
+ "repositoryKey": "squid",
+ "severity": "MAJOR",
+ "status": "READY",
+ "cardinality": "SINGLE",
+ "createdAt": "2013-07-26T07:40:51.977Z",
+ "updatedAt": "2014-01-10T15:38:27.386Z"
+}
+++ /dev/null
-{
- "id": 25,
- "severity": "MINOR",
- "profileId": 1,
- "inheritance": null
-}
+++ /dev/null
-{
- "id": 391,
- "severity": "MINOR",
- "profileId": 2,
- "inheritance": "INHERITED",
- "activeRuleParentId": 25
-}
+++ /dev/null
-{
- "id": 2303,
- "key": "RuleA",
- "language": "xoo",
- "name": "A first rule",
- "description": "First rule of Fight Club is: you do not talk about Fight Club.",
- "parentKey": null,
- "repositoryKey": "xoo",
- "severity": "INFO",
- "status": "READY",
- "createdAt": "2013-12-04T10:24:09.000Z",
- "updatedAt": "2013-12-12T15:19:59.000Z"
-}
+++ /dev/null
-{
- "id": 2305,
- "key": "RuleC",
- "language": "xoo",
- "name": "C third rule",
- "description": "Third rule of Fight Club: someone yells stop, goes limp, taps out, the fight is over.",
- "parentKey": null,
- "repositoryKey": "xoo",
- "severity": "BLOCKER",
- "status": "READY",
- "createdAt": "2013-07-04T07:38:05.543Z",
- "updatedAt": "2013-03-27T08:52:40.370Z"
-}
+++ /dev/null
-{
- "id": 2304,
- "key": "Ruleb",
- "language": "xoo",
- "name": "b second rule",
- "description": "Second rule of Fight Club is: you do NOT talk about Fight Club.",
- "parentKey": null,
- "repositoryKey": "xoo",
- "severity": "MAJOR",
- "status": "READY",
- "createdAt": "2013-12-04T10:24:11.000Z",
- "updatedAt": "2013-12-12T15:20:01.000Z"
-}
+++ /dev/null
-{
- "id": 2307,
- "severity": "CRITICAL",
- "profileId": 2,
- "inheritance": null
-}
+++ /dev/null
-{
- "id": 2303,
- "severity": "INFO",
- "profileId": 2,
- "inheritance": null
-}
+++ /dev/null
-{
- "id": 2304,
- "key": "RuleWithTagA",
- "language": "xoo",
- "name": "Rule with tag taga",
- "description": "This rule has tag 'taga'",
- "parentKey": null,
- "repositoryKey": "xoo",
- "severity": "INFO",
- "status": "READY",
- "systemTags": ["taga"],
- "createdAt": "2013-12-04T10:24:09.000Z",
- "updatedAt": "2013-12-12T15:19:59.000Z"
-}
+++ /dev/null
-{
- "id": 2305,
- "key": "RuleWithTagsAB",
- "language": "xoo",
- "name": "Rule with tags taga and tagb",
- "description": "This rule has tags 'taga' and 'tagb'",
- "parentKey": null,
- "repositoryKey": "xoo",
- "severity": "INFO",
- "status": "READY",
- "systemTags": ["tagb"],
- "adminTags": ["taga"],
- "createdAt": "2013-12-04T10:24:09.000Z",
- "updatedAt": "2013-12-12T15:19:59.000Z"
-}
+++ /dev/null
-{
- "id": 2307,
- "key": "RuleWithTagsACE",
- "language": "xoo",
- "name": "Rule with tags taga, tagc and tage",
- "description": "This rule has tags 'taga', 'tagc' and 'tage'",
- "parentKey": null,
- "repositoryKey": "xoo",
- "severity": "INFO",
- "status": "READY",
- "systemTags": ["taga", "tagc"],
- "adminTags": ["tage"],
- "createdAt": "2013-12-04T10:24:09.000Z",
- "updatedAt": "2013-12-12T15:19:59.000Z"
-}
+++ /dev/null
-{
- "id": 2306,
- "key": "RuleWithTagsBC",
- "language": "xoo",
- "name": "Rule with tags tagb and tagc",
- "description": "This rule has tags 'tagb' and 'tagc'",
- "parentKey": null,
- "repositoryKey": "xoo",
- "severity": "INFO",
- "status": "READY",
- "systemTags": ["tagb", "tagc"],
- "createdAt": "2013-12-04T10:24:09.000Z",
- "updatedAt": "2013-12-12T15:19:59.000Z"
-}
+++ /dev/null
-{
- "id": 2303,
- "key": "RuleWithoutTags",
- "language": "xoo",
- "name": "Rule without tags",
- "description": "This rule has no tag",
- "parentKey": null,
- "repositoryKey": "xoo",
- "severity": "INFO",
- "status": "READY",
- "createdAt": "2013-12-04T10:24:09.000Z",
- "updatedAt": "2013-12-12T15:19:59.000Z"
-}
+++ /dev/null
-{
- "id": 25,
- "severity": "MINOR",
- "profileId": 1,
- "inheritance": "OVERRIDES"
-}
+++ /dev/null
-{
- "id": 2702,
- "severity": "CRITICAL",
- "profileId": 1,
- "inheritance": null,
- "params": [
- {
- "key": "fromClasses",
- "value": "**.core.**"
- },
- {
- "key": "toClasses",
- "value": "**.server.**"
- }
- ]
-}
+++ /dev/null
-{
- "id": 391,
- "severity": "MAJOR",
- "profileId": 1,
- "inheritance": "INHERITED"
-}
+++ /dev/null
-{
- "id": 523,
- "severity": "MAJOR",
- "profileId": 2,
- "inheritance": null
-}
+++ /dev/null
-{
- "id": 1482,
- "key": "ArchitecturalConstraint",
- "language": "java",
- "name": "Architectural constraint",
- "description": "<p>A source code comply to an architectural model when it fully\n\tadheres to a set of architectural constraints. A constraint allows to\n\tdeny references between classes by pattern.</p>\n<p>You can for instance use this rule to :</p>\n<ul>\n\t<li>forbid access to **.web.** from **.dao.** classes</li>\n\t<li>forbid access to java.util.Vector, java.util.Hashtable and\n\t\tjava.util.Enumeration from any classes</li>\n\t<li>forbid access to java.sql.** from **.ui.** and **.web.**\n\t\tclasses</li>\n</ul>",
- "parentKey": null,
- "repositoryKey": "squid",
- "severity": "MAJOR",
- "status": "READY",
- "createdAt": "2013-12-11T13:48:00.799Z",
- "updatedAt": "2013-12-13T17:26:35.767Z",
- "params": [
- {
- "key": "toClasses",
- "type": "STRING",
- "defaultValue": "",
- "description": "Mandatory. Ex : java.util.Vector, java.util.Hashtable, java.util.Enumeration"
- },
- {
- "key": "fromClasses",
- "type": "STRING",
- "defaultValue": "",
- "description": "Optional. If this property is not defined, all classes should adhere to this constraint. Ex : **.web.**"
- }
- ]
-}
+++ /dev/null
-{
- "id": 25,
- "key": "DM_CONVERT_CASE",
- "language": "java",
- "name": "Internationalization - Consider using Locale parameterized version of invoked method",
- "description": "<p> A String is being converted to upper or lowercase, using the platform's default encoding. This may\n result in improper conversions when used with international characters. Use the </p>\n <table><tr><td>String.toUpperCase( Locale l )</td></tr><tr><td>String.toLowerCase( Locale l )</td></tr></table>\n <p>versions instead.</p>",
- "parentKey": null,
- "repositoryKey": "findbugs",
- "severity": "INFO",
- "status": "READY",
- "createdAt": "2013-12-04T10:24:09.000Z",
- "updatedAt": "2013-12-12T15:19:59.000Z"
-}
+++ /dev/null
-{
- "id": 719,
- "key": "com.puppycrawl.tools.checkstyle.checks.coding.DoubleCheckedLockingCheck",
- "language": "java",
- "name": "Double Checked Locking",
- "description": null,
- "parentKey": null,
- "repositoryKey": "checkstyle",
- "severity": "MAJOR",
- "status": "READY",
- "cardinality": "SINGLE",
- "createdAt": "2013-07-04T07:38:05.543Z",
- "updatedAt": "2013-03-27T08:52:40.370Z"
-}
+++ /dev/null
-{
- "id": 759,
- "key": "UnusedNullCheckInEquals",
- "language": "java",
- "name": "Unused Null Check In Equals",
- "description": "After checking an object reference for null, you should invoke equals() on that object rather than passing it to another object's equals() method.",
- "parentKey": null,
- "repositoryKey": "pmd",
- "severity": "MAJOR",
- "status": "READY",
- "createdAt": "2013-12-04T10:24:11.000Z",
- "updatedAt": "2013-12-12T15:20:01.000Z"
-}
+++ /dev/null
-{
- "id": 860,
- "key": "Snippet",
- "language": null,
- "name": null,
- "description": null,
- "parentKey": null,
- "repositoryKey": "squid",
- "severity": "MAJOR",
- "status": "REMOVED",
- "cardinality": "MULTIPLE",
- "createdAt": "2013-07-04T07:38:05.543Z",
- "updatedAt": "2013-03-27T08:52:40.370Z"
-}
+++ /dev/null
-{
- "id": 944,
- "key": "S1125",
- "language": "java",
- "name": "Boolean expressions should not be compared to true or false",
- "description": "<p> Boolean expressions should not be compared against boolean literals, as their value can be directly used. </p> <p>The following code:</p> <pre> if (booleanVariable == true) { /* ... */ } // Non-Compliant if (booleanVariable != true) { /* ... */ } // Non-Compliant </pre> <p>should be refactored into:</p> <pre> if (booleanVariable) { /* ... */ } // Compliant if (!booleanVariable) { /* ... */ } // Compliant </pre>",
- "parentKey": null,
- "repositoryKey": "squid",
- "severity": "MAJOR",
- "status": "READY",
- "cardinality": "SINGLE",
- "createdAt": "2013-07-26T07:40:51.977Z",
- "updatedAt": "2014-01-10T15:38:27.386Z"
-}