import java.util.ArrayList;
import java.util.List;
+/**
+ * @since 2.1 (experimental)
+ * @deprecated since 2.3
+ */
+@Deprecated
public final class AnnotationIntrospector {
private AnnotationIntrospector() {
import java.lang.annotation.Target;
/**
- * @since 2.1
+ * @since 2.1 (experimental)
+ * @deprecated since 2.3. Not supported anymore
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
+@Deprecated
public @interface BelongsToProfiles {
BelongsToProfile[] value() default {};
import java.lang.annotation.Target;
/**
- * @since 2.1
+ * @since 2.1 (experimental)
+ * @deprecated since 2.3. Use @Rule
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
+@Deprecated
public @interface Check {
/**
import java.lang.annotation.Target;
/**
- * @since 2.1
+ * @since 2.1 (experimental)
+ * @deprecated since 2.3. Use @RuleProperty
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
+@Deprecated
public @interface CheckProperty {
/**
import java.util.Locale;
+@Deprecated
public interface Message {
/**
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.check;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @since 2.3
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface Rule {
+
+ /**
+ * The default key is the class name.
+ */
+ String key() default "";
+
+ /**
+ * The rule name. If not defined, then the name is the key
+ */
+ String name() default "";
+
+ /**
+ * The description, optional.
+ */
+ String description() default "";
+
+ /**
+ * Default priority.
+ */
+ Priority priority() default Priority.MAJOR;
+
+ /**
+ * Will probably be deprecated and replaced by tags
+ */
+ IsoCategory isoCategory();
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.check;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @since 2.3
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface RuleProperty {
+
+ /**
+ * The default key is the field name, read by reflection. Overriding this key can be useful when
+ * obfuscating the code.
+ */
+ String key() default "";
+
+ /**
+ * Optional description
+ */
+ String description() default "";
+
+ /**
+ * Optional default value.
+ */
+ String defaultValue() default "";
+}
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
package org.sonar.api.checks.checkers;
import org.junit.Before;
import org.sonar.check.IsoCategory;
import org.sonar.check.Priority;
-/**
- * Created by IntelliJ IDEA.
- * User: simonbrandhof
- * Date: Sep 14, 2010
- * Time: 11:20:57 AM
- * To change this template use File | Settings | File Templates.
- */
@Check(isoCategory = IsoCategory.Efficiency, priority = Priority.CRITICAL)
class CheckWithUnsupportedPropertyType {
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
package org.sonar.api.checks.checkers;
import org.sonar.check.Check;
import org.sonar.check.IsoCategory;
import org.sonar.check.Priority;
-/**
- * Created by IntelliJ IDEA.
- * User: simonbrandhof
- * Date: Sep 14, 2010
- * Time: 11:20:57 AM
- * To change this template use File | Settings | File Templates.
- */
@Check(isoCategory = IsoCategory.Efficiency, priority = Priority.CRITICAL)
class CheckerWithPrimitiveProperties {
import org.sonar.check.IsoCategory;
import org.sonar.check.Priority;
-/**
- * Created by IntelliJ IDEA.
- * User: simonbrandhof
- * Date: Sep 14, 2010
- * Time: 11:20:57 AM
- * To change this template use File | Settings | File Templates.
- */
@Check(isoCategory = IsoCategory.Efficiency, priority = Priority.CRITICAL)
class CheckerWithStringProperty {
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.checks;
+
+import com.google.common.collect.Maps;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.ActiveRule;
+import org.sonar.api.rules.ActiveRuleParam;
+import org.sonar.api.utils.SonarException;
+import org.sonar.check.Check;
+import org.sonar.check.CheckProperty;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * @since 2.3
+ */
+public final class AnnotationCheckFactory extends CheckFactory {
+
+ private Map<String, Class> checkClassesByKey = Maps.newHashMap();
+
+ private AnnotationCheckFactory(RulesProfile profile, String repositoryKey, Collection<Class> checkClasses) {
+ super(profile, repositoryKey);
+ groupClassesByKey(checkClasses);
+ }
+
+
+ public static AnnotationCheckFactory create(RulesProfile profile, String repositoryKey, Collection<Class> checkClasses) {
+ AnnotationCheckFactory factory = new AnnotationCheckFactory(profile, repositoryKey, checkClasses);
+ factory.init();
+ return factory;
+ }
+
+ private void groupClassesByKey(Collection<Class> checkClasses) {
+ for (Class checkClass : checkClasses) {
+ String key = getRuleKey(checkClass);
+ if (key != null) {
+ checkClassesByKey.put(key, checkClass);
+ }
+ }
+ }
+
+ protected Object createCheck(ActiveRule activeRule) {
+ Class clazz = checkClassesByKey.get(activeRule.getRuleKey());
+ if (clazz != null) {
+ return instantiate(activeRule, clazz);
+ }
+ return null;
+ }
+
+ private Object instantiate(ActiveRule activeRule, Class clazz) {
+ try {
+ Object check = clazz.newInstance();
+ configureFields(activeRule, check);
+ return check;
+
+ } catch (InstantiationException e) {
+ throw new SonarException("Can not instantiate the check related to the rule " + activeRule, e);
+
+ } catch (IllegalAccessException e) {
+ throw new SonarException("Can not instantiate the check related to the rule " + activeRule, e);
+ }
+ }
+
+ private void configureFields(ActiveRule activeRule, Object check) {
+ for (ActiveRuleParam param : activeRule.getActiveRuleParams()) {
+ Field field = getField(check, param.getKey());
+ if (field == null) {
+ throw new SonarException("The field " + param.getKey() + " does not exist or is not annotated with @RuleProperty in the class " + check.getClass().getName());
+ }
+ if (StringUtils.isNotBlank(param.getValue())) {
+ configureField(check, field, param.getValue());
+ }
+ }
+
+ }
+
+ 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 (field.getType().getSimpleName().equals("int")) {
+ field.setInt(check, Integer.parseInt(value));
+
+ } else if (field.getType().getSimpleName().equals("short")) {
+ field.setShort(check, Short.parseShort(value));
+
+ } else if (field.getType().getSimpleName().equals("long")) {
+ field.setLong(check, Long.parseLong(value));
+
+ } else if (field.getType().getSimpleName().equals("double")) {
+ field.setDouble(check, Double.parseDouble(value));
+
+ } else if (field.getType().getSimpleName().equals("boolean")) {
+ field.setBoolean(check, Boolean.parseBoolean(value));
+
+ } else if (field.getType().getSimpleName().equals("byte")) {
+ field.setByte(check, Byte.parseByte(value));
+
+ } else if (field.getType().equals(Integer.class)) {
+ field.set(check, new Integer(Integer.parseInt(value)));
+
+ } else if (field.getType().equals(Long.class)) {
+ field.set(check, new Long(Long.parseLong(value)));
+
+ } else if (field.getType().equals(Double.class)) {
+ field.set(check, new Double(Double.parseDouble(value)));
+
+ } else if (field.getType().equals(Boolean.class)) {
+ field.set(check, Boolean.valueOf(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());
+ }
+ }
+
+ private Field getField(Object check, String key) {
+ Field[] fields = check.getClass().getDeclaredFields();
+ for (Field field : fields) {
+ RuleProperty propertyAnnotation = field.getAnnotation(RuleProperty.class);
+ if (propertyAnnotation != null) {
+ if (StringUtils.equals(key, field.getName()) || StringUtils.equals(key, propertyAnnotation.key())) {
+ return field;
+ }
+ } else {
+ CheckProperty checkAnnotation = field.getAnnotation(CheckProperty.class);
+ if (checkAnnotation != null) {
+ if (StringUtils.equals(key, field.getName()) || StringUtils.equals(key, checkAnnotation.key())) {
+ return field;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private String getRuleKey(Class annotatedClass) {
+ String key = null;
+ Rule ruleAnnotation = (Rule) annotatedClass.getAnnotation(Rule.class);
+ if (ruleAnnotation != null) {
+ key = ruleAnnotation.key();
+ } else {
+ Check checkAnnotation = (Check) annotatedClass.getAnnotation(Check.class);
+ if (checkAnnotation != null) {
+ key = checkAnnotation.key();
+
+ }
+ }
+ return StringUtils.defaultIfEmpty(key, annotatedClass.getCanonicalName());
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.checks;
+
+import com.google.common.collect.Maps;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.ActiveRule;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * @since 2.3
+ */
+public abstract class CheckFactory<CHECK> {
+
+ private Map<ActiveRule, CHECK> checkByActiveRule = Maps.newIdentityHashMap();
+ private Map<CHECK, ActiveRule> activeRuleByCheck = Maps.newIdentityHashMap();
+ private RulesProfile profile;
+ private String repositoryKey;
+
+ protected CheckFactory(RulesProfile profile, String repositoryKey) {
+ this.repositoryKey = repositoryKey;
+ this.profile = profile;
+ }
+
+ protected void init() {
+ checkByActiveRule.clear();
+ activeRuleByCheck.clear();
+ for (ActiveRule activeRule : profile.getActiveRulesByRepository(repositoryKey)) {
+ CHECK check = createCheck(activeRule);
+ checkByActiveRule.put(activeRule, check);
+ activeRuleByCheck.put(check, activeRule);
+ }
+ }
+
+ abstract CHECK createCheck(ActiveRule activeRule);
+
+ public final String getRepositoryKey() {
+ return repositoryKey;
+ }
+
+ public final Collection<CHECK> getChecks() {
+ return checkByActiveRule.values();
+ }
+
+ public final CHECK getCheck(ActiveRule activeRule) {
+ return checkByActiveRule.get(activeRule);
+ }
+
+ public final ActiveRule getActiveRule(CHECK check) {
+ return activeRuleByCheck.get(check);
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+
+package org.sonar.api.rules;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.utils.AnnotationUtils;
+import org.sonar.check.Check;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @since 2.3
+ */
+public final class AnnotationRuleRepository extends RuleRepository {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AnnotationRuleRepository.class);
+
+ private Collection<Class> annotatedClasses;
+
+ /**
+ * Use the factory method()
+ */
+ private AnnotationRuleRepository(String key, String language, Collection<Class> annotatedClasses) {
+ super(key, language);
+ this.annotatedClasses = annotatedClasses;
+ }
+
+ public static AnnotationRuleRepository create(String key, String language, Collection<Class> annotatedClasses) {
+ return new AnnotationRuleRepository(key, language, annotatedClasses);
+ }
+
+ @Override
+ public List<Rule> createRules() {
+ List<Rule> rules = Lists.newArrayList();
+ for (Class annotatedClass : annotatedClasses) {
+ rules.add(create(annotatedClass));
+ }
+ return rules;
+ }
+
+ private Rule create(Class annotatedClass) {
+ org.sonar.check.Rule ruleAnnotation = AnnotationUtils.getClassAnnotation(annotatedClass, org.sonar.check.Rule.class);
+ if (ruleAnnotation != null) {
+ return toRule(annotatedClass, ruleAnnotation);
+ }
+ Check checkAnnotation = AnnotationUtils.getClassAnnotation(annotatedClass, Check.class);
+ if (checkAnnotation != null) {
+ return toRule(annotatedClass, checkAnnotation);
+ }
+ LOG.warn("The class " + annotatedClass.getCanonicalName() + " is not a check template. It should be annotated with " + Rule.class);
+ return null;
+ }
+
+ private Rule toRule(Class clazz, org.sonar.check.Rule ruleAnnotation) {
+ String key = StringUtils.defaultIfEmpty(ruleAnnotation.key(), clazz.getCanonicalName());
+ Rule rule = Rule.create(getKey(), key, ruleAnnotation.name());
+ rule.setDescription(ruleAnnotation.description());
+ rule.setRulesCategory(RulesCategory.fromIsoCategory(ruleAnnotation.isoCategory()));
+ rule.setPriority(RulePriority.fromCheckPriority(ruleAnnotation.priority()));
+
+ Field[] fields = clazz.getDeclaredFields();
+ if (fields != null) {
+ for (Field field : fields) {
+ addRuleProperty(rule, field);
+ }
+ }
+
+ return rule;
+ }
+
+ private Rule toRule(Class clazz, Check checkAnnotation) {
+ String key = StringUtils.defaultIfEmpty(checkAnnotation.key(), clazz.getCanonicalName());
+ Rule rule = Rule.create(getKey(), key, checkAnnotation.title());
+ rule.setDescription(checkAnnotation.description());
+ rule.setRulesCategory(RulesCategory.fromIsoCategory(checkAnnotation.isoCategory()));
+ rule.setPriority(RulePriority.fromCheckPriority(checkAnnotation.priority()));
+
+ Field[] fields = clazz.getDeclaredFields();
+ if (fields != null) {
+ for (Field field : fields) {
+ addCheckProperty(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());
+ }
+ }
+
+ private void addCheckProperty(Rule rule, Field field) {
+ org.sonar.check.CheckProperty propertyAnnotation = field.getAnnotation(org.sonar.check.CheckProperty.class);
+ if (propertyAnnotation != null) {
+ String fieldKey = StringUtils.defaultIfEmpty(propertyAnnotation.key(), field.getName());
+ RuleParam param = rule.createParameter(fieldKey);
+ param.setDescription(propertyAnnotation.description());
+ }
+ }
+}
}\r
return null;\r
}\r
+\r
+ public static RulesCategory fromIsoCategory(IsoCategory iso) {\r
+ if (iso==IsoCategory.Efficiency) {\r
+ return Iso9126RulesCategories.EFFICIENCY;\r
+ }\r
+ if (iso==IsoCategory.Maintainability) {\r
+ return Iso9126RulesCategories.MAINTAINABILITY;\r
+ }\r
+ if (iso==IsoCategory.Portability) {\r
+ return Iso9126RulesCategories.PORTABILITY;\r
+ }\r
+ if (iso==IsoCategory.Reliability) {\r
+ return Iso9126RulesCategories.RELIABILITY;\r
+ }\r
+ if (iso==IsoCategory.Usability) {\r
+ return Iso9126RulesCategories.USABILITY;\r
+ }\r
+ return null;\r
+ }\r
}\r
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.checks;
+
+import org.junit.Test;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.ActiveRule;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.utils.SonarException;
+
+import java.util.Arrays;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+public class AnnotationCheckFactoryTest {
+
+ @Test
+ public void createCheckWithoutProperties() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ ActiveRule activeRule = profile.activateRule(Rule.create("repo", "org.sonar.api.checks.CheckWithoutProperties", ""), null);
+ AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithoutProperties.class));
+
+ Object check = factory.getCheck(activeRule);
+ assertNotNull(check);
+ assertThat(check, is(CheckWithoutProperties.class));
+ }
+
+ @Test
+ public void createCheckWithStringProperty() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "org.sonar.api.checks.CheckWithStringProperty", "");
+ rule.createParameter("pattern");
+
+ ActiveRule activeRule = profile.activateRule(rule, null);
+ activeRule.setParameter("pattern", "foo");
+ AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithStringProperty.class));
+
+ Object check = factory.getCheck(activeRule);
+ assertNotNull(check);
+ assertThat(check, is(CheckWithStringProperty.class));
+ assertThat(((CheckWithStringProperty) check).getPattern(), is("foo"));
+ }
+
+ @Test(expected = SonarException.class)
+ public void failIfMissingProperty() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "org.sonar.api.checks.CheckWithStringProperty", "");
+ rule.createParameter("unknown");
+
+ ActiveRule activeRule = profile.activateRule(rule, null);
+ activeRule.setParameter("unknown", "bar");
+ AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithStringProperty.class));
+ }
+
+ @Test
+ public void createCheckWithPrimitiveProperties() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "org.sonar.api.checks.CheckWithPrimitiveProperties", "");
+ rule.createParameter("max");
+ rule.createParameter("ignore");
+
+ ActiveRule activeRule = profile.activateRule(rule, null);
+ activeRule.setParameter("max", "300");
+ activeRule.setParameter("ignore", "true");
+ AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithPrimitiveProperties.class));
+
+ Object check = factory.getCheck(activeRule);
+ assertThat(((CheckWithPrimitiveProperties) check).getMax(), is(300));
+ assertThat(((CheckWithPrimitiveProperties) check).isIgnore(), is(true));
+ }
+
+ @Test
+ public void createCheckWithIntegerProperty() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "org.sonar.api.checks.CheckWithIntegerProperty", "");
+ rule.createParameter("max");
+
+ ActiveRule activeRule = profile.activateRule(rule, null);
+ activeRule.setParameter("max", "300");
+ AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithIntegerProperty.class));
+
+ Object check = factory.getCheck(activeRule);
+ assertThat(((CheckWithIntegerProperty) check).getMax(), is(300));
+ }
+
+
+ @Test(expected = SonarException.class)
+ public void failIfPropertyTypeIsNotSupported() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "org.sonar.api.checks.CheckWithUnsupportedPropertyType", "");
+ rule.createParameter("max");
+
+ ActiveRule activeRule = profile.activateRule(rule, null);
+ activeRule.setParameter("max", "300");
+ AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithUnsupportedPropertyType.class));
+ }
+
+ @Test
+ public void shouldOverridePropertyKey() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "org.sonar.api.checks.CheckWithOverriddenPropertyKey", "");
+ rule.createParameter("maximum");
+
+ ActiveRule activeRule = profile.activateRule(rule, null);
+ activeRule.setParameter("maximum", "300");
+ AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithOverriddenPropertyKey.class));
+
+ Object check = factory.getCheck(activeRule);
+ assertThat(((CheckWithOverriddenPropertyKey) check).getMax(), is(300));
+ }
+}
+
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.checks;
+
+import org.sonar.check.*;
+
+@Rule(isoCategory = IsoCategory.Efficiency, priority = Priority.CRITICAL)
+class CheckWithIntegerProperty {
+
+ @RuleProperty
+ private Integer max;
+
+ public Integer getMax() {
+ return max;
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.checks;
+
+import org.sonar.check.IsoCategory;
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+
+@Rule(isoCategory = IsoCategory.Efficiency, priority = Priority.CRITICAL)
+class CheckWithOverriddenPropertyKey{
+
+ @RuleProperty(key = "maximum")
+ private int max = 50;
+
+ public int getMax() {
+ return max;
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.checks;
+
+import org.sonar.check.*;
+
+@Rule(isoCategory = IsoCategory.Efficiency, priority = Priority.CRITICAL)
+class CheckWithPrimitiveProperties {
+
+ @RuleProperty(description = "Maximum threshold")
+ private int max = 50;
+
+ @RuleProperty
+ private boolean ignore;
+
+ public int getMax() {
+ return max;
+ }
+
+ public boolean isIgnore() {
+ return ignore;
+ }
+}
+
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.checks;
+
+import org.sonar.check.*;
+
+@Rule(isoCategory = IsoCategory.Efficiency, priority = Priority.CRITICAL)
+class CheckWithStringProperty {
+
+ @RuleProperty
+ private String pattern;
+
+ public String getPattern() {
+ return pattern;
+ }
+}
+
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.checks;
+
+import org.sonar.check.*;
+
+@Rule(isoCategory = IsoCategory.Efficiency, priority = Priority.CRITICAL)
+class CheckWithUnsupportedPropertyType {
+
+ @RuleProperty
+ private StringBuilder max = null;
+
+}
--- /dev/null
+/*
+* Sonar, open source software quality management tool.
+* Copyright (C) 2009 SonarSource SA
+* mailto:contact AT sonarsource DOT com
+*
+* Sonar 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.
+*
+* Sonar 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 Sonar; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+*/
+package org.sonar.api.checks;
+
+import org.sonar.check.IsoCategory;
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+
+@Rule(isoCategory = IsoCategory.Efficiency, priority = Priority.CRITICAL)
+class CheckWithoutProperties {
+
+}
+