*/
package org.sonar.batch.rule;
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import org.apache.commons.lang.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.sonar.api.batch.rule.ActiveRule;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.rule.internal.DefaultActiveRule;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.rules.RuleQuery;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
+/**
+ * FIXME Waiting for the list of all server rules on batch side this is implemented by redirecting on ActiveRules. This is not correct
+ * since there is a difference between a rule that doesn't exists and a rule that is not activated in project quality profile.
+ *
+ */
public class RuleFinderCompatibility implements RuleFinder {
private final ActiveRules activeRules;
@Override
public Rule findByKey(RuleKey key) {
- DefaultActiveRule ar = (DefaultActiveRule) activeRules.find(key);
- return ar == null ? null : Rule.create(key.repository(), key.rule()).setName(ar.name());
+ return toRule(activeRules.find(key));
}
@Override
public Rule find(RuleQuery query) {
- throw new UnsupportedOperationException("Unable to find rule by query");
+ Collection<Rule> all = findAll(query);
+ if (all.size() > 1) {
+ throw new IllegalArgumentException("Non unique result for rule query: " + ReflectionToStringBuilder.toString(query, ToStringStyle.SHORT_PREFIX_STYLE));
+ } else if (all.isEmpty()) {
+ return null;
+ } else {
+ return all.iterator().next();
+ }
}
@Override
public Collection<Rule> findAll(RuleQuery query) {
+ if (query.getConfigKey() != null) {
+ if (query.getRepositoryKey() != null && query.getKey() == null) {
+ return byInternalKey(query);
+ }
+ } else if (query.getRepositoryKey() != null) {
+ if (query.getKey() != null) {
+ return byKey(query);
+ } else {
+ return byRepository(query);
+ }
+ }
throw new UnsupportedOperationException("Unable to find rule by query");
}
+ private Collection<Rule> byRepository(RuleQuery query) {
+ return Collections2.transform(activeRules.findByRepository(query.getRepositoryKey()), new Function<ActiveRule, Rule>() {
+ @Override
+ public Rule apply(@Nonnull ActiveRule input) {
+ return toRule(input);
+ }
+ });
+ }
+
+ private Collection<Rule> byKey(RuleQuery query) {
+ Rule rule = toRule(activeRules.find(RuleKey.of(query.getRepositoryKey(), query.getKey())));
+ return rule != null ? Arrays.asList(rule) : Collections.<Rule>emptyList();
+ }
+
+ private Collection<Rule> byInternalKey(RuleQuery query) {
+ Rule rule = toRule(activeRules.findByInternalKey(query.getRepositoryKey(), query.getConfigKey()));
+ return rule != null ? Arrays.asList(rule) : Collections.<Rule>emptyList();
+ }
+
+ @CheckForNull
+ private Rule toRule(@Nullable ActiveRule rule) {
+ DefaultActiveRule ar = (DefaultActiveRule) rule;
+ return ar == null ? null : Rule.create(ar.ruleKey().repository(), ar.ruleKey().rule()).setName(ar.name()).setConfigKey(ar.internalKey()).setLanguage(ar.language());
+ }
+
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.batch.rule;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.batch.rule.ActiveRules;
+import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.RuleQuery;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class RuleFinderCompatibilityTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private ActiveRules activeRules = new ActiveRulesBuilder()
+ .create(RuleKey.of("repo1", "rule1"))
+ .activate()
+ .create(RuleKey.of("repo1", "rule2"))
+ .setInternalKey("rule2_internal")
+ .activate()
+ .create(RuleKey.of("repo2", "rule1"))
+ .activate()
+ .build();
+ private RuleFinderCompatibility ruleFinder;
+
+ @Before
+ public void prepare() {
+ ruleFinder = new RuleFinderCompatibility(activeRules);
+ }
+
+ @Test
+ public void testByInternalKey() {
+ assertThat(ruleFinder.find(RuleQuery.create().withRepositoryKey("repo1").withConfigKey("rule2_internal")).getKey()).isEqualTo("rule2");
+ assertThat(ruleFinder.find(RuleQuery.create().withRepositoryKey("repo1").withConfigKey("rule2_internal2"))).isNull();
+ }
+
+ @Test
+ public void testByKey() {
+ assertThat(ruleFinder.find(RuleQuery.create().withRepositoryKey("repo1").withKey("rule2")).getKey()).isEqualTo("rule2");
+ assertThat(ruleFinder.find(RuleQuery.create().withRepositoryKey("repo1").withKey("rule3"))).isNull();
+ assertThat(ruleFinder.findByKey("repo1", "rule2").getKey()).isEqualTo("rule2");
+ }
+
+ @Test
+ public void duplicateResult() {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Non unique result for rule query: RuleQuery[repositoryKey=repo1,key=<null>,configKey=<null>]");
+ ruleFinder.find(RuleQuery.create().withRepositoryKey("repo1"));
+ }
+
+ @Test
+ public void unsupportedById() {
+ thrown.expect(UnsupportedOperationException.class);
+ ruleFinder.findById(1);
+ }
+
+ @Test
+ public void unsupportedByInternalKeyWithoutRepo() {
+ thrown.expect(UnsupportedOperationException.class);
+ ruleFinder.find(RuleQuery.create().withConfigKey("config"));
+ }
+
+ @Test
+ public void unsupportedByKeyWithoutRepo() {
+ thrown.expect(UnsupportedOperationException.class);
+ ruleFinder.find(RuleQuery.create().withKey("key"));
+ }
+
+ @Test
+ public void unsupportedByKeyAndInternalKey() {
+ thrown.expect(UnsupportedOperationException.class);
+ ruleFinder.find(RuleQuery.create().withRepositoryKey("repo").withKey("key").withConfigKey("config"));
+ }
+
+ @Test
+ public void unsupportedByKeyAndInternalKeyWithoutRepo() {
+ thrown.expect(UnsupportedOperationException.class);
+ ruleFinder.find(RuleQuery.create().withKey("key").withConfigKey("config"));
+ }
+}