diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2014-03-25 23:10:45 +0100 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2014-03-25 23:10:46 +0100 |
commit | 1b8416c73a97f61899286d2e1f4e3e7685135e9a (patch) | |
tree | 2894a01e8efd50df65264f7f31328f46f0a756a0 /sonar-plugin-api | |
parent | 0abfc8ad75bb91dceba66f9e5905268312bed038 (diff) | |
download | sonarqube-1b8416c73a97f61899286d2e1f4e3e7685135e9a.tar.gz sonarqube-1b8416c73a97f61899286d2e1f4e3e7685135e9a.zip |
SONAR-4908 extract RulesDefinitionAnnotationLoader
+ refactor the classes RegisterXXX used during server startup
Diffstat (limited to 'sonar-plugin-api')
-rw-r--r-- | sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java | 213 | ||||
-rw-r--r-- | sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinitionAnnotationLoader.java (renamed from sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitionsFromAnnotations.java) | 22 | ||||
-rw-r--r-- | sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java | 33 | ||||
-rw-r--r-- | sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionAnnotationLoaderTest.java (renamed from sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionFromAnnotationsTest.java) | 26 | ||||
-rw-r--r-- | sonar-plugin-api/src/test/java/org/sonar/api/utils/text/JsonWriterTest.java | 2 |
5 files changed, 241 insertions, 55 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java index fff3f96e797..7c01f5836c7 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java @@ -139,6 +139,170 @@ import java.util.Set; public interface RulesDefinition extends ServerExtension { /** + * Default sub-characteristics of technical debt model. See http://www.sqale.org + */ + final class SubCharacteristics { + private SubCharacteristics() { + // only constants + } + + /** + * Related to characteristic REUSABILITY + */ + public static final String MODULARITY = "MODULARITY"; + + /** + * Related to characteristic REUSABILITY + */ + public static final String TRANSPORTABILITY = "TRANSPORTABILITY"; + + /** + * Related to characteristic PORTABILITY + */ + public static final String COMPILER_RELATED_PORTABILITY = "COMPILER_RELATED_PORTABILITY"; + + /** + * Related to characteristic PORTABILITY + */ + public static final String HARDWARE_RELATED_PORTABILITY = "HARDWARE_RELATED_PORTABILITY"; + + /** + * Related to characteristic PORTABILITY + */ + public static final String LANGUAGE_RELATED_PORTABILITY = "LANGUAGE_RELATED_PORTABILITY"; + + /** + * Related to characteristic PORTABILITY + */ + public static final String OS_RELATED_PORTABILITY = "OS_RELATED_PORTABILITY"; + + /** + * Related to characteristic PORTABILITY + */ + public static final String SOFTWARE_RELATED_PORTABILITY = "SOFTWARE_RELATED_PORTABILITY"; + + /** + * Related to characteristic PORTABILITY + */ + public static final String TIME_ZONE_RELATED_PORTABILITY = "TIME_ZONE_RELATED_PORTABILITY"; + + /** + * Related to characteristic MAINTAINABILITY + */ + public static final String READABILITY = "READABILITY"; + + /** + * Related to characteristic MAINTAINABILITY + */ + public static final String UNDERSTANDABILITY = "UNDERSTANDABILITY"; + + /** + * Related to characteristic SECURITY + */ + public static final String API_ABUSE = "API_ABUSE"; + + /** + * Related to characteristic SECURITY + */ + public static final String ERRORS = "ERRORS"; + + /** + * Related to characteristic SECURITY + */ + public static final String INPUT_VALIDATION_AND_REPRESENTATION = "INPUT_VALIDATION_AND_REPRESENTATION"; + + /** + * Related to characteristic SECURITY + */ + public static final String SECURITY_FEATURES = "SECURITY_FEATURES"; + + /** + * Related to characteristic EFFICIENCY + */ + public static final String CPU_EFFICIENCY = "CPU_EFFICIENCY"; + + /** + * Related to characteristic EFFICIENCY + */ + public static final String MEMORY_EFFICIENCY = "MEMORY_EFFICIENCY"; + + /** + * Related to characteristic EFFICIENCY + */ + public static final String NETWORK_USE = "NETWORK_USE"; + + /** + * Related to characteristic CHANGEABILITY + */ + public static final String ARCHITECTURE_CHANGEABILITY = "ARCHITECTURE_CHANGEABILITY"; + + /** + * Related to characteristic CHANGEABILITY + */ + public static final String DATA_CHANGEABILITY = "DATA_CHANGEABILITY"; + + /** + * Related to characteristic CHANGEABILITY + */ + public static final String LOGIC_CHANGEABILITY = "LOGIC_CHANGEABILITY"; + + /** + * Related to characteristic RELIABILITY + */ + public static final String ARCHITECTURE_RELIABILITY = "ARCHITECTURE_RELIABILITY"; + + /** + * Related to characteristic RELIABILITY + */ + public static final String DATA_RELIABILITY = "DATA_RELIABILITY"; + + /** + * Related to characteristic RELIABILITY + */ + public static final String EXCEPTION_HANDLING = "EXCEPTION_HANDLING"; + + /** + * Related to characteristic RELIABILITY + */ + public static final String FAULT_TOLERANCE = "FAULT_TOLERANCE"; + + /** + * Related to characteristic RELIABILITY + */ + public static final String INSTRUCTION_RELIABILITY = "INSTRUCTION_RELIABILITY"; + + /** + * Related to characteristic RELIABILITY + */ + public static final String LOGIC_RELIABILITY = "LOGIC_RELIABILITY"; + + /** + * Related to characteristic RELIABILITY + */ + public static final String RESOURCE_RELIABILITY = "RESOURCE_RELIABILITY"; + + /** + * Related to characteristic RELIABILITY + */ + public static final String SYNCHRONIZATION_RELIABILITY = "SYNCHRONIZATION_RELIABILITY"; + + /** + * Related to characteristic RELIABILITY + */ + public static final String UNIT_TESTS = "UNIT_TESTS"; + + /** + * Related to characteristic TESTABILITY + */ + public static final String INTEGRATION_TESTABILITY = "INTEGRATION_TESTABILITY"; + + /** + * Related to characteristic TESTABILITY + */ + public static final String UNIT_TESTABILITY = "UNIT_TESTABILITY"; + } + + /** * Instantiated by core but not by plugins */ class Context { @@ -186,28 +350,18 @@ public interface RulesDefinition extends ServerExtension { interface NewExtendedRepository { NewRule createRule(String ruleKey); - /** - * Reads definition of rule from the annotations provided by the library sonar-check-api. - */ - NewRule loadAnnotatedClass(Class clazz); + @CheckForNull + NewRule rule(String ruleKey); - /** - * Reads definitions of rules from the annotations provided by the library sonar-check-api. - */ - NewExtendedRepository loadAnnotatedClasses(Class... classes); + Collection<NewRule> rules(); + + String key(); void done(); } interface NewRepository extends NewExtendedRepository { NewRepository setName(String s); - - @CheckForNull - NewRule rule(String ruleKey); - - Collection<NewRule> rules(); - - String key(); } class NewRepositoryImpl implements NewRepository { @@ -263,17 +417,6 @@ public interface RulesDefinition extends ServerExtension { } @Override - public NewRepositoryImpl loadAnnotatedClasses(Class... classes) { - new RuleDefinitionsFromAnnotations().loadRules(this, classes); - return this; - } - - @Override - public RulesDefinition.NewRule loadAnnotatedClass(Class clazz) { - return new RuleDefinitionsFromAnnotations().loadRule(this, clazz); - } - - @Override public void done() { // note that some validations can be done here, for example for // verifying that at least one rule is declared @@ -362,6 +505,9 @@ public interface RulesDefinition extends ServerExtension { } } + /** + * Factory of {@link org.sonar.api.server.debt.DebtRemediationFunction}. + */ interface DebtRemediationFunctions { DebtRemediationFunction linear(String factor); @@ -393,7 +539,10 @@ public interface RulesDefinition extends ServerExtension { return this.key; } - public NewRule setName(@Nullable String s) { + /** + * Required rule name + */ + public NewRule setName(String s) { this.name = StringUtils.trim(s); return this; } @@ -432,6 +581,11 @@ public interface RulesDefinition extends ServerExtension { return this; } + /** + * Default value is {@link org.sonar.api.rule.RuleStatus#READY}. The value + * {@link org.sonar.api.rule.RuleStatus#REMOVED} is not accepted and raises an + * {@link java.lang.IllegalArgumentException}. + */ public NewRule setStatus(RuleStatus status) { if (status.equals(RuleStatus.REMOVED)) { throw new IllegalArgumentException(String.format("Status 'REMOVED' is not accepted on rule '%s'", this)); @@ -440,6 +594,11 @@ public interface RulesDefinition extends ServerExtension { return this; } + /** + * SQALE sub-characteristic. See http://www.sqale.org + * + * @see org.sonar.api.server.rule.RulesDefinition.SubCharacteristics for constant values + */ public NewRule setDebtSubCharacteristic(@Nullable String s) { this.debtSubCharacteristic = s; return this; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitionsFromAnnotations.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinitionAnnotationLoader.java index a5ad00af839..2a2585110d7 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitionsFromAnnotations.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinitionAnnotationLoader.java @@ -32,30 +32,27 @@ import org.sonar.api.utils.FieldUtils2; import org.sonar.check.Cardinality; import javax.annotation.CheckForNull; - import java.lang.reflect.Field; import java.util.List; /** - * Read definitions of rules based on the annotations provided by sonar-check-api. - * </p> - * It is internally used by {@link RulesDefinition} and can't be directly - * used by plugins. + * Read definitions of rules based on the annotations provided by sonar-check-api. It is used + * to feed {@link RulesDefinition}. * - * @since 4.2 + * @since 4.3 */ -class RuleDefinitionsFromAnnotations { +public class RulesDefinitionAnnotationLoader { - private static final Logger LOG = LoggerFactory.getLogger(RuleDefinitionsFromAnnotations.class); + private static final Logger LOG = LoggerFactory.getLogger(RulesDefinitionAnnotationLoader.class); - void loadRules(RulesDefinition.NewRepository repo, Class... annotatedClasses) { + public void load(RulesDefinition.NewExtendedRepository repo, Class... annotatedClasses) { for (Class annotatedClass : annotatedClasses) { loadRule(repo, annotatedClass); } } @CheckForNull - RulesDefinition.NewRule loadRule(RulesDefinition.NewRepository repo, Class clazz) { + RulesDefinition.NewRule loadRule(RulesDefinition.NewExtendedRepository repo, Class clazz) { org.sonar.check.Rule ruleAnnotation = AnnotationUtils.getAnnotation(clazz, org.sonar.check.Rule.class); if (ruleAnnotation != null) { return loadRule(repo, clazz, ruleAnnotation); @@ -65,7 +62,7 @@ class RuleDefinitionsFromAnnotations { } } - private RulesDefinition.NewRule loadRule(RulesDefinition.NewRepository repo, Class clazz, org.sonar.check.Rule ruleAnnotation) { + private RulesDefinition.NewRule loadRule(RulesDefinition.NewExtendedRepository repo, 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); @@ -114,7 +111,8 @@ class RuleDefinitionsFromAnnotations { .put(Boolean.class, RuleParamType.BOOLEAN) .put(boolean.class, RuleParamType.BOOLEAN) .build(), - RuleParamType.STRING); + RuleParamType.STRING + ); @VisibleForTesting static RuleParamType guessType(Class<?> type) { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java index f8e2c79ba44..48b04d938e9 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java @@ -26,6 +26,27 @@ import java.io.Writer; import java.util.Date; /** + * Writes JSON as a stream. This class allows plugins to not directly depend + * on the underlying JSON library. + * + * <h3>How to use</h3> + * <pre> + * StringWriter json = new StringWriter(); + * JsonWriter writer = JsonWriter.of(json); + * writer + * .beginObject() + * .prop("aBoolean", true) + * .prop("aInt", 123) + * .prop("aString", "foo") + * .beginObject().name("aList") + * .beginArray() + * .beginObject().prop("key", "ABC").endObject() + * .beginObject().prop("key", "DEF").endObject() + * .endArray() + * .endObject() + * .close(); + * </pre> + * * @since 4.2 */ public class JsonWriter { @@ -64,6 +85,7 @@ public class JsonWriter { /** * Ends encoding the current array. Output is <code>]</code>. + * * @throws org.sonar.api.utils.text.WriterException on any failure */ public JsonWriter endArray() { @@ -78,6 +100,7 @@ public class JsonWriter { /** * Begins encoding a new object. Each call to this method must be paired * with a call to {@link #endObject}. Output is <code>{</code>. + * * @throws org.sonar.api.utils.text.WriterException on any failure */ public JsonWriter beginObject() { @@ -91,6 +114,7 @@ public class JsonWriter { /** * Ends encoding the current object. Output is <code>}</code>. + * * @throws org.sonar.api.utils.text.WriterException on any failure */ public JsonWriter endObject() { @@ -104,6 +128,7 @@ public class JsonWriter { /** * Encodes the property name. Output is <code>"theName":</code>. + * * @throws org.sonar.api.utils.text.WriterException on any failure */ public JsonWriter name(String name) { @@ -117,6 +142,7 @@ public class JsonWriter { /** * Encodes {@code value}. Output is <code>true</code> or <code>false</code>. + * * @throws org.sonar.api.utils.text.WriterException on any failure */ public JsonWriter value(boolean value) { @@ -157,7 +183,7 @@ public class JsonWriter { */ public JsonWriter valueDate(@Nullable Date value) { try { - stream.value(value==null ? null : DateUtils.formatDate(value)); + stream.value(value == null ? null : DateUtils.formatDate(value)); return this; } catch (Exception e) { throw rethrow(e); @@ -166,7 +192,7 @@ public class JsonWriter { public JsonWriter valueDateTime(@Nullable Date value) { try { - stream.value(value==null ? null : DateUtils.formatDateTime(value)); + stream.value(value == null ? null : DateUtils.formatDateTime(value)); return this; } catch (Exception e) { throw rethrow(e); @@ -199,6 +225,7 @@ public class JsonWriter { /** * Encodes the property name and value. Output is for example <code>"theName":123</code>. + * * @throws org.sonar.api.utils.text.WriterException on any failure */ public JsonWriter prop(String name, @Nullable Number value) { @@ -208,6 +235,7 @@ public class JsonWriter { /** * Encodes the property name and date value (ISO format). * Output is for example <code>"theDate":"2013-01-24"</code>. + * * @throws org.sonar.api.utils.text.WriterException on any failure */ public JsonWriter propDate(String name, @Nullable Date value) { @@ -217,6 +245,7 @@ public class JsonWriter { /** * Encodes the property name and datetime value (ISO format). * Output is for example <code>"theDate":"2013-01-24T13:12:45+01"</code>. + * * @throws org.sonar.api.utils.text.WriterException on any failure */ public JsonWriter propDateTime(String name, @Nullable Date value) { diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionFromAnnotationsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionAnnotationLoaderTest.java index 65efa9d1258..da45d7d5dea 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionFromAnnotationsTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionAnnotationLoaderTest.java @@ -28,11 +28,13 @@ import org.sonar.check.Priority; import static org.fest.assertions.Assertions.assertThat; -public class RulesDefinitionFromAnnotationsTest { +public class RulesDefinitionAnnotationLoaderTest { @org.junit.Rule public final ExpectedException thrown = ExpectedException.none(); + RulesDefinitionAnnotationLoader annotationLoader = new RulesDefinitionAnnotationLoader(); + @Test public void rule_with_property() { RulesDefinition.Repository repository = load(RuleWithProperty.class); @@ -57,7 +59,7 @@ public class RulesDefinitionFromAnnotationsTest { public void override_annotation_programmatically() { RulesDefinition.Context context = new RulesDefinition.Context(); RulesDefinition.NewRepository newRepository = context.createRepository("squid", "java"); - NewRule newRule = newRepository.loadAnnotatedClass(RuleWithProperty.class); + NewRule newRule = annotationLoader.loadRule(newRepository, RuleWithProperty.class); newRule.setName("Overriden name"); newRule.param("property").setDefaultValue("true"); newRule.param("property").setDescription("Overriden"); @@ -102,14 +104,14 @@ public class RulesDefinitionFromAnnotationsTest { @Test public void should_recognize_type() { - assertThat(RuleDefinitionsFromAnnotations.guessType(Integer.class)).isEqualTo(RuleParamType.INTEGER); - assertThat(RuleDefinitionsFromAnnotations.guessType(int.class)).isEqualTo(RuleParamType.INTEGER); - assertThat(RuleDefinitionsFromAnnotations.guessType(Float.class)).isEqualTo(RuleParamType.FLOAT); - assertThat(RuleDefinitionsFromAnnotations.guessType(float.class)).isEqualTo(RuleParamType.FLOAT); - assertThat(RuleDefinitionsFromAnnotations.guessType(Boolean.class)).isEqualTo(RuleParamType.BOOLEAN); - assertThat(RuleDefinitionsFromAnnotations.guessType(boolean.class)).isEqualTo(RuleParamType.BOOLEAN); - assertThat(RuleDefinitionsFromAnnotations.guessType(String.class)).isEqualTo(RuleParamType.STRING); - assertThat(RuleDefinitionsFromAnnotations.guessType(Object.class)).isEqualTo(RuleParamType.STRING); + assertThat(RulesDefinitionAnnotationLoader.guessType(Integer.class)).isEqualTo(RuleParamType.INTEGER); + assertThat(RulesDefinitionAnnotationLoader.guessType(int.class)).isEqualTo(RuleParamType.INTEGER); + assertThat(RulesDefinitionAnnotationLoader.guessType(Float.class)).isEqualTo(RuleParamType.FLOAT); + assertThat(RulesDefinitionAnnotationLoader.guessType(float.class)).isEqualTo(RuleParamType.FLOAT); + assertThat(RulesDefinitionAnnotationLoader.guessType(Boolean.class)).isEqualTo(RuleParamType.BOOLEAN); + assertThat(RulesDefinitionAnnotationLoader.guessType(boolean.class)).isEqualTo(RuleParamType.BOOLEAN); + assertThat(RulesDefinitionAnnotationLoader.guessType(String.class)).isEqualTo(RuleParamType.STRING); + assertThat(RulesDefinitionAnnotationLoader.guessType(Object.class)).isEqualTo(RuleParamType.STRING); } @Test @@ -143,8 +145,8 @@ public class RulesDefinitionFromAnnotationsTest { private RulesDefinition.Repository load(Class annotatedClass) { RulesDefinition.Context context = new RulesDefinition.Context(); - RulesDefinition.NewExtendedRepository newRepository = context.createRepository("squid", "java") - .loadAnnotatedClasses(annotatedClass); + RulesDefinition.NewExtendedRepository newRepository = context.createRepository("squid", "java"); + annotationLoader.load(newRepository, annotatedClass); newRepository.done(); return context.repository("squid"); } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/text/JsonWriterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/text/JsonWriterTest.java index 3d1675168d5..ea9de6560d5 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/text/JsonWriterTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/text/JsonWriterTest.java @@ -23,8 +23,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.utils.DateUtils; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.utils.text.WriterException; import java.io.IOException; import java.io.StringWriter; |