--- /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.api.rules;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.PropertyType;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.utils.AnnotationUtils;
+import org.sonar.api.utils.FieldUtils2;
+import org.sonar.api.utils.SonarException;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @since 2.3
+ * @deprecated in 4.2. Replaced by org.sonar.api.rule.RuleDefinitions#loadAnnotatedClasses()
+ */
+@Deprecated
+public final class AnnotationRuleParser implements ServerComponent {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AnnotationRuleParser.class);
+
+ public List<Rule> parse(String repositoryKey, Collection<Class> annotatedClasses) {
+ List<Rule> rules = Lists.newArrayList();
+ for (Class annotatedClass : annotatedClasses) {
+ rules.add(create(repositoryKey, annotatedClass));
+ }
+ return rules;
+ }
+
+ private Rule create(String repositoryKey, Class annotatedClass) {
+ org.sonar.check.Rule ruleAnnotation = AnnotationUtils.getAnnotation(annotatedClass, org.sonar.check.Rule.class);
+ if (ruleAnnotation != null) {
+ return toRule(repositoryKey, annotatedClass, ruleAnnotation);
+ }
+ LOG.warn("The class " + annotatedClass.getCanonicalName() + " should be annotated with " + Rule.class);
+ return null;
+ }
+
+ private Rule toRule(String repositoryKey, Class clazz, org.sonar.check.Rule ruleAnnotation) {
+ String ruleKey = StringUtils.defaultIfEmpty(ruleAnnotation.key(), clazz.getCanonicalName());
+ String ruleName = StringUtils.defaultIfEmpty(ruleAnnotation.name(), null);
+ String description = StringUtils.defaultIfEmpty(ruleAnnotation.description(), null);
+ Rule rule = Rule.create(repositoryKey, ruleKey, ruleName);
+ rule.setDescription(description);
+ rule.setSeverity(RulePriority.fromCheckPriority(ruleAnnotation.priority()));
+ rule.setCardinality(ruleAnnotation.cardinality());
+ rule.setStatus(ruleAnnotation.status());
+
+ List<Field> fields = FieldUtils2.getFields(clazz, true);
+ for (Field field : fields) {
+ addRuleProperty(rule, field);
+ }
+ return rule;
+ }
+
+ private void addRuleProperty(Rule rule, Field field) {
+ org.sonar.check.RuleProperty propertyAnnotation = field.getAnnotation(org.sonar.check.RuleProperty.class);
+ if (propertyAnnotation != null) {
+ String fieldKey = StringUtils.defaultIfEmpty(propertyAnnotation.key(), field.getName());
+ RuleParam param = rule.createParameter(fieldKey);
+ param.setDescription(propertyAnnotation.description());
+ param.setDefaultValue(propertyAnnotation.defaultValue());
+ if (!StringUtils.isBlank(propertyAnnotation.type())) {
+ try {
+ param.setType(PropertyType.valueOf(propertyAnnotation.type().trim()).name());
+ } catch (IllegalArgumentException e) {
+ throw new SonarException("Invalid property type [" + propertyAnnotation.type() + "]", e);
+ }
+ } else {
+ param.setType(guessType(field.getType()).name());
+ }
+ }
+ }
+
+ private static final Function<Class<?>, PropertyType> TYPE_FOR_CLASS = Functions.forMap(
+ ImmutableMap.<Class<?>, PropertyType> builder()
+ .put(Integer.class, PropertyType.INTEGER)
+ .put(int.class, PropertyType.INTEGER)
+ .put(Float.class, PropertyType.FLOAT)
+ .put(float.class, PropertyType.FLOAT)
+ .put(Boolean.class, PropertyType.BOOLEAN)
+ .put(boolean.class, PropertyType.BOOLEAN)
+ .build(),
+ PropertyType.STRING);
+
+ @VisibleForTesting
+ static PropertyType guessType(Class<?> type) {
+ return TYPE_FOR_CLASS.apply(type);
+ }
+}
--- /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.api.rules;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.sonar.api.ServerExtension;
+
+import java.util.List;
+
+/**
+ * @since 2.3
+ * @deprecated in 4.2. Replaced by org.sonar.api.rule.RuleDefinitions
+ */
+@Deprecated
+public abstract class RuleRepository implements ServerExtension {
+
+ private String key;
+ private String language;
+ private String name;
+
+ protected RuleRepository(String key, String language) {
+ this.key = key;
+ this.language = language;
+ }
+
+ public final String getKey() {
+ return key;
+ }
+
+ public final String getLanguage() {
+ return language;
+ }
+
+ public final String getName() {
+ return name;
+ }
+
+ public final String getName(boolean useKeyIfEmpty) {
+ if (useKeyIfEmpty) {
+ return StringUtils.defaultIfEmpty(name, key);
+ }
+ return name;
+ }
+
+ public final RuleRepository setName(String s) {
+ this.name = s;
+ return this;
+ }
+
+ public abstract List<Rule> createRules();
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append("key", key)
+ .append("language", language)
+ .append("name", name)
+ .toString();
+ }
+}
--- /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.api.rules;
+
+import java.util.Map;
+
+import org.apache.commons.configuration.Configuration;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.utils.KeyValueFormat;
+
+/**
+ * A utility class to manipulate concepts around rules
+ * @deprecated in 3.7. Commons Configuration must be replaced by {@link org.sonar.api.config.Settings}
+ */
+@Deprecated
+public final class RuleUtils {
+
+ private RuleUtils() {
+ }
+
+ /**
+ * Gets a Map<RulePriority, Integer> containing the weights defined in the settings
+ * Default value is used when the property is not set (see property key and default value in the class CoreProperties)
+ *
+ * @param configuration the Sonar configuration
+ * @return a map
+ */
+ public static Map<RulePriority, Integer> getPriorityWeights(final Configuration configuration) {
+ String levelWeight = configuration.getString(CoreProperties.CORE_RULE_WEIGHTS_PROPERTY, CoreProperties.CORE_RULE_WEIGHTS_DEFAULT_VALUE);
+
+ Map<RulePriority, Integer> weights = KeyValueFormat.parse(levelWeight, new KeyValueFormat.RulePriorityNumbersPairTransformer());
+
+ for (RulePriority priority : RulePriority.values()) {
+ if (!weights.containsKey(priority)) {
+ weights.put(priority, 1);
+ }
+ }
+ return weights;
+ }
+}
--- /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.api.rules;
+
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.PropertyType;
+import org.sonar.api.utils.SonarException;
+import org.sonar.check.Priority;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class AnnotationRuleParserTest {
+
+ @org.junit.Rule
+ public final ExpectedException exception = ExpectedException.none();
+
+ @Test
+ public void rule_with_property() {
+ List<Rule> rules = parseAnnotatedClass(RuleWithProperty.class);
+ assertThat(rules).hasSize(1);
+ Rule rule = rules.get(0);
+ assertThat(rule.getKey()).isEqualTo("foo");
+ assertThat(rule.getName()).isEqualTo("bar");
+ assertThat(rule.getDescription()).isEqualTo("Foo Bar");
+ assertThat(rule.getSeverity()).isEqualTo(RulePriority.BLOCKER);
+ assertThat(rule.getStatus()).isEqualTo(Rule.STATUS_READY);
+ assertThat(rule.getParams()).hasSize(1);
+
+ RuleParam prop = rule.getParam("property");
+ assertThat(prop.getKey()).isEqualTo("property");
+ assertThat(prop.getDescription()).isEqualTo("Ignore ?");
+ assertThat(prop.getDefaultValue()).isEqualTo("false");
+ assertThat(prop.getType()).isEqualTo(PropertyType.STRING.name());
+ }
+
+ @Test
+ public void rule_with_integer_property() {
+ List<Rule> rules = parseAnnotatedClass(RuleWithIntegerProperty.class);
+
+ RuleParam prop = rules.get(0).getParam("property");
+ assertThat(prop.getDescription()).isEqualTo("Max");
+ assertThat(prop.getDefaultValue()).isEqualTo("12");
+ assertThat(prop.getType()).isEqualTo(PropertyType.INTEGER.name());
+ }
+
+ @Test
+ public void rule_with_text_property() {
+ List<Rule> rules = parseAnnotatedClass(RuleWithTextProperty.class);
+
+ RuleParam prop = rules.get(0).getParam("property");
+ assertThat(prop.getDescription()).isEqualTo("text");
+ assertThat(prop.getDefaultValue()).isEqualTo("Long text");
+ assertThat(prop.getType()).isEqualTo(PropertyType.TEXT.name());
+ }
+
+ @Test
+ public void should_reject_invalid_property_types() {
+ exception.expect(SonarException.class);
+ exception.expectMessage("Invalid property type [INVALID]");
+
+ parseAnnotatedClass(RuleWithInvalidPropertyType.class);
+ }
+
+ @Test
+ public void should_recognize_type() {
+ assertThat(AnnotationRuleParser.guessType(Integer.class)).isEqualTo(PropertyType.INTEGER);
+ assertThat(AnnotationRuleParser.guessType(int.class)).isEqualTo(PropertyType.INTEGER);
+ assertThat(AnnotationRuleParser.guessType(Float.class)).isEqualTo(PropertyType.FLOAT);
+ assertThat(AnnotationRuleParser.guessType(float.class)).isEqualTo(PropertyType.FLOAT);
+ assertThat(AnnotationRuleParser.guessType(Boolean.class)).isEqualTo(PropertyType.BOOLEAN);
+ assertThat(AnnotationRuleParser.guessType(boolean.class)).isEqualTo(PropertyType.BOOLEAN);
+ assertThat(AnnotationRuleParser.guessType(String.class)).isEqualTo(PropertyType.STRING);
+ assertThat(AnnotationRuleParser.guessType(Object.class)).isEqualTo(PropertyType.STRING);
+ }
+
+ @Test
+ public void rule_without_name_nor_description() {
+ List<Rule> rules = parseAnnotatedClass(RuleWithoutNameNorDescription.class);
+ assertThat(rules).hasSize(1);
+ Rule rule = rules.get(0);
+ assertThat(rule.getKey()).isEqualTo("foo");
+ assertThat(rule.getSeverity()).isEqualTo(RulePriority.MAJOR);
+ assertThat(rule.getName()).isNull();
+ assertThat(rule.getDescription()).isNull();
+ }
+
+ @Test
+ public void rule_without_key() {
+ List<Rule> rules = parseAnnotatedClass(RuleWithoutKey.class);
+ assertThat(rules).hasSize(1);
+ Rule rule = rules.get(0);
+ assertThat(rule.getKey()).isEqualTo(RuleWithoutKey.class.getCanonicalName());
+ assertThat(rule.getName()).isEqualTo("foo");
+ assertThat(rule.getDescription()).isNull();
+ assertThat(rule.getSeverity()).isEqualTo(RulePriority.MAJOR);
+ }
+
+ @Test
+ public void overridden_rule() {
+ List<Rule> rules = parseAnnotatedClass(OverridingRule.class);
+ assertThat(rules).hasSize(1);
+ Rule rule = rules.get(0);
+ assertThat(rule.getKey()).isEqualTo("overriding_foo");
+ assertThat(rule.getName()).isEqualTo("Overriding Foo");
+ assertThat(rule.getDescription()).isNull();
+ assertThat(rule.getSeverity()).isEqualTo(RulePriority.MAJOR);
+ assertThat(rule.getParams()).hasSize(2);
+ }
+
+ private List<Rule> parseAnnotatedClass(Class annotatedClass) {
+ return new AnnotationRuleParser().parse("repo", Collections.singleton(annotatedClass));
+ }
+
+ @org.sonar.check.Rule(name = "foo")
+ static class RuleWithoutKey {
+ }
+
+ @org.sonar.check.Rule(key = "foo")
+ static class RuleWithoutNameNorDescription {
+ }
+
+ @org.sonar.check.Rule(key = "foo", name = "bar", description = "Foo Bar", status = Rule.STATUS_READY, priority = Priority.BLOCKER)
+ static class RuleWithProperty {
+ @org.sonar.check.RuleProperty(description = "Ignore ?", defaultValue = "false")
+ private String property;
+ }
+
+ @org.sonar.check.Rule(key = "overriding_foo", name = "Overriding Foo")
+ static class OverridingRule extends RuleWithProperty {
+ @org.sonar.check.RuleProperty
+ private String additionalProperty;
+ }
+
+ @org.sonar.check.Rule(key = "foo", name = "bar", description = "Foo Bar", status = Rule.STATUS_READY, priority = Priority.BLOCKER)
+ static class RuleWithIntegerProperty {
+ @org.sonar.check.RuleProperty(description = "Max", defaultValue = "12")
+ private Integer property;
+ }
+
+ @org.sonar.check.Rule(key = "foo", name = "bar", description = "Foo Bar", status = Rule.STATUS_READY, priority = Priority.BLOCKER)
+ static class RuleWithTextProperty {
+ @org.sonar.check.RuleProperty(description = "text", defaultValue = "Long text", type = "TEXT")
+ protected String property;
+ }
+
+ @org.sonar.check.Rule(key = "foo", name = "bar", description = "Foo Bar", status = Rule.STATUS_READY, priority = Priority.BLOCKER)
+ static class RuleWithInvalidPropertyType {
+ @org.sonar.check.RuleProperty(description = "text", defaultValue = "Long text", type = "INVALID")
+ public String property;
+ }
+}
--- /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.api.rules;
+
+import org.apache.commons.configuration.Configuration;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.sonar.api.CoreProperties;
+
+import java.util.Map;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class RuleUtilsTest {
+
+ @Test
+ public void getPriorityWeights() {
+ Configuration conf = mock(Configuration.class);
+ when(conf.getString(Matchers.eq(CoreProperties.CORE_RULE_WEIGHTS_PROPERTY), anyString())).thenReturn("info=0;minor=1;major=2;critical=5;blocker=10");
+
+ final Map<RulePriority, Integer> map = RuleUtils.getPriorityWeights(conf);
+
+ assertThat(map.get(RulePriority.BLOCKER), is(10));
+ assertThat(map.get(RulePriority.CRITICAL), is(5));
+ assertThat(map.get(RulePriority.MAJOR), is(2));
+ assertThat(map.get(RulePriority.MINOR), is(1));
+ assertThat(map.get(RulePriority.INFO), is(0));
+ }
+
+ @Test
+ public void loadMissingWeights() {
+ Configuration conf = mock(Configuration.class);
+ when(conf.getString(Matchers.eq(CoreProperties.CORE_RULE_WEIGHTS_PROPERTY), anyString())).thenReturn("foo=0;bar=1;CRITICAL=5");
+
+ final Map<RulePriority, Integer> map = RuleUtils.getPriorityWeights(conf);
+
+ assertThat(map.get(RulePriority.BLOCKER), is(1));
+ assertThat(map.get(RulePriority.CRITICAL), is(5));
+ assertThat(map.get(RulePriority.MAJOR), is(1));
+ assertThat(map.get(RulePriority.MINOR), is(1));
+ assertThat(map.get(RulePriority.INFO), is(1));
+ }
+
+}
* Defines the coding rules. For example the Java Findbugs plugin provides an implementation of
* this extension point in order to define the rules that it supports.
* <p/>
- * This interface replaces the deprecated class {@link org.sonar.api.rules.RuleRepository}.
+ * This interface replaces the deprecated class org.sonar.api.rules.RuleRepository.
*
* @since 4.2
*/
+++ /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.api.rules;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.PropertyType;
-import org.sonar.api.ServerComponent;
-import org.sonar.api.utils.AnnotationUtils;
-import org.sonar.api.utils.FieldUtils2;
-import org.sonar.api.utils.SonarException;
-
-import java.lang.reflect.Field;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * @since 2.3
- */
-public final class AnnotationRuleParser implements ServerComponent {
-
- private static final Logger LOG = LoggerFactory.getLogger(AnnotationRuleParser.class);
-
- public List<Rule> parse(String repositoryKey, Collection<Class> annotatedClasses) {
- List<Rule> rules = Lists.newArrayList();
- for (Class annotatedClass : annotatedClasses) {
- rules.add(create(repositoryKey, annotatedClass));
- }
- return rules;
- }
-
- private Rule create(String repositoryKey, Class annotatedClass) {
- org.sonar.check.Rule ruleAnnotation = AnnotationUtils.getAnnotation(annotatedClass, org.sonar.check.Rule.class);
- if (ruleAnnotation != null) {
- return toRule(repositoryKey, annotatedClass, ruleAnnotation);
- }
- LOG.warn("The class " + annotatedClass.getCanonicalName() + " should be annotated with " + Rule.class);
- return null;
- }
-
- private Rule toRule(String repositoryKey, Class clazz, org.sonar.check.Rule ruleAnnotation) {
- String ruleKey = StringUtils.defaultIfEmpty(ruleAnnotation.key(), clazz.getCanonicalName());
- String ruleName = StringUtils.defaultIfEmpty(ruleAnnotation.name(), null);
- String description = StringUtils.defaultIfEmpty(ruleAnnotation.description(), null);
- Rule rule = Rule.create(repositoryKey, ruleKey, ruleName);
- rule.setDescription(description);
- rule.setSeverity(RulePriority.fromCheckPriority(ruleAnnotation.priority()));
- rule.setCardinality(ruleAnnotation.cardinality());
- rule.setStatus(ruleAnnotation.status());
-
- List<Field> fields = FieldUtils2.getFields(clazz, true);
- for (Field field : fields) {
- addRuleProperty(rule, field);
- }
- return rule;
- }
-
- private void addRuleProperty(Rule rule, Field field) {
- org.sonar.check.RuleProperty propertyAnnotation = field.getAnnotation(org.sonar.check.RuleProperty.class);
- if (propertyAnnotation != null) {
- String fieldKey = StringUtils.defaultIfEmpty(propertyAnnotation.key(), field.getName());
- RuleParam param = rule.createParameter(fieldKey);
- param.setDescription(propertyAnnotation.description());
- param.setDefaultValue(propertyAnnotation.defaultValue());
- if (!StringUtils.isBlank(propertyAnnotation.type())) {
- try {
- param.setType(PropertyType.valueOf(propertyAnnotation.type().trim()).name());
- } catch (IllegalArgumentException e) {
- throw new SonarException("Invalid property type [" + propertyAnnotation.type() + "]", e);
- }
- } else {
- param.setType(guessType(field.getType()).name());
- }
- }
- }
-
- private static final Function<Class<?>, PropertyType> TYPE_FOR_CLASS = Functions.forMap(
- ImmutableMap.<Class<?>, PropertyType> builder()
- .put(Integer.class, PropertyType.INTEGER)
- .put(int.class, PropertyType.INTEGER)
- .put(Float.class, PropertyType.FLOAT)
- .put(float.class, PropertyType.FLOAT)
- .put(Boolean.class, PropertyType.BOOLEAN)
- .put(boolean.class, PropertyType.BOOLEAN)
- .build(),
- PropertyType.STRING);
-
- @VisibleForTesting
- static PropertyType guessType(Class<?> type) {
- return TYPE_FOR_CLASS.apply(type);
- }
-}
+++ /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.api.rules;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.commons.lang.builder.ToStringStyle;
-import org.sonar.api.ServerExtension;
-
-import java.util.List;
-
-/**
- * @since 2.3
- * @deprecated in 4.2. Replaced by {@link org.sonar.api.rule.RuleDefinitions}
- */
-@Deprecated
-public abstract class RuleRepository implements ServerExtension {
-
- private String key;
- private String language;
- private String name;
-
- protected RuleRepository(String key, String language) {
- this.key = key;
- this.language = language;
- }
-
- public final String getKey() {
- return key;
- }
-
- public final String getLanguage() {
- return language;
- }
-
- public final String getName() {
- return name;
- }
-
- public final String getName(boolean useKeyIfEmpty) {
- if (useKeyIfEmpty) {
- return StringUtils.defaultIfEmpty(name, key);
- }
- return name;
- }
-
- public final RuleRepository setName(String s) {
- this.name = s;
- return this;
- }
-
- public abstract List<Rule> createRules();
-
- @Override
- public String toString() {
- return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
- .append("key", key)
- .append("language", language)
- .append("name", name)
- .toString();
- }
-}
+++ /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.api.rules;
-
-import java.util.Map;
-
-import org.apache.commons.configuration.Configuration;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.utils.KeyValueFormat;
-
-/**
- * A utility class to manipulate concepts around rules
- * @deprecated in 3.7. Commons Configuration must be replaced by {@link org.sonar.api.config.Settings}
- */
-@Deprecated
-public final class RuleUtils {
-
- private RuleUtils() {
- }
-
- /**
- * Gets a Map<RulePriority, Integer> containing the weights defined in the settings
- * Default value is used when the property is not set (see property key and default value in the class CoreProperties)
- *
- * @param configuration the Sonar configuration
- * @return a map
- */
- public static Map<RulePriority, Integer> getPriorityWeights(final Configuration configuration) {
- String levelWeight = configuration.getString(CoreProperties.CORE_RULE_WEIGHTS_PROPERTY, CoreProperties.CORE_RULE_WEIGHTS_DEFAULT_VALUE);
-
- Map<RulePriority, Integer> weights = KeyValueFormat.parse(levelWeight, new KeyValueFormat.RulePriorityNumbersPairTransformer());
-
- for (RulePriority priority : RulePriority.values()) {
- if (!weights.containsKey(priority)) {
- weights.put(priority, 1);
- }
- }
- return weights;
- }
-}
+++ /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.api.rules;
-
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.PropertyType;
-import org.sonar.api.utils.SonarException;
-import org.sonar.check.Priority;
-
-import java.util.Collections;
-import java.util.List;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class AnnotationRuleParserTest {
-
- @org.junit.Rule
- public final ExpectedException exception = ExpectedException.none();
-
- @Test
- public void rule_with_property() {
- List<Rule> rules = parseAnnotatedClass(RuleWithProperty.class);
- assertThat(rules).hasSize(1);
- Rule rule = rules.get(0);
- assertThat(rule.getKey()).isEqualTo("foo");
- assertThat(rule.getName()).isEqualTo("bar");
- assertThat(rule.getDescription()).isEqualTo("Foo Bar");
- assertThat(rule.getSeverity()).isEqualTo(RulePriority.BLOCKER);
- assertThat(rule.getStatus()).isEqualTo(Rule.STATUS_READY);
- assertThat(rule.getParams()).hasSize(1);
-
- RuleParam prop = rule.getParam("property");
- assertThat(prop.getKey()).isEqualTo("property");
- assertThat(prop.getDescription()).isEqualTo("Ignore ?");
- assertThat(prop.getDefaultValue()).isEqualTo("false");
- assertThat(prop.getType()).isEqualTo(PropertyType.STRING.name());
- }
-
- @Test
- public void rule_with_integer_property() {
- List<Rule> rules = parseAnnotatedClass(RuleWithIntegerProperty.class);
-
- RuleParam prop = rules.get(0).getParam("property");
- assertThat(prop.getDescription()).isEqualTo("Max");
- assertThat(prop.getDefaultValue()).isEqualTo("12");
- assertThat(prop.getType()).isEqualTo(PropertyType.INTEGER.name());
- }
-
- @Test
- public void rule_with_text_property() {
- List<Rule> rules = parseAnnotatedClass(RuleWithTextProperty.class);
-
- RuleParam prop = rules.get(0).getParam("property");
- assertThat(prop.getDescription()).isEqualTo("text");
- assertThat(prop.getDefaultValue()).isEqualTo("Long text");
- assertThat(prop.getType()).isEqualTo(PropertyType.TEXT.name());
- }
-
- @Test
- public void should_reject_invalid_property_types() {
- exception.expect(SonarException.class);
- exception.expectMessage("Invalid property type [INVALID]");
-
- parseAnnotatedClass(RuleWithInvalidPropertyType.class);
- }
-
- @Test
- public void should_recognize_type() {
- assertThat(AnnotationRuleParser.guessType(Integer.class)).isEqualTo(PropertyType.INTEGER);
- assertThat(AnnotationRuleParser.guessType(int.class)).isEqualTo(PropertyType.INTEGER);
- assertThat(AnnotationRuleParser.guessType(Float.class)).isEqualTo(PropertyType.FLOAT);
- assertThat(AnnotationRuleParser.guessType(float.class)).isEqualTo(PropertyType.FLOAT);
- assertThat(AnnotationRuleParser.guessType(Boolean.class)).isEqualTo(PropertyType.BOOLEAN);
- assertThat(AnnotationRuleParser.guessType(boolean.class)).isEqualTo(PropertyType.BOOLEAN);
- assertThat(AnnotationRuleParser.guessType(String.class)).isEqualTo(PropertyType.STRING);
- assertThat(AnnotationRuleParser.guessType(Object.class)).isEqualTo(PropertyType.STRING);
- }
-
- @Test
- public void rule_without_name_nor_description() {
- List<Rule> rules = parseAnnotatedClass(RuleWithoutNameNorDescription.class);
- assertThat(rules).hasSize(1);
- Rule rule = rules.get(0);
- assertThat(rule.getKey()).isEqualTo("foo");
- assertThat(rule.getSeverity()).isEqualTo(RulePriority.MAJOR);
- assertThat(rule.getName()).isNull();
- assertThat(rule.getDescription()).isNull();
- }
-
- @Test
- public void rule_without_key() {
- List<Rule> rules = parseAnnotatedClass(RuleWithoutKey.class);
- assertThat(rules).hasSize(1);
- Rule rule = rules.get(0);
- assertThat(rule.getKey()).isEqualTo(RuleWithoutKey.class.getCanonicalName());
- assertThat(rule.getName()).isEqualTo("foo");
- assertThat(rule.getDescription()).isNull();
- assertThat(rule.getSeverity()).isEqualTo(RulePriority.MAJOR);
- }
-
- @Test
- public void overridden_rule() {
- List<Rule> rules = parseAnnotatedClass(OverridingRule.class);
- assertThat(rules).hasSize(1);
- Rule rule = rules.get(0);
- assertThat(rule.getKey()).isEqualTo("overriding_foo");
- assertThat(rule.getName()).isEqualTo("Overriding Foo");
- assertThat(rule.getDescription()).isNull();
- assertThat(rule.getSeverity()).isEqualTo(RulePriority.MAJOR);
- assertThat(rule.getParams()).hasSize(2);
- }
-
- private List<Rule> parseAnnotatedClass(Class annotatedClass) {
- return new AnnotationRuleParser().parse("repo", Collections.singleton(annotatedClass));
- }
-
- @org.sonar.check.Rule(name = "foo")
- static class RuleWithoutKey {
- }
-
- @org.sonar.check.Rule(key = "foo")
- static class RuleWithoutNameNorDescription {
- }
-
- @org.sonar.check.Rule(key = "foo", name = "bar", description = "Foo Bar", status = Rule.STATUS_READY, priority = Priority.BLOCKER)
- static class RuleWithProperty {
- @org.sonar.check.RuleProperty(description = "Ignore ?", defaultValue = "false")
- private String property;
- }
-
- @org.sonar.check.Rule(key = "overriding_foo", name = "Overriding Foo")
- static class OverridingRule extends RuleWithProperty {
- @org.sonar.check.RuleProperty
- private String additionalProperty;
- }
-
- @org.sonar.check.Rule(key = "foo", name = "bar", description = "Foo Bar", status = Rule.STATUS_READY, priority = Priority.BLOCKER)
- static class RuleWithIntegerProperty {
- @org.sonar.check.RuleProperty(description = "Max", defaultValue = "12")
- private Integer property;
- }
-
- @org.sonar.check.Rule(key = "foo", name = "bar", description = "Foo Bar", status = Rule.STATUS_READY, priority = Priority.BLOCKER)
- static class RuleWithTextProperty {
- @org.sonar.check.RuleProperty(description = "text", defaultValue = "Long text", type = "TEXT")
- protected String property;
- }
-
- @org.sonar.check.Rule(key = "foo", name = "bar", description = "Foo Bar", status = Rule.STATUS_READY, priority = Priority.BLOCKER)
- static class RuleWithInvalidPropertyType {
- @org.sonar.check.RuleProperty(description = "text", defaultValue = "Long text", type = "INVALID")
- public String property;
- }
-}
+++ /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.api.rules;
-
-import org.apache.commons.configuration.Configuration;
-import org.junit.Test;
-import org.mockito.Matchers;
-import org.sonar.api.CoreProperties;
-
-import java.util.Map;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class RuleUtilsTest {
-
- @Test
- public void getPriorityWeights() {
- Configuration conf = mock(Configuration.class);
- when(conf.getString(Matchers.eq(CoreProperties.CORE_RULE_WEIGHTS_PROPERTY), anyString())).thenReturn("info=0;minor=1;major=2;critical=5;blocker=10");
-
- final Map<RulePriority, Integer> map = RuleUtils.getPriorityWeights(conf);
-
- assertThat(map.get(RulePriority.BLOCKER), is(10));
- assertThat(map.get(RulePriority.CRITICAL), is(5));
- assertThat(map.get(RulePriority.MAJOR), is(2));
- assertThat(map.get(RulePriority.MINOR), is(1));
- assertThat(map.get(RulePriority.INFO), is(0));
- }
-
- @Test
- public void loadMissingWeights() {
- Configuration conf = mock(Configuration.class);
- when(conf.getString(Matchers.eq(CoreProperties.CORE_RULE_WEIGHTS_PROPERTY), anyString())).thenReturn("foo=0;bar=1;CRITICAL=5");
-
- final Map<RulePriority, Integer> map = RuleUtils.getPriorityWeights(conf);
-
- assertThat(map.get(RulePriority.BLOCKER), is(1));
- assertThat(map.get(RulePriority.CRITICAL), is(5));
- assertThat(map.get(RulePriority.MAJOR), is(1));
- assertThat(map.get(RulePriority.MINOR), is(1));
- assertThat(map.get(RulePriority.INFO), is(1));
- }
-
-}
+++ /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.test.i18n;
-
-import com.google.common.io.Closeables;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleRepository;
-import org.sonar.api.utils.SonarException;
-import org.sonar.test.TestUtils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import java.util.Properties;
-
-public final class RuleRepositoryTestHelper {
- private RuleRepositoryTestHelper() {
- // Static utility class
- }
-
- public static List<Rule> createRulesWithNameAndDescription(String pluginKey, RuleRepository repository) {
- Properties props = loadProperties(String.format("/org/sonar/l10n/%s.properties", pluginKey));
-
- List<Rule> rules = repository.createRules();
- for (Rule rule : rules) {
- String name = props.getProperty(String.format("rule.%s.%s.name", repository.getKey(), rule.getKey()));
- String description = TestUtils.getResourceContent(String.format("/org/sonar/l10n/%s/rules/%s/%s.html", pluginKey, repository.getKey(), rule.getKey()));
-
- rule.setName(name);
- rule.setDescription(description);
- }
-
- return rules;
- }
-
- private static Properties loadProperties(String resourcePath) {
- Properties properties = new Properties();
-
- InputStream input = null;
- try {
- input = TestUtils.class.getResourceAsStream(resourcePath);
- properties.load(input);
- return properties;
- } catch (IOException e) {
- throw new SonarException("Unable to read properties " + resourcePath, e);
- } finally {
- Closeables.closeQuietly(input);
- }
- }
-}