aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2014-01-27 21:21:12 +0100
committerSimon Brandhof <simon.brandhof@gmail.com>2014-01-27 21:21:36 +0100
commit5a6746e93985fd04c2667186b6826a320456a9ae (patch)
tree4f6a539dea313b438cf45f311e3fbf1ff940ac71
parent6420445cad9acb42bf465e008124abd3ffb7c0ae (diff)
downloadsonarqube-5a6746e93985fd04c2667186b6826a320456a9ae.tar.gz
sonarqube-5a6746e93985fd04c2667186b6826a320456a9ae.zip
SONAR-4908 add org.sonar.api.batch.rule.CheckFactory
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/rule/ModuleRulesProvider.java5
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/rule/ModuleRulesProviderTest.java1
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/CheckFactory.java38
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Checks.java189
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ModuleRule.java1
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultModuleRule.java8
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewModuleRule.java11
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/profiles/RulesProfile.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/rules/ActiveRule.java1
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitions.java20
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitionsFromXml.java6
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/AbstractCheck.java32
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckFactoryTest.java171
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithKey.java28
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithOverriddenPropertyKey.java35
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithPrimitiveProperties.java43
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithStringProperty.java36
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithUnsupportedPropertyType.java32
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithoutProperties.java29
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/ImplementedCheck.java28
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ModuleRulesBuilderTest.java11
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest.java2
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsTest.java6
-rw-r--r--sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRuleDefinitions.java2
-rw-r--r--sonar-server/src/main/java/org/sonar/server/rule/RuleRegistration.java6
-rw-r--r--sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRuleDefinitionsTest.java2
-rw-r--r--sonar-server/src/test/java/org/sonar/server/rule/RuleRegistrationTest.java4
28 files changed, 721 insertions, 30 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleRulesProvider.java b/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleRulesProvider.java
index ef4ec47ed0d..86b66314599 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleRulesProvider.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleRulesProvider.java
@@ -59,6 +59,11 @@ public class ModuleRulesProvider extends ProviderAdapter {
if (rule != null) {
NewModuleRule newModuleRule = builder.activate(rule.ruleKey());
newModuleRule.setSeverity(activeDto.getSeverityString());
+ if (rule.getParent() != null) {
+ newModuleRule.setEngineKey(rule.getParent().getConfigKey());
+ } else {
+ newModuleRule.setEngineKey(rule.getConfigKey());
+ }
for (ActiveRuleParamDto paramDto : paramDtosByActiveRuleId.get(activeDto.getId())) {
newModuleRule.setParam(paramDto.getKey(), paramDto.getValue());
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
index 56659948df0..fde6e9c3ec7 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
@@ -24,6 +24,7 @@ import org.slf4j.LoggerFactory;
import org.sonar.api.BatchExtension;
import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.rule.CheckFactory;
import org.sonar.api.platform.ComponentContainer;
import org.sonar.api.resources.Languages;
import org.sonar.api.resources.Project;
@@ -124,6 +125,7 @@ public class ModuleScanContainer extends ComponentContainer {
new ModuleRulesProvider(),
new RulesProfileProvider(),
QProfileSensor.class,
+ CheckFactory.class,
// report
JsonReport.class,
diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/ModuleRulesProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/ModuleRulesProviderTest.java
index 5d1fdcfc8d5..56775acc508 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/rule/ModuleRulesProviderTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/rule/ModuleRulesProviderTest.java
@@ -68,6 +68,7 @@ public class ModuleRulesProviderTest extends AbstractDaoTestCase {
assertThat(moduleRules.findByRepository("unknown")).isEmpty();
ModuleRule squidRule = moduleRules.find(RuleKey.of("squid", "S0001"));
assertThat(squidRule.severity()).isEqualTo(Severity.INFO);
+ assertThat(squidRule.engineKey()).isNull();
assertThat(squidRule.params()).hasSize(2);
assertThat(squidRule.param("max")).isEqualTo("20");
assertThat(squidRule.param("format")).isEqualTo("html");
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/CheckFactory.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/CheckFactory.java
new file mode 100644
index 00000000000..69e8df67191
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/CheckFactory.java
@@ -0,0 +1,38 @@
+/*
+ * 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.api.batch.rule;
+
+import org.sonar.api.BatchComponent;
+
+/**
+ * @since 4.2
+ */
+public class CheckFactory implements BatchComponent {
+
+ private final ModuleRules moduleRules;
+
+ public CheckFactory(ModuleRules moduleRules) {
+ this.moduleRules = moduleRules;
+ }
+
+ public Checks create(String repository) {
+ return new Checks(moduleRules, repository);
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Checks.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Checks.java
new file mode 100644
index 00000000000..7c8bbc8f14d
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Checks.java
@@ -0,0 +1,189 @@
+/*
+ * 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.api.batch.rule;
+
+import com.google.common.collect.Maps;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.utils.AnnotationUtils;
+import org.sonar.api.utils.FieldUtils2;
+import org.sonar.api.utils.SonarException;
+import org.sonar.check.RuleProperty;
+
+import javax.annotation.CheckForNull;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @since 4.2
+ */
+public class Checks<C> {
+ private final ModuleRules moduleRules;
+ private final String repository;
+ private final Map<RuleKey, C> checkByRule = Maps.newHashMap();
+ private final Map<C, RuleKey> ruleByCheck = Maps.newIdentityHashMap();
+
+ Checks(ModuleRules moduleRules, String repository) {
+ this.moduleRules = moduleRules;
+ this.repository = repository;
+ }
+
+ @CheckForNull
+ public C of(RuleKey ruleKey) {
+ return checkByRule.get(ruleKey);
+ }
+
+ public Collection<C> all() {
+ return checkByRule.values();
+ }
+
+ @CheckForNull
+ public RuleKey ruleKey(C check) {
+ return ruleByCheck.get(check);
+ }
+
+ private void add(RuleKey ruleKey, C obj) {
+ checkByRule.put(ruleKey, obj);
+ ruleByCheck.put(obj, ruleKey);
+ }
+
+ public Checks<C> addAnnotatedChecks(Object... checkClassesOrObjects) {
+ return addAnnotatedChecks(Arrays.asList(checkClassesOrObjects));
+ }
+
+ public Checks<C> addAnnotatedChecks(Collection checkClassesOrObjects) {
+ Map<String, Object> checksByEngineKey = Maps.newHashMap();
+ for (Object checkClassesOrObject : checkClassesOrObjects) {
+ String engineKey = annotatedEngineKey(checkClassesOrObject);
+ if (engineKey != null) {
+ checksByEngineKey.put(engineKey, checkClassesOrObject);
+ }
+ }
+
+ for (ModuleRule moduleRule : moduleRules.findByRepository(repository)) {
+ String engineKey = StringUtils.defaultIfBlank(moduleRule.engineKey(), moduleRule.ruleKey().rule());
+ Object checkClassesOrObject = checksByEngineKey.get(engineKey);
+ Object obj = instantiate(moduleRule, checkClassesOrObject);
+ add(moduleRule.ruleKey(), (C) obj);
+ }
+ return this;
+ }
+
+ private String annotatedEngineKey(Object annotatedClassOrObject) {
+ String key = null;
+ org.sonar.check.Rule ruleAnnotation = AnnotationUtils.getAnnotation(annotatedClassOrObject, org.sonar.check.Rule.class);
+ if (ruleAnnotation != null) {
+ key = ruleAnnotation.key();
+ }
+ Class clazz = annotatedClassOrObject.getClass();
+ if (annotatedClassOrObject instanceof Class) {
+ clazz = (Class) annotatedClassOrObject;
+ }
+ return StringUtils.defaultIfEmpty(key, clazz.getCanonicalName());
+ }
+
+ private Object instantiate(ModuleRule moduleRule, Object checkClassOrInstance) {
+ try {
+ Object check = checkClassOrInstance;
+ if (check instanceof Class) {
+ check = ((Class) checkClassOrInstance).newInstance();
+ }
+ configureFields(moduleRule, check);
+ return check;
+
+ } catch (ReflectiveOperationException e) {
+ throw new IllegalStateException(String.format("Fail to instantiate class %s for rule %s", checkClassOrInstance, moduleRule.ruleKey()), e);
+ }
+ }
+
+ private void configureFields(ModuleRule moduleRule, Object check) {
+ for (Map.Entry<String, String> param : moduleRule.params().entrySet()) {
+ Field field = getField(check, param.getKey());
+ if (field == null) {
+ throw new IllegalStateException(
+ String.format("The field '%s' does not exist or is not annotated with @RuleProperty in the class %s", param.getKey(), check.getClass().getName())
+ );
+ }
+ if (StringUtils.isNotBlank(param.getValue())) {
+ configureField(check, field, param.getValue());
+ }
+ }
+ }
+
+ @CheckForNull
+ private Field getField(Object check, String key) {
+ List<Field> fields = FieldUtils2.getFields(check.getClass(), true);
+ for (Field field : fields) {
+ RuleProperty propertyAnnotation = field.getAnnotation(RuleProperty.class);
+ if (propertyAnnotation != null && (StringUtils.equals(key, field.getName()) || StringUtils.equals(key, propertyAnnotation.key()))) {
+ return field;
+ }
+ }
+ return null;
+ }
+
+ private void configureField(Object check, Field field, String value) {
+ try {
+ field.setAccessible(true);
+
+ if (field.getType().equals(String.class)) {
+ field.set(check, value);
+
+ } else if ("int".equals(field.getType().getSimpleName())) {
+ field.setInt(check, Integer.parseInt(value));
+
+ } else if ("short".equals(field.getType().getSimpleName())) {
+ field.setShort(check, Short.parseShort(value));
+
+ } else if ("long".equals(field.getType().getSimpleName())) {
+ field.setLong(check, Long.parseLong(value));
+
+ } else if ("double".equals(field.getType().getSimpleName())) {
+ field.setDouble(check, Double.parseDouble(value));
+
+ } else if ("boolean".equals(field.getType().getSimpleName())) {
+ field.setBoolean(check, Boolean.parseBoolean(value));
+
+ } else if ("byte".equals(field.getType().getSimpleName())) {
+ field.setByte(check, Byte.parseByte(value));
+
+ } else if (field.getType().equals(Integer.class)) {
+ field.set(check, Integer.parseInt(value));
+
+ } else if (field.getType().equals(Long.class)) {
+ field.set(check, Long.parseLong(value));
+
+ } else if (field.getType().equals(Double.class)) {
+ field.set(check, Double.parseDouble(value));
+
+ } else if (field.getType().equals(Boolean.class)) {
+ field.set(check, Boolean.parseBoolean(value));
+
+ } else {
+ throw new SonarException("The type of the field " + field + " is not supported: " + field.getType());
+ }
+ } catch (IllegalAccessException e) {
+ throw new SonarException("Can not set the value of the field " + field + " in the class: " + check.getClass().getName(), e);
+ }
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ModuleRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ModuleRule.java
index 7bf93d9e8b8..110c4002acb 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ModuleRule.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ModuleRule.java
@@ -38,4 +38,5 @@ public interface ModuleRule {
Map<String, String> params();
+ String engineKey();
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultModuleRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultModuleRule.java
index 4165ce1e7c4..49757a1e332 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultModuleRule.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultModuleRule.java
@@ -29,11 +29,12 @@ import java.util.Map;
@Immutable
class DefaultModuleRule implements ModuleRule {
private final RuleKey ruleKey;
- private final String severity;
+ private final String severity, engineKey;
private final Map<String, String> params;
DefaultModuleRule(NewModuleRule newModuleRule) {
this.severity = newModuleRule.severity;
+ this.engineKey = newModuleRule.engineKey;
this.ruleKey = newModuleRule.ruleKey;
this.params = ImmutableMap.copyOf(newModuleRule.params);
}
@@ -58,4 +59,9 @@ class DefaultModuleRule implements ModuleRule {
// immutable
return params;
}
+
+ @Override
+ public String engineKey() {
+ return engineKey;
+ }
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewModuleRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewModuleRule.java
index 2cfecd7c9af..b79c6bc91ff 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewModuleRule.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewModuleRule.java
@@ -19,6 +19,7 @@
*/
package org.sonar.api.batch.rule.internal;
+import org.apache.commons.lang.StringUtils;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
@@ -30,13 +31,19 @@ public class NewModuleRule {
final RuleKey ruleKey;
String severity = Severity.defaultSeverity();
Map<String, String> params = new HashMap<String, String>();
+ String engineKey;
NewModuleRule(RuleKey ruleKey) {
this.ruleKey = ruleKey;
}
- public NewModuleRule setSeverity(String severity) {
- this.severity = severity;
+ public NewModuleRule setSeverity(@Nullable String severity) {
+ this.severity = StringUtils.defaultIfBlank(severity, Severity.defaultSeverity());
+ return this;
+ }
+
+ public NewModuleRule setEngineKey(@Nullable String engineKey) {
+ this.engineKey = engineKey;
return this;
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/RulesProfile.java b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/RulesProfile.java
index b7e23152096..62263668299 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/RulesProfile.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/RulesProfile.java
@@ -36,9 +36,11 @@ import java.util.List;
/**
* This class is badly named. It should be "QualityProfile". Indeed it does not relate only to rules but to metric thresholds too.
+ * @deprecated since 4.2. Replaced by {@link org.sonar.api.batch.rule.ModuleRules} for batch extensions.
*/
@Entity
@Table(name = "rules_profiles")
+@Deprecated
public class RulesProfile implements Cloneable {
/**
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rules/ActiveRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/rules/ActiveRule.java
index 55772eac07d..5c21e31b788 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/rules/ActiveRule.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/rules/ActiveRule.java
@@ -36,6 +36,7 @@ import java.util.List;
*/
@Entity
@Table(name = "active_rules")
+@Deprecated
public class ActiveRule implements Cloneable {
public static final String INHERITED = "INHERITED";
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitions.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitions.java
index 7243ffe3292..42b17cee731 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitions.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitions.java
@@ -23,8 +23,8 @@ import com.google.common.collect.*;
import org.apache.commons.lang.StringUtils;
import org.slf4j.LoggerFactory;
import org.sonar.api.ServerExtension;
-import org.sonar.api.rule.Severity;
import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rule.Severity;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
@@ -282,7 +282,7 @@ public interface RuleDefinitions extends ServerExtension {
class NewRule {
private final String repoKey, key;
- private String name, htmlDescription, metadata, severity = Severity.MAJOR;
+ private String name, htmlDescription, engineKey, severity = Severity.MAJOR;
private boolean template;
private RuleStatus status = RuleStatus.defaultStatus();
private final Set<String> tags = Sets.newTreeSet();
@@ -355,12 +355,12 @@ public interface RuleDefinitions extends ServerExtension {
}
/**
- * Optional metadata that can be used by the rule engine. Not displayed
+ * Optional key that can be used by the rule engine. Not displayed
* in webapp. For example the Java Checkstyle plugin feeds this field
* with the internal path ("Checker/TreeWalker/AnnotationUseStyle").
*/
- public NewRule setMetadata(@Nullable String s) {
- this.metadata = s;
+ public NewRule setEngineKey(@Nullable String s) {
+ this.engineKey = s;
return this;
}
@@ -382,7 +382,7 @@ public interface RuleDefinitions extends ServerExtension {
@Immutable
class Rule {
private final Repository repository;
- private final String repoKey, key, name, htmlDescription, metadata, severity;
+ private final String repoKey, key, name, htmlDescription, engineKey, severity;
private final boolean template;
private final Set<String> tags;
private final Map<String, Param> params;
@@ -394,7 +394,7 @@ public interface RuleDefinitions extends ServerExtension {
this.key = newRule.key;
this.name = newRule.name;
this.htmlDescription = newRule.htmlDescription;
- this.metadata = newRule.metadata;
+ this.engineKey = newRule.engineKey;
this.severity = newRule.severity;
this.template = newRule.template;
this.status = newRule.status;
@@ -449,11 +449,11 @@ public interface RuleDefinitions extends ServerExtension {
}
/**
- * @see RuleDefinitions.NewRule#setMetadata(String)
+ * @see RuleDefinitions.NewRule#setEngineKey(String)
*/
@CheckForNull
- public String metadata() {
- return metadata;
+ public String engineKey() {
+ return engineKey;
}
@Override
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitionsFromXml.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitionsFromXml.java
index 7506b9ca6be..e1be54f648f 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitionsFromXml.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitionsFromXml.java
@@ -80,7 +80,7 @@ class RuleDefinitionsFromXml {
}
private void processRule(RuleDefinitions.NewRepository repo, SMInputCursor ruleC) throws XMLStreamException {
- String key = null, name = null, description = null, metadata = null, severity = Severity.defaultSeverity(), status = null;
+ String key = null, name = null, description = null, engineKey = null, severity = Severity.defaultSeverity(), status = null;
Cardinality cardinality = Cardinality.SINGLE;
List<ParamStruct> params = new ArrayList<ParamStruct>();
@@ -108,7 +108,7 @@ class RuleDefinitionsFromXml {
key = StringUtils.trim(cursor.collectDescendantText(false));
} else if (StringUtils.equalsIgnoreCase("configKey", nodeName)) {
- metadata = StringUtils.trim(cursor.collectDescendantText(false));
+ engineKey = StringUtils.trim(cursor.collectDescendantText(false));
} else if (StringUtils.equalsIgnoreCase("priority", nodeName)) {
// deprecated field, replaced by severity
@@ -131,7 +131,7 @@ class RuleDefinitionsFromXml {
.setHtmlDescription(description)
.setSeverity(severity)
.setName(name)
- .setMetadata(metadata)
+ .setEngineKey(engineKey)
.setTemplate(cardinality == Cardinality.MULTIPLE);
if (status != null) {
rule.setStatus(RuleStatus.valueOf(status));
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/AbstractCheck.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/AbstractCheck.java
new file mode 100644
index 00000000000..7263d679697
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/AbstractCheck.java
@@ -0,0 +1,32 @@
+/*
+ * 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.api.batch.rule;
+
+import org.sonar.check.RuleProperty;
+
+public abstract class AbstractCheck {
+
+ @RuleProperty
+ private Integer max;
+
+ public Integer getMax() {
+ return max;
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckFactoryTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckFactoryTest.java
new file mode 100644
index 00000000000..089ad60f722
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckFactoryTest.java
@@ -0,0 +1,171 @@
+/*
+ * 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.api.batch.rule;
+
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.batch.rule.internal.ModuleRulesBuilder;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.utils.SonarException;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class CheckFactoryTest {
+
+ @org.junit.Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ ModuleRulesBuilder builder = new ModuleRulesBuilder();
+
+ @Test
+ public void no_checks_are_enabled() {
+ CheckFactory checkFactory = new CheckFactory(builder.build());
+
+ Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithoutProperties.class);
+
+ assertThat(checks.all()).isEmpty();
+ }
+
+ @Test
+ public void class_name_as_check_key() {
+ RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithoutProperties");
+ builder.activate(ruleKey);
+ CheckFactory checkFactory = new CheckFactory(builder.build());
+
+ Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithoutProperties.class);
+
+ Object check = checks.of(ruleKey);
+ assertThat(check).isInstanceOf(CheckWithoutProperties.class);
+ assertThat(checks.all()).containsOnly(check);
+ assertThat(checks.ruleKey(check)).isEqualTo(ruleKey);
+ }
+
+ @Test
+ public void param_as_string_field() {
+ RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithStringProperty");
+ builder.activate(ruleKey).setParam("pattern", "foo");
+
+ CheckFactory checkFactory = new CheckFactory(builder.build());
+ Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithStringProperty.class);
+
+ Object check = checks.of(ruleKey);
+ assertThat(check).isInstanceOf(CheckWithStringProperty.class);
+
+ assertThat(((CheckWithStringProperty) check).getPattern()).isEqualTo("foo");
+ }
+
+ @Test
+ public void fail_if_missing_field() {
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("The field 'unknown' does not exist or is not annotated with @RuleProperty in the class org.sonar.api.batch.rule.CheckWithStringProperty");
+
+ RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithStringProperty");
+ builder.activate(ruleKey).setParam("unknown", "foo");
+
+ CheckFactory checkFactory = new CheckFactory(builder.build());
+ checkFactory.create("squid").addAnnotatedChecks(CheckWithStringProperty.class);
+ }
+
+ @Test
+ public void param_as_primitive_fields() {
+ RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithPrimitiveProperties");
+ builder.activate(ruleKey).setParam("max", "300").setParam("ignore", "true");
+
+ CheckFactory checkFactory = new CheckFactory(builder.build());
+ Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithPrimitiveProperties.class);
+
+ Object check = checks.of(ruleKey);
+ assertThat(check).isInstanceOf(CheckWithPrimitiveProperties.class);
+ assertThat(((CheckWithPrimitiveProperties) check).getMax()).isEqualTo(300);
+ assertThat(((CheckWithPrimitiveProperties) check).isIgnore()).isTrue();
+ }
+
+ /**
+ * SONAR-3164
+ */
+ @Test
+ public void param_as_inherited_field() {
+ RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithPrimitiveProperties");
+ builder.activate(ruleKey).setParam("max", "300");
+
+ CheckFactory checkFactory = new CheckFactory(builder.build());
+ Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithPrimitiveProperties.class);
+
+ Object check = checks.of(ruleKey);
+ assertThat(check).isInstanceOf(CheckWithPrimitiveProperties.class);
+ assertThat(((CheckWithPrimitiveProperties) check).getMax()).isEqualTo(300);
+ }
+
+ @Test
+ public void use_engine_key() {
+ RuleKey ruleKey = RuleKey.of("squid", "One");
+ builder.activate(ruleKey).setEngineKey("S0001");
+
+ CheckFactory checkFactory = new CheckFactory(builder.build());
+ Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithKey.class);
+
+ Object check = checks.of(ruleKey);
+ assertThat(check).isInstanceOf(CheckWithKey.class);
+ assertThat(checks.of(ruleKey)).isSameAs(check);
+ assertThat(checks.ruleKey(check)).isEqualTo(ruleKey);
+ assertThat(checks.all()).containsOnly(check);
+ }
+
+ @Test
+ public void fail_if_field_type_is_not_supported() {
+ thrown.expect(SonarException.class);
+
+ RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithUnsupportedPropertyType");
+ builder.activate(ruleKey).setParam("max", "300");
+
+ CheckFactory checkFactory = new CheckFactory(builder.build());
+ checkFactory.create("squid").addAnnotatedChecks(CheckWithUnsupportedPropertyType.class);
+ }
+
+ @Test
+ public void override_field_key() {
+ RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithOverriddenPropertyKey");
+ builder.activate(ruleKey).setParam("maximum", "300");
+
+ CheckFactory checkFactory = new CheckFactory(builder.build());
+ Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithOverriddenPropertyKey.class);
+
+ Object check = checks.of(ruleKey);
+ assertThat(check).isInstanceOf(CheckWithOverriddenPropertyKey.class);
+ assertThat(((CheckWithOverriddenPropertyKey) check).getMax()).isEqualTo(300);
+ }
+
+ /**
+ * SONAR-2900
+ */
+ @Test
+ public void checks_as_objects() {
+ RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithStringProperty");
+ builder.activate(ruleKey).setParam("pattern", "foo");
+ CheckFactory checkFactory = new CheckFactory(builder.build());
+
+ CheckWithStringProperty check = new CheckWithStringProperty();
+ Checks checks = checkFactory.create("squid").addAnnotatedChecks(check);
+
+ Object createdCheck = checks.of(ruleKey);
+ assertThat(createdCheck).isSameAs(check);
+ assertThat(((CheckWithStringProperty) createdCheck).getPattern()).isEqualTo("foo");
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithKey.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithKey.java
new file mode 100644
index 00000000000..68891480b04
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithKey.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.batch.rule;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+
+@Rule(key = "S0001", priority = Priority.CRITICAL)
+public class CheckWithKey {
+
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithOverriddenPropertyKey.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithOverriddenPropertyKey.java
new file mode 100644
index 00000000000..260db29407b
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithOverriddenPropertyKey.java
@@ -0,0 +1,35 @@
+/*
+ * 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.api.batch.rule;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+
+@Rule(priority = Priority.CRITICAL)
+public class CheckWithOverriddenPropertyKey{
+
+ @RuleProperty(key = "maximum")
+ private int max = 50;
+
+ public int getMax() {
+ return max;
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithPrimitiveProperties.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithPrimitiveProperties.java
new file mode 100644
index 00000000000..b39f4219a23
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithPrimitiveProperties.java
@@ -0,0 +1,43 @@
+/*
+ * 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.api.batch.rule;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+
+@Rule(priority = Priority.CRITICAL)
+public class CheckWithPrimitiveProperties {
+
+ @RuleProperty(description = "Maximum threshold")
+ private int max = 50;
+
+ @RuleProperty
+ private boolean ignore;
+
+ public int getMax() {
+ return max;
+ }
+
+ public boolean isIgnore() {
+ return ignore;
+ }
+}
+
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithStringProperty.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithStringProperty.java
new file mode 100644
index 00000000000..0d0596c390c
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithStringProperty.java
@@ -0,0 +1,36 @@
+/*
+ * 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.api.batch.rule;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+
+@Rule(priority = Priority.CRITICAL)
+public class CheckWithStringProperty {
+
+ @RuleProperty
+ private String pattern;
+
+ public String getPattern() {
+ return pattern;
+ }
+}
+
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithUnsupportedPropertyType.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithUnsupportedPropertyType.java
new file mode 100644
index 00000000000..407388e2a1a
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithUnsupportedPropertyType.java
@@ -0,0 +1,32 @@
+/*
+ * 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.api.batch.rule;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+
+@Rule(priority = Priority.CRITICAL)
+class CheckWithUnsupportedPropertyType {
+
+ @RuleProperty
+ private StringBuilder max = null;
+
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithoutProperties.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithoutProperties.java
new file mode 100644
index 00000000000..f8bcf4ff2c7
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckWithoutProperties.java
@@ -0,0 +1,29 @@
+/*
+ * 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.api.batch.rule;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+
+@Rule(priority = Priority.CRITICAL)
+public class CheckWithoutProperties {
+
+}
+
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/ImplementedCheck.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/ImplementedCheck.java
new file mode 100644
index 00000000000..cd6d422a9f4
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/ImplementedCheck.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.batch.rule;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+
+@Rule(priority = Priority.CRITICAL)
+public class ImplementedCheck extends AbstractCheck {
+
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ModuleRulesBuilderTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ModuleRulesBuilderTest.java
index 19b796db350..4a9ec9bf7de 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ModuleRulesBuilderTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ModuleRulesBuilderTest.java
@@ -22,8 +22,6 @@ package org.sonar.api.batch.rule.internal;
import org.junit.Test;
import org.sonar.api.batch.rule.ModuleRule;
import org.sonar.api.batch.rule.ModuleRules;
-import org.sonar.api.batch.rule.Rule;
-import org.sonar.api.batch.rule.Rules;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
@@ -43,10 +41,11 @@ public class ModuleRulesBuilderTest {
ModuleRulesBuilder builder = new ModuleRulesBuilder();
NewModuleRule newSquid1 = builder.activate(RuleKey.of("squid", "S0001"));
newSquid1.setSeverity(Severity.CRITICAL);
+ newSquid1.setEngineKey("__S0001__");
newSquid1.setParam("min", "20");
// most simple rule
builder.activate(RuleKey.of("squid", "S0002"));
- builder.activate(RuleKey.of("findbugs", "NPE"));
+ builder.activate(RuleKey.of("findbugs", "NPE")).setEngineKey(null).setSeverity(null).setParam("foo", null);
ModuleRules moduleRules = builder.build();
@@ -59,6 +58,7 @@ public class ModuleRulesBuilderTest {
assertThat(squid1.ruleKey().repository()).isEqualTo("squid");
assertThat(squid1.ruleKey().rule()).isEqualTo("S0001");
assertThat(squid1.severity()).isEqualTo(Severity.CRITICAL);
+ assertThat(squid1.engineKey()).isEqualTo("__S0001__");
assertThat(squid1.params()).hasSize(1);
assertThat(squid1.param("min")).isEqualTo("20");
@@ -67,6 +67,11 @@ public class ModuleRulesBuilderTest {
assertThat(squid2.ruleKey().rule()).isEqualTo("S0002");
assertThat(squid2.severity()).isEqualTo(Severity.defaultSeverity());
assertThat(squid2.params()).isEmpty();
+
+ ModuleRule findbugsRule = moduleRules.find(RuleKey.of("findbugs", "NPE"));
+ assertThat(findbugsRule.severity()).isEqualTo(Severity.defaultSeverity());
+ assertThat(findbugsRule.engineKey()).isNull();
+ assertThat(findbugsRule.params()).isEmpty();
}
@Test
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest.java
index a66cb03cc04..0bf2bbd5061 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest.java
@@ -58,7 +58,7 @@ public class RuleDefinitionsFromXmlTest {
assertThat(rule.severity()).isEqualTo(Severity.BLOCKER);
assertThat(rule.template()).isTrue();
assertThat(rule.status()).isEqualTo(RuleStatus.BETA);
- assertThat(rule.metadata()).isEqualTo("Checker/TreeWalker/LocalVariableName");
+ assertThat(rule.engineKey()).isEqualTo("Checker/TreeWalker/LocalVariableName");
assertThat(rule.params()).hasSize(2);
RuleDefinitions.Param ignore = rule.param("ignore");
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsTest.java
index d3fdbf513ab..463ee4bac1b 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleDefinitionsTest.java
@@ -67,7 +67,7 @@ public class RuleDefinitionsTest {
.setHtmlDescription("Detect <code>NPE</code>")
.setHtmlDescription("Detect <code>java.lang.NullPointerException</code>")
.setSeverity(Severity.BLOCKER)
- .setMetadata("/something")
+ .setEngineKey("/something")
.setStatus(RuleStatus.BETA)
.setTags("one", "two")
.addTags("two", "three", "four");
@@ -84,7 +84,7 @@ public class RuleDefinitionsTest {
assertThat(npeRule.htmlDescription()).isEqualTo("Detect <code>java.lang.NullPointerException</code>");
assertThat(npeRule.tags()).containsOnly("one", "two", "three", "four");
assertThat(npeRule.params()).isEmpty();
- assertThat(npeRule.metadata()).isEqualTo("/something");
+ assertThat(npeRule.engineKey()).isEqualTo("/something");
assertThat(npeRule.template()).isFalse();
assertThat(npeRule.status()).isEqualTo(RuleStatus.BETA);
assertThat(npeRule.toString()).isEqualTo("[repository=findbugs, key=NPE]");
@@ -106,7 +106,7 @@ public class RuleDefinitionsTest {
assertThat(rule.key()).isEqualTo("NPE");
assertThat(rule.severity()).isEqualTo(Severity.MAJOR);
assertThat(rule.params()).isEmpty();
- assertThat(rule.metadata()).isNull();
+ assertThat(rule.engineKey()).isNull();
assertThat(rule.status()).isEqualTo(RuleStatus.defaultStatus());
assertThat(rule.tags()).isEmpty();
}
diff --git a/sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRuleDefinitions.java b/sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRuleDefinitions.java
index 98233f7b758..c646497d90b 100644
--- a/sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRuleDefinitions.java
+++ b/sonar-server/src/main/java/org/sonar/server/rule/DeprecatedRuleDefinitions.java
@@ -63,7 +63,7 @@ public class DeprecatedRuleDefinitions implements RuleDefinitions {
NewRule newRule = newRepository.newRule(rule.getKey());
newRule.setName(ruleName(repository.getKey(), rule));
newRule.setHtmlDescription(ruleDescription(repository.getKey(), rule));
- newRule.setMetadata(rule.getConfigKey());
+ newRule.setEngineKey(rule.getConfigKey());
newRule.setTemplate(Cardinality.MULTIPLE.equals(rule.getCardinality()));
newRule.setSeverity(rule.getSeverity().toString());
newRule.setStatus(rule.getStatus() == null ? RuleStatus.defaultStatus() : RuleStatus.valueOf(rule.getStatus()));
diff --git a/sonar-server/src/main/java/org/sonar/server/rule/RuleRegistration.java b/sonar-server/src/main/java/org/sonar/server/rule/RuleRegistration.java
index cac30bd83a4..938ddfb90da 100644
--- a/sonar-server/src/main/java/org/sonar/server/rule/RuleRegistration.java
+++ b/sonar-server/src/main/java/org/sonar/server/rule/RuleRegistration.java
@@ -149,7 +149,7 @@ public class RuleRegistration implements Startable {
private RuleDto enableAndInsert(Buffer buffer, SqlSession sqlSession, RuleDefinitions.Rule ruleDef) {
RuleDto ruleDto = new RuleDto()
.setCardinality(ruleDef.template() ? Cardinality.MULTIPLE : Cardinality.SINGLE)
- .setConfigKey(ruleDef.metadata())
+ .setConfigKey(ruleDef.engineKey())
.setDescription(ruleDef.htmlDescription())
.setLanguage(ruleDef.repository().language())
.setName(ruleDef.name())
@@ -195,8 +195,8 @@ public class RuleRegistration implements Startable {
dto.setDescription(def.htmlDescription());
changed = true;
}
- if (!StringUtils.equals(dto.getConfigKey(), def.metadata())) {
- dto.setConfigKey(def.metadata());
+ if (!StringUtils.equals(dto.getConfigKey(), def.engineKey())) {
+ dto.setConfigKey(def.engineKey());
changed = true;
}
String severity = RulePriority.valueOf(def.severity()).name();
diff --git a/sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRuleDefinitionsTest.java b/sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRuleDefinitionsTest.java
index 892fe0675e2..7da084cfcbf 100644
--- a/sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRuleDefinitionsTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/rule/DeprecatedRuleDefinitionsTest.java
@@ -75,7 +75,7 @@ public class DeprecatedRuleDefinitionsTest {
assertThat(rule.name()).isEqualTo("Constant Name");
assertThat(rule.htmlDescription()).isEqualTo("Checks that constant names conform to the specified format");
assertThat(rule.severity()).isEqualTo(Severity.BLOCKER);
- assertThat(rule.metadata()).isEqualTo("Checker/TreeWalker/ConstantName");
+ assertThat(rule.engineKey()).isEqualTo("Checker/TreeWalker/ConstantName");
assertThat(rule.status()).isEqualTo(RuleStatus.BETA);
assertThat(rule.tags()).isEmpty();
assertThat(rule.params()).hasSize(1);
diff --git a/sonar-server/src/test/java/org/sonar/server/rule/RuleRegistrationTest.java b/sonar-server/src/test/java/org/sonar/server/rule/RuleRegistrationTest.java
index 4a95a47dd82..1613c31d655 100644
--- a/sonar-server/src/test/java/org/sonar/server/rule/RuleRegistrationTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/rule/RuleRegistrationTest.java
@@ -204,7 +204,7 @@ public class RuleRegistrationTest extends AbstractDaoTestCase {
.setName("One")
.setHtmlDescription("Description of One")
.setSeverity(Severity.BLOCKER)
- .setMetadata("config1")
+ .setEngineKey("config1")
.setTags("tag1", "tag3", "tag5");
rule1.newParam("param1").setDescription("parameter one").setDefaultValue("default value one");
rule1.newParam("param2").setDescription("parameter two").setDefaultValue("default value two");
@@ -229,7 +229,7 @@ public class RuleRegistrationTest extends AbstractDaoTestCase {
.setName("name of " + i)
.setHtmlDescription("description of " + i)
.setSeverity(Severity.BLOCKER)
- .setMetadata("config1")
+ .setEngineKey("config1")
.setTags("tag1", "tag3", "tag5");
for (int j = 0; j < 20; j++) {
rule.newParam("param" + j);