001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2009 SonarSource SA
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020 package org.sonar.api.rules;
021
022 import org.slf4j.Logger;
023 import org.slf4j.LoggerFactory;
024 import org.sonar.check.AnnotationIntrospector;
025
026 import java.lang.reflect.Field;
027 import java.util.ArrayList;
028 import java.util.Collection;
029 import java.util.List;
030
031 /**
032 * @since 2.3
033 */
034 public final class RuleAnnotationUtils {
035
036 private static final Logger LOG = LoggerFactory.getLogger(RuleAnnotationUtils.class);
037
038 private RuleAnnotationUtils() {
039 // only static methods
040 }
041
042 public static List<Rule> readAnnotatedClasses(Collection<Class> annotatedClasses) {
043 List<Rule> rules = new ArrayList<Rule>();
044 if (annotatedClasses != null) {
045 for (Class annotatedClass : annotatedClasses) {
046 Rule rule = readAnnotatedClass(annotatedClass);
047 if (rule != null) {
048 rules.add(rule);
049 }
050 }
051 }
052 return rules;
053 }
054
055 public static Rule readAnnotatedClass(Class annotatedClass) {
056 org.sonar.check.Check checkAnnotation = AnnotationIntrospector.getCheckAnnotation(annotatedClass);
057 if (checkAnnotation == null) {
058 LOG.warn("The class " + annotatedClass.getCanonicalName() + " is not a rule. It should be annotated with " + org.sonar.check.Check.class);
059 return null;
060 }
061
062 Rule rule = toRule(annotatedClass, checkAnnotation);
063 Field[] fields = annotatedClass.getDeclaredFields();
064 if (fields != null) {
065 for (Field field : fields) {
066 createParam(rule, field);
067 }
068 }
069 return rule;
070 }
071
072 private static Rule toRule(Class annotatedClass, org.sonar.check.Check annotation) {
073 String key = AnnotationIntrospector.getCheckKey(annotatedClass);
074
075 Rule rule = Rule.create();
076 rule.setKey(key);
077 rule.setName(annotation.title());
078 rule.setDescription(annotation.description());
079 rule.setRulesCategory(new RulesCategory(annotation.isoCategory().name()));
080 rule.setPriority(RulePriority.fromCheckPriority(annotation.priority()));
081 return rule;
082 }
083
084 private static void createParam(Rule rule, Field field) {
085 org.sonar.check.CheckProperty propertyAnnotation = field.getAnnotation(org.sonar.check.CheckProperty.class);
086 if (propertyAnnotation != null) {
087 String fieldKey = propertyAnnotation.key();
088 if (fieldKey==null || "".equals(fieldKey)) {
089 fieldKey = field.getName();
090 }
091 RuleParam param = rule.createParameter(fieldKey);
092 param.setDescription(propertyAnnotation.description());
093 }
094 }
095 }