diff options
author | Julien Lancelot <julien.lancelot@gmail.com> | 2013-03-26 18:12:39 +0100 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@gmail.com> | 2013-03-26 18:13:15 +0100 |
commit | 4689f87a0ad833bb9522fbde1896b3ab5fcb52c8 (patch) | |
tree | fc8be79d3fa5d36b2c1ee0d2fed688bcaddc0607 /sonar-plugin-api | |
parent | 996c779bd2b0336bbb3d207d0fb3c5bcaab18fca (diff) | |
download | sonarqube-4689f87a0ad833bb9522fbde1896b3ab5fcb52c8.tar.gz sonarqube-4689f87a0ad833bb9522fbde1896b3ab5fcb52c8.zip |
SONAR-3891 Update PropertyDefinition in order to be used directly to define properties (with builder pattern)
Diffstat (limited to 'sonar-plugin-api')
8 files changed, 650 insertions, 289 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java index 083b598d4da..be4ee0527e2 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java @@ -19,121 +19,95 @@ */ package org.sonar.api.config; +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; -import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; +import org.sonar.api.BatchComponent; import org.sonar.api.Property; import org.sonar.api.PropertyType; +import org.sonar.api.ServerComponent; +import org.sonar.api.resources.Qualifiers; import javax.annotation.Nullable; import java.util.List; +import static com.google.common.collect.Lists.newArrayList; + /** + * Property value can be set in different ways : + * <ul> + * <li>System property</li> + * <li>Maven command-line (-Dfoo=bar)</li> + * <li>Maven pom.xml (element <properties>)</li> + * <li>Maven settings.xml</li> + * <li>Sonar web interface</li> + * </ul> + * <p/> + * Value is accessible in batch extensions via the Configuration object of class <code>org.sonar.api.resources.Project</code> + * (see method <code>getConfiguration()</code>). + * <p/> + * <p><strong>Must be used in <code>org.sonar.api.Plugin</code> classes only.</strong></p> + * * @since 3.0 */ -public final class PropertyDefinition { - - public static final class Result { - private static final Result SUCCESS = new Result(null); - - private String errorKey = null; - - private static Result newError(String key) { - return new Result(key); - } - - @Nullable - private Result(@Nullable String errorKey) { - this.errorKey = errorKey; - } - - public boolean isValid() { - return StringUtils.isBlank(errorKey); - } - - @Nullable - public String getErrorKey() { - return errorKey; - } - } - - private final String key; - private final String defaultValue; - private final String name; - private final PropertyType type; - private final String[] options; - private final String description; - private final String category; - private final boolean onProject; - private final boolean onModule; - private final boolean isGlobal; - private final boolean multiValues; - private final String propertySetKey; - private final String deprecatedKey; - private final List<PropertyFieldDefinition> fields; - - private PropertyDefinition(Property annotation) { - this.key = annotation.key(); - this.name = annotation.name(); - this.defaultValue = annotation.defaultValue(); - this.description = annotation.description(); - this.isGlobal = annotation.global(); - this.onProject = annotation.project(); - this.onModule = annotation.module(); - this.category = annotation.category(); - this.type = fixType(annotation.key(), annotation.type()); - this.options = annotation.options(); - this.multiValues = annotation.multiValues(); - this.propertySetKey = annotation.propertySetKey(); - this.fields = ImmutableList.copyOf(PropertyFieldDefinition.create(annotation.fields())); - this.deprecatedKey = annotation.deprecatedKey(); - } - - private PropertyDefinition(String key, PropertyType type, String[] options) { - this.key = key; - this.name = null; - this.defaultValue = null; - this.description = null; - this.isGlobal = true; - this.onProject = false; - this.onModule = false; - this.category = null; - this.type = type; - this.options = options; - this.multiValues = false; - this.propertySetKey = null; - this.fields = null; - this.deprecatedKey = null; - } - - private static PropertyType fixType(String key, PropertyType type) { - // Auto-detect passwords and licenses for old versions of plugins that - // do not declare property types - if (type == PropertyType.STRING) { - if (StringUtils.endsWith(key, ".password.secured")) { - return PropertyType.PASSWORD; - } else if (StringUtils.endsWith(key, ".license.secured")) { - return PropertyType.LICENSE; - } - } - return type; +public final class PropertyDefinition implements BatchComponent, ServerComponent { + + private String key; + private String defaultValue; + private String name; + private PropertyType type; + private List<String> options; + private String description; + private String category; + private List<String> qualifiers; + private boolean global; + private boolean multiValues; + private String propertySetKey; + private String deprecatedKey; + private List<PropertyFieldDefinition> fields; + + private PropertyDefinition(Builder builder) { + this.key = builder.key; + this.name = builder.name; + this.description = builder.description; + this.defaultValue = builder.defaultValue; + this.category = builder.category; + this.global = builder.global; + this.type = builder.type; + this.options = builder.options; + this.multiValues = builder.multiValues; + this.propertySetKey = builder.propertySetKey; + this.fields = builder.fields; + this.deprecatedKey = builder.deprecatedKey; + this.qualifiers = builder.qualifiers; } - public static PropertyDefinition create(Property annotation) { - return new PropertyDefinition(annotation); + public static Builder build(String key) { + return new Builder(key); } - public static PropertyDefinition create(String key, PropertyType type, String[] options) { - return new PropertyDefinition(key, type, options); + static PropertyDefinition create(Property annotation) { + return PropertyDefinition.build(annotation.key()) + .name(annotation.name()) + .defaultValue(annotation.defaultValue()) + .description(annotation.description()) + .global(annotation.global()) + .project(annotation.project()) + .module(annotation.module()) + .category(annotation.category()) + .type(annotation.type()) + .options(annotation.options()) + .multiValues(annotation.multiValues()) + .propertySetKey(annotation.propertySetKey()) + .fields(PropertyFieldDefinition.create(annotation.fields())) + .deprecatedKey(annotation.deprecatedKey()) + .build(); } - public Result validate(@Nullable String value) { - return validate(type, value, options); - } - - static Result validate(PropertyType type, @Nullable String value, String[] options) { + public static Result validate(PropertyType type, @Nullable String value, List<String> options) { if (StringUtils.isNotBlank(value)) { if (type == PropertyType.BOOLEAN) { if (!StringUtils.equalsIgnoreCase(value, "true") && !StringUtils.equalsIgnoreCase(value, "false")) { @@ -150,7 +124,7 @@ public final class PropertyDefinition { return Result.newError("notFloat"); } } else if (type == PropertyType.SINGLE_SELECT_LIST) { - if (!ArrayUtils.contains(options, value)) { + if (!options.contains(value)) { return Result.newError("notInOptions"); } } @@ -158,71 +132,273 @@ public final class PropertyDefinition { return Result.SUCCESS; } - public String getKey() { + public Result validate(@Nullable String value) { + return validate(type, value, options); + } + + /** + * Unique key within all plugins. It's recommended to prefix the key by 'sonar.' and the plugin name. Examples : + * 'sonar.cobertura.reportPath' and 'sonar.cpd.minimumTokens'. + */ + public String key() { return key; } - public String getDefaultValue() { + public String defaultValue() { return defaultValue; } - public String getName() { + public String name() { return name; } - public PropertyType getType() { + public PropertyType type() { return type; } - public String[] getOptions() { - return options.clone(); + /** + * Options for *_LIST types + * <p/> + * Options for property of type PropertyType.SINGLE_SELECT_LIST</code> + * For example {"property_1", "property_3", "property_3"}). + * <p/> + * Options for property of type PropertyType.METRIC</code>. + * If no option is specified, any metric will match. + * If options are specified, all must match for the metric to be displayed. + * Three types of filter are supported <code>key:REGEXP</code>, <code>domain:REGEXP</code> and <code>type:comma_separated__list_of_types</code>. + * For example <code>key:new_.*</code> will match any metric which key starts by <code>new_</code>. + * For example <code>type:INT,FLOAT</code> will match any metric of type <code>INT</code> or <code>FLOAT</code>. + * For example <code>type:NUMERIC</code> will match any metric of numerictype. + */ + public List<String> options() { + return options; } - public String getDescription() { + public String description() { return description; } - public String getCategory() { + public String category() { return category; } - public boolean isOnProject() { - return onProject; + /** + * Is the property displayed in project settings page ? + */ + public boolean project() { + return qualifiers.contains(Qualifiers.PROJECT); + } + + /** + * Is the property displayed in module settings page ? A module is a maven sub-project. + */ + public boolean module() { + return qualifiers.contains(Qualifiers.MODULE); } - public boolean isOnModule() { - return onModule; + /** + * Qualifiers that can display this property + * + * @since 3.6 + */ + public List<String> qualifiers() { + return qualifiers; } - public boolean isGlobal() { - return isGlobal; + /** + * Is the property displayed in global settings page ? + */ + public boolean global() { + return global; } /** * @since 3.3 */ - public boolean isMultiValues() { + public boolean multiValues() { return multiValues; } /** * @since 3.3 */ - public String getPropertySetKey() { + public String propertySetKey() { return propertySetKey; } /** * @since 3.3 */ - public List<PropertyFieldDefinition> getFields() { + public List<PropertyFieldDefinition> fields() { return fields; } /** * @since 3.4 */ - public String getDeprecatedKey() { + public String deprecatedKey() { return deprecatedKey; } + + public static final class Result { + private static final Result SUCCESS = new Result(null); + private String errorKey = null; + + @Nullable + private Result(@Nullable String errorKey) { + this.errorKey = errorKey; + } + + private static Result newError(String key) { + return new Result(key); + } + + public boolean isValid() { + return StringUtils.isBlank(errorKey); + } + + @Nullable + public String getErrorKey() { + return errorKey; + } + } + + public static class Builder { + private String key; + private String name; + private String description; + private String defaultValue; + private String category; + private List<String> qualifiers; + private boolean global; + private PropertyType type; + private List<String> options; + private boolean multiValues; + private String propertySetKey; + private List<PropertyFieldDefinition> fields; + private String deprecatedKey; + + private Builder(String key) { + this.key = key; + this.name = ""; + this.description = ""; + this.defaultValue = ""; + this.category = ""; + this.propertySetKey = ""; + this.deprecatedKey = ""; + this.global = true; + this.type = PropertyType.STRING; + this.qualifiers = newArrayList(); + this.options = newArrayList(); + this.fields = newArrayList(); + } + + public Builder description(String description) { + this.description = description; + return this; + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder defaultValue(String defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + public Builder category(String category) { + this.category = category; + return this; + } + + public Builder qualifiers(String... qualifiers) { + this.qualifiers.addAll(newArrayList(qualifiers)); + return this; + } + + public Builder project(boolean displayOnProject) { + if (displayOnProject) { + this.qualifiers.add(Qualifiers.PROJECT); + } else { + this.qualifiers.remove(Qualifiers.PROJECT); + } + return this; + } + + public Builder module(boolean displayOnModule) { + if (displayOnModule) { + this.qualifiers.add(Qualifiers.MODULE); + } else { + this.qualifiers.remove(Qualifiers.MODULE); + } + return this; + } + + public Builder global(boolean global) { + this.global = global; + return this; + } + + public Builder type(PropertyType type) { + this.type = type; + return this; + } + + public Builder options(String... options) { + this.options.addAll(ImmutableList.copyOf(options)); + return this; + } + + public Builder options(List<String> options) { + this.options.addAll(ImmutableList.copyOf(options)); + return this; + } + + public Builder multiValues(boolean multiValues) { + this.multiValues = multiValues; + return this; + } + + public Builder propertySetKey(String propertySetKey) { + this.propertySetKey = propertySetKey; + return this; + } + + public Builder fields(PropertyFieldDefinition... fields) { + this.fields.addAll(ImmutableList.copyOf(fields)); + return this; + } + + public Builder fields(List<PropertyFieldDefinition> fields) { + this.fields.addAll(ImmutableList.copyOf(fields)); + return this; + } + + public Builder deprecatedKey(String deprecatedKey) { + this.deprecatedKey = deprecatedKey; + return this; + } + + public PropertyDefinition build() { + Preconditions.checkArgument(!Strings.isNullOrEmpty(key), "Key must be set"); + Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "Name must be set"); + fixType(key, type); + return new PropertyDefinition(this); + } + + private void fixType(String key, PropertyType type) { + // Auto-detect passwords and licenses for old versions of plugins that + // do not declare property types + if (type == PropertyType.STRING) { + if (StringUtils.endsWith(key, ".password.secured")) { + this.type = PropertyType.PASSWORD; + } else if (StringUtils.endsWith(key, ".license.secured")) { + this.type = PropertyType.LICENSE; + } + } + } + } + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinitions.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinitions.java index 58820d07115..e7e2fb96c64 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinitions.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinitions.java @@ -69,6 +69,15 @@ public final class PropertyDefinitions implements BatchComponent, ServerComponen } public PropertyDefinitions addComponent(Object component, String defaultCategory) { + addComponentFromAnnotationPropety(component, defaultCategory); + if (component instanceof PropertyDefinition) { + PropertyDefinition propertyDefinition = (PropertyDefinition) component; + add(propertyDefinition, defaultCategory); + } + return this; + } + + private PropertyDefinitions addComponentFromAnnotationPropety(Object component, String defaultCategory){ Properties annotations = AnnotationUtils.getAnnotation(component, Properties.class); if (annotations != null) { for (Property property : annotations.value()) { @@ -88,11 +97,11 @@ public final class PropertyDefinitions implements BatchComponent, ServerComponen } private PropertyDefinitions add(PropertyDefinition definition, String defaultCategory) { - if (!definitions.containsKey(definition.getKey())) { - definitions.put(definition.getKey(), definition); - categories.put(definition.getKey(), StringUtils.defaultIfBlank(definition.getCategory(), defaultCategory)); - if (!Strings.isNullOrEmpty(definition.getDeprecatedKey()) && !definition.getDeprecatedKey().equals(definition.getKey())) { - deprecatedKeys.put(definition.getDeprecatedKey(), definition.getKey()); + if (!definitions.containsKey(definition.key())) { + definitions.put(definition.key(), definition); + categories.put(definition.key(), StringUtils.defaultIfBlank(definition.category(), defaultCategory)); + if (!Strings.isNullOrEmpty(definition.deprecatedKey()) && !definition.deprecatedKey().equals(definition.key())) { + deprecatedKeys.put(definition.deprecatedKey(), definition.key()); } } return this; @@ -114,19 +123,19 @@ public final class PropertyDefinitions implements BatchComponent, ServerComponen GLOBAL { @Override boolean accept(PropertyDefinition propertyDefinition) { - return propertyDefinition.isGlobal(); + return propertyDefinition.global(); } }, PROJECT { @Override boolean accept(PropertyDefinition propertyDefinition) { - return propertyDefinition.isOnProject(); + return propertyDefinition.project(); } }, MODULE { @Override boolean accept(PropertyDefinition propertyDefinition) { - return propertyDefinition.isOnModule(); + return propertyDefinition.module(); } }; @@ -138,7 +147,7 @@ public final class PropertyDefinitions implements BatchComponent, ServerComponen for (PropertyDefinition definition : getAll()) { if (filter.accept(definition)) { - byCategory.put(getCategory(definition.getKey()), definition); + byCategory.put(getCategory(definition.key()), definition); } } @@ -171,7 +180,7 @@ public final class PropertyDefinitions implements BatchComponent, ServerComponen if (def == null) { return null; } - return StringUtils.defaultIfEmpty(def.getDefaultValue(), null); + return StringUtils.defaultIfEmpty(def.defaultValue(), null); } public String getCategory(String key) { @@ -191,6 +200,6 @@ public final class PropertyDefinitions implements BatchComponent, ServerComponen if (def == null) { return null; } - return StringUtils.defaultIfEmpty(def.getDeprecatedKey(), null); + return StringUtils.defaultIfEmpty(def.deprecatedKey(), null); } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyFieldDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyFieldDefinition.java index 05fbea9cf7e..b71ff860ec9 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyFieldDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyFieldDefinition.java @@ -19,7 +19,9 @@ */ package org.sonar.api.config; -import com.google.common.collect.Lists; +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableList; import org.sonar.api.PropertyField; import org.sonar.api.PropertyType; @@ -27,6 +29,8 @@ import javax.annotation.Nullable; import java.util.List; +import static com.google.common.collect.Lists.newArrayList; + /** * @since 3.3 */ @@ -36,50 +40,115 @@ public final class PropertyFieldDefinition { private final String description; private final int indicativeSize; private final PropertyType type; - private final String[] options; - - private PropertyFieldDefinition(PropertyField annotation) { - this.key = annotation.key(); - this.name = annotation.name(); - this.description = annotation.description(); - this.indicativeSize = annotation.indicativeSize(); - this.type = annotation.type(); - this.options = annotation.options(); + private final List<String> options; + + private PropertyFieldDefinition(Builder builder) { + this.key = builder.key; + this.name = builder.name; + this.description = builder.description; + this.indicativeSize = builder.indicativeSize; + this.type = builder.type; + this.options = builder.options; } - public static List<PropertyFieldDefinition> create(PropertyField[] fields) { - List<PropertyFieldDefinition> definitions = Lists.newArrayList(); + static List<PropertyFieldDefinition> create(PropertyField[] fields) { + List<PropertyFieldDefinition> definitions = newArrayList(); for (PropertyField field : fields) { - definitions.add(new PropertyFieldDefinition(field)); + definitions.add(PropertyFieldDefinition.build(field.key()) + .name(field.name()) + .description(field.description()) + .indicativeSize(field.indicativeSize()) + .type(field.type()) + .options(field.options()) + .build() + ); } return definitions; } - public String getKey() { + public static Builder build(String key) { + return new Builder(key); + } + + public String key() { return key; } - public String getName() { + public String name() { return name; } - public String getDescription() { + public String description() { return description; } - public int getIndicativeSize() { + public int indicativeSize() { return indicativeSize; } - public PropertyType getType() { + public PropertyType type() { return type; } - public String[] getOptions() { - return options.clone(); + public List<String> options() { + return options; } public PropertyDefinition.Result validate(@Nullable String value) { return PropertyDefinition.validate(type, value, options); } + + public static class Builder { + private String key; + private String name; + private String description; + private int indicativeSize; + private PropertyType type; + private List<String> options; + + private Builder(String key) { + this.key = key; + this.name = ""; + this.description = ""; + this.indicativeSize = 20; + this.type = PropertyType.STRING; + this.options = newArrayList(); + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder description(String description) { + this.description = description; + return this; + } + + public Builder indicativeSize(int indicativeSize) { + this.indicativeSize = indicativeSize; + return this; + } + + public Builder type(PropertyType type) { + this.type = type; + return this; + } + + public Builder options(String... options) { + this.options.addAll(ImmutableList.copyOf(options)); + return this; + } + + public Builder options(List<String> options) { + this.options.addAll(ImmutableList.copyOf(options)); + return this; + } + + public PropertyFieldDefinition build() { + Preconditions.checkArgument(!Strings.isNullOrEmpty(key), "Key must be set"); + Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "Name must be set"); + return new PropertyFieldDefinition(this); + } + } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java index 1a9c2ffc975..d51c5efcfac 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java @@ -191,7 +191,7 @@ public class Settings implements BatchComponent, ServerComponent { */ public String[] getStringArray(String key) { PropertyDefinition property = getDefinitions().get(key); - if ((null != property) && (property.isMultiValues())) { + if ((null != property) && (property.multiValues())) { String value = getString(key); if (value == null) { return ArrayUtils.EMPTY_STRING_ARRAY; @@ -259,7 +259,7 @@ public class Settings implements BatchComponent, ServerComponent { public Settings setProperty(String key, @Nullable String[] values) { PropertyDefinition property = getDefinitions().get(key); - if ((null == property) || (!property.isMultiValues())) { + if ((null == property) || (!property.multiValues())) { throw new IllegalStateException("Fail to set multiple values on a single value property " + key); } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionTest.java index a0b2295f98b..b849e2951a5 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionTest.java @@ -19,101 +19,161 @@ */ package org.sonar.api.config; -import org.sonar.api.PropertyField; - import org.junit.Test; import org.sonar.api.Properties; import org.sonar.api.Property; +import org.sonar.api.PropertyField; import org.sonar.api.PropertyType; +import org.sonar.api.resources.Qualifiers; import org.sonar.api.utils.AnnotationUtils; import static org.fest.assertions.Assertions.assertThat; public class PropertyDefinitionTest { + @Test - public void createFromAnnotation() { + public void should_create_property() { + PropertyDefinition def = PropertyDefinition.build("hello") + .name("Hello") + .defaultValue("world") + .category("categ") + .options("de", "en") + .description("desc") + .type(PropertyType.FLOAT) + .global(false) + .qualifiers(Qualifiers.FILE, Qualifiers.CLASS) + .multiValues(true) + .propertySetKey("set") + .build(); + + assertThat(def.key()).isEqualTo("hello"); + assertThat(def.name()).isEqualTo("Hello"); + assertThat(def.defaultValue()).isEqualTo("world"); + assertThat(def.category()).isEqualTo("categ"); + assertThat(def.options()).containsOnly("de", "en"); + assertThat(def.description()).isEqualTo("desc"); + assertThat(def.type()).isEqualTo(PropertyType.FLOAT); + assertThat(def.global()).isFalse(); + assertThat(def.qualifiers()).containsOnly(Qualifiers.FILE, Qualifiers.CLASS); + assertThat(def.multiValues()).isTrue(); + assertThat(def.propertySetKey()).isEqualTo("set"); + assertThat(def.fields()).isEmpty(); + } + + @Test + public void should_create_from_annotation() { Properties props = AnnotationUtils.getAnnotation(Init.class, Properties.class); Property prop = props.value()[0]; PropertyDefinition def = PropertyDefinition.create(prop); - assertThat(def.getKey()).isEqualTo("hello"); - assertThat(def.getName()).isEqualTo("Hello"); - assertThat(def.getDefaultValue()).isEqualTo("world"); - assertThat(def.getCategory()).isEqualTo("categ"); - assertThat(def.getOptions()).hasSize(2); - assertThat(def.getOptions()).contains("de", "en"); - assertThat(def.getDescription()).isEqualTo("desc"); - assertThat(def.getType()).isEqualTo(PropertyType.FLOAT); - assertThat(def.isGlobal()).isFalse(); - assertThat(def.isOnProject()).isTrue(); - assertThat(def.isOnModule()).isTrue(); - assertThat(def.isMultiValues()).isTrue(); - assertThat(def.getPropertySetKey()).isEqualTo("set"); - assertThat(def.getFields()).isEmpty(); + assertThat(def.key()).isEqualTo("hello"); + assertThat(def.name()).isEqualTo("Hello"); + assertThat(def.defaultValue()).isEqualTo("world"); + assertThat(def.category()).isEqualTo("categ"); + assertThat(def.options()).containsOnly("de", "en"); + assertThat(def.description()).isEqualTo("desc"); + assertThat(def.type()).isEqualTo(PropertyType.FLOAT); + assertThat(def.global()).isFalse(); + assertThat(def.project()).isTrue(); + assertThat(def.module()).isTrue(); + assertThat(def.multiValues()).isTrue(); + assertThat(def.propertySetKey()).isEqualTo("set"); + assertThat(def.fields()).isEmpty(); } - @Properties(@Property(key = "hello", name = "Hello", defaultValue = "world", description = "desc", - options = {"de", "en"}, category = "categ", type = PropertyType.FLOAT, global = false, project = true, module = true, multiValues = true, propertySetKey = "set")) - static class Init { + @Test + public void should_create_property_with_default_values() { + PropertyDefinition def = PropertyDefinition.build("hello") + .name("Hello") + .build(); + + assertThat(def.key()).isEqualTo("hello"); + assertThat(def.name()).isEqualTo("Hello"); + assertThat(def.defaultValue()).isEmpty(); + assertThat(def.category()).isEmpty(); + assertThat(def.options()).isEmpty(); + assertThat(def.description()).isEmpty(); + assertThat(def.type()).isEqualTo(PropertyType.STRING); + assertThat(def.global()).isTrue(); + assertThat(def.qualifiers()).isEmpty(); + assertThat(def.project()).isFalse(); + assertThat(def.module()).isFalse(); + assertThat(def.multiValues()).isFalse(); + assertThat(def.propertySetKey()).isEmpty(); + assertThat(def.fields()).isEmpty(); } @Test - public void createFromAnnotation_default_values() { + public void should_create_from_annotation_default_values() { Properties props = AnnotationUtils.getAnnotation(DefaultValues.class, Properties.class); Property prop = props.value()[0]; PropertyDefinition def = PropertyDefinition.create(prop); - assertThat(def.getKey()).isEqualTo("hello"); - assertThat(def.getName()).isEqualTo("Hello"); - assertThat(def.getDefaultValue()).isEmpty(); - assertThat(def.getCategory()).isEmpty(); - assertThat(def.getOptions()).isEmpty(); - assertThat(def.getDescription()).isEmpty(); - assertThat(def.getType()).isEqualTo(PropertyType.STRING); - assertThat(def.isGlobal()).isTrue(); - assertThat(def.isOnProject()).isFalse(); - assertThat(def.isOnModule()).isFalse(); - assertThat(def.isMultiValues()).isFalse(); - assertThat(def.getPropertySetKey()).isEmpty(); - assertThat(def.getFields()).isEmpty(); + assertThat(def.key()).isEqualTo("hello"); + assertThat(def.name()).isEqualTo("Hello"); + assertThat(def.defaultValue()).isEmpty(); + assertThat(def.category()).isEmpty(); + assertThat(def.options()).isEmpty(); + assertThat(def.description()).isEmpty(); + assertThat(def.type()).isEqualTo(PropertyType.STRING); + assertThat(def.global()).isTrue(); + assertThat(def.project()).isFalse(); + assertThat(def.module()).isFalse(); + assertThat(def.multiValues()).isFalse(); + assertThat(def.propertySetKey()).isEmpty(); + assertThat(def.fields()).isEmpty(); } - @Properties(@Property(key = "hello", name = "Hello", fields = { - @PropertyField(key = "first", name = "First", description = "Description", options = {"A", "B"}), - @PropertyField(key = "second", name = "Second", type = PropertyType.INTEGER, indicativeSize = 5)})) - static class WithPropertySet { + @Test + public void should_support_property_sets() { + PropertyDefinition def = PropertyDefinition.build("hello") + .name("Hello") + .fields( + PropertyFieldDefinition.build("first").name("First").description("Description").options("A", "B").build(), + PropertyFieldDefinition.build("second").name("Second").type(PropertyType.INTEGER).indicativeSize(5).build() + ) + .build(); + + assertThat(def.fields()).hasSize(2); + assertThat(def.fields().get(0).key()).isEqualTo("first"); + assertThat(def.fields().get(0).name()).isEqualTo("First"); + assertThat(def.fields().get(0).description()).isEqualTo("Description"); + assertThat(def.fields().get(0).type()).isEqualTo(PropertyType.STRING); + assertThat(def.fields().get(0).options()).containsOnly("A", "B"); + assertThat(def.fields().get(0).indicativeSize()).isEqualTo(20); + assertThat(def.fields().get(1).key()).isEqualTo("second"); + assertThat(def.fields().get(1).name()).isEqualTo("Second"); + assertThat(def.fields().get(1).type()).isEqualTo(PropertyType.INTEGER); + assertThat(def.fields().get(1).options()).isEmpty(); + assertThat(def.fields().get(1).indicativeSize()).isEqualTo(5); } @Test - public void should_support_property_sets() { + public void should_support_property_sets_from_annotation() { Properties props = AnnotationUtils.getAnnotation(WithPropertySet.class, Properties.class); Property prop = props.value()[0]; PropertyDefinition def = PropertyDefinition.create(prop); - assertThat(def.getFields()).hasSize(2); - assertThat(def.getFields().get(0).getKey()).isEqualTo("first"); - assertThat(def.getFields().get(0).getName()).isEqualTo("First"); - assertThat(def.getFields().get(0).getDescription()).isEqualTo("Description"); - assertThat(def.getFields().get(0).getType()).isEqualTo(PropertyType.STRING); - assertThat(def.getFields().get(0).getOptions()).containsOnly("A", "B"); - assertThat(def.getFields().get(0).getIndicativeSize()).isEqualTo(20); - assertThat(def.getFields().get(1).getKey()).isEqualTo("second"); - assertThat(def.getFields().get(1).getName()).isEqualTo("Second"); - assertThat(def.getFields().get(1).getType()).isEqualTo(PropertyType.INTEGER); - assertThat(def.getFields().get(1).getOptions()).isEmpty(); - assertThat(def.getFields().get(1).getIndicativeSize()).isEqualTo(5); - } - - @Properties(@Property(key = "hello", name = "Hello")) - static class DefaultValues { + assertThat(def.fields()).hasSize(2); + assertThat(def.fields().get(0).key()).isEqualTo("first"); + assertThat(def.fields().get(0).name()).isEqualTo("First"); + assertThat(def.fields().get(0).description()).isEqualTo("Description"); + assertThat(def.fields().get(0).type()).isEqualTo(PropertyType.STRING); + assertThat(def.fields().get(0).options()).containsOnly("A", "B"); + assertThat(def.fields().get(0).indicativeSize()).isEqualTo(20); + assertThat(def.fields().get(1).key()).isEqualTo("second"); + assertThat(def.fields().get(1).name()).isEqualTo("Second"); + assertThat(def.fields().get(1).type()).isEqualTo(PropertyType.INTEGER); + assertThat(def.fields().get(1).options()).isEmpty(); + assertThat(def.fields().get(1).indicativeSize()).isEqualTo(5); } @Test - public void validate_string() { - PropertyDefinition def = PropertyDefinition.create("foo", PropertyType.STRING, new String[0]); + public void should_validate_string() { + PropertyDefinition def = PropertyDefinition.build("foo").name("foo").type(PropertyType.STRING).build(); assertThat(def.validate(null).isValid()).isTrue(); assertThat(def.validate("").isValid()).isTrue(); @@ -122,8 +182,8 @@ public class PropertyDefinitionTest { } @Test - public void validate_boolean() { - PropertyDefinition def = PropertyDefinition.create("foo", PropertyType.BOOLEAN, new String[0]); + public void should_validate_boolean() { + PropertyDefinition def = PropertyDefinition.build("foo").name("foo").type(PropertyType.BOOLEAN).build(); assertThat(def.validate(null).isValid()).isTrue(); assertThat(def.validate("").isValid()).isTrue(); @@ -136,8 +196,8 @@ public class PropertyDefinitionTest { } @Test - public void validate_integer() { - PropertyDefinition def = PropertyDefinition.create("foo", PropertyType.INTEGER, new String[0]); + public void should_validate_integer() { + PropertyDefinition def = PropertyDefinition.build("foo").name("foo").type(PropertyType.INTEGER).build(); assertThat(def.validate(null).isValid()).isTrue(); assertThat(def.validate("").isValid()).isTrue(); @@ -149,8 +209,8 @@ public class PropertyDefinitionTest { } @Test - public void validate_float() { - PropertyDefinition def = PropertyDefinition.create("foo", PropertyType.FLOAT, new String[0]); + public void should_validate_float() { + PropertyDefinition def = PropertyDefinition.build("foo").name("foo").type(PropertyType.FLOAT).build(); assertThat(def.validate(null).isValid()).isTrue(); assertThat(def.validate("").isValid()).isTrue(); @@ -163,8 +223,8 @@ public class PropertyDefinitionTest { } @Test - public void validate_single_select_list() { - PropertyDefinition def = PropertyDefinition.create("foo", PropertyType.SINGLE_SELECT_LIST, new String[]{"de", "en"}); + public void should_validate_single_select_list() { + PropertyDefinition def = PropertyDefinition.build("foo").name("foo").type(PropertyType.SINGLE_SELECT_LIST).options("de", "en").build(); assertThat(def.validate(null).isValid()).isTrue(); assertThat(def.validate("").isValid()).isTrue(); @@ -176,33 +236,35 @@ public class PropertyDefinitionTest { assertThat(def.validate("fr").getErrorKey()).isEqualTo("notInOptions"); } - @Properties(@Property(key = "scm.password.secured", name = "SCM password")) - static class OldScmPlugin { + @Test + public void should_auto_detect_password_type() { + PropertyDefinition def = PropertyDefinition.build("scm.password.secured").name("SCM password").build(); + + assertThat(def.key()).isEqualTo("scm.password.secured"); + assertThat(def.type()).isEqualTo(PropertyType.PASSWORD); } @Test - public void autoDetectPasswordType() { - Properties props = AnnotationUtils.getAnnotation(OldScmPlugin.class, Properties.class); - Property prop = props.value()[0]; + public void should_auto_detect_license_type() { + PropertyDefinition def = PropertyDefinition.build("views.license.secured").name("Views license").build(); - PropertyDefinition def = PropertyDefinition.create(prop); - - assertThat(def.getKey()).isEqualTo("scm.password.secured"); - assertThat(def.getType()).isEqualTo(PropertyType.PASSWORD); + assertThat(def.key()).isEqualTo("views.license.secured"); + assertThat(def.type()).isEqualTo(PropertyType.LICENSE); } - @Properties(@Property(key = "views.license.secured", name = "Views license")) - static class ViewsPlugin { + @Properties(@Property(key = "hello", name = "Hello", defaultValue = "world", description = "desc", + options = {"de", "en"}, category = "categ", type = PropertyType.FLOAT, global = false, project = true, module = true, multiValues = true, propertySetKey = "set")) + static class Init { } - @Test - public void autoDetectLicenseType() { - Properties props = AnnotationUtils.getAnnotation(ViewsPlugin.class, Properties.class); - Property prop = props.value()[0]; - - PropertyDefinition def = PropertyDefinition.create(prop); + @Properties(@Property(key = "hello", name = "Hello", fields = { + @PropertyField(key = "first", name = "First", description = "Description", options = {"A", "B"}), + @PropertyField(key = "second", name = "Second", type = PropertyType.INTEGER, indicativeSize = 5)})) + static class WithPropertySet { + } - assertThat(def.getKey()).isEqualTo("views.license.secured"); - assertThat(def.getType()).isEqualTo(PropertyType.LICENSE); + @Properties(@Property(key = "hello", name = "Hello")) + static class DefaultValues { } + } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionsTest.java index 9f30157e3bd..fbc5045b586 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionsTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/config/PropertyDefinitionsTest.java @@ -24,73 +24,88 @@ import org.sonar.api.Properties; import org.sonar.api.Property; import static org.fest.assertions.Assertions.assertThat; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; public class PropertyDefinitionsTest { @Test - public void shouldInspectPluginObjects() { - PropertyDefinitions def = new PropertyDefinitions(new PluginWithProperty(), new PluginWithProperties()); + public void should_inspect_plugin_objects() { + PropertyDefinitions def = new PropertyDefinitions( + PropertyDefinition.build("foo").name("Foo").build(), + PropertyDefinition.build("one").name("One").build(), + PropertyDefinition.build("two").name("Two").defaultValue("2").build() + ); assertProperties(def); } @Test - public void shouldInspectPluginClasses() { - PropertyDefinitions def = new PropertyDefinitions(PluginWithProperty.class, PluginWithProperties.class); + public void should_inspect_annotation_plugin_objects() { + PropertyDefinitions def = new PropertyDefinitions(new PluginWithProperty(), new PluginWithProperties()); assertProperties(def); } - private void assertProperties(PropertyDefinitions definitions) { - assertThat(definitions.get("foo").getName(), is("Foo")); - assertThat(definitions.get("one").getName(), is("One")); - assertThat(definitions.get("two").getName(), is("Two")); - assertThat(definitions.get("unknown"), nullValue()); - - assertThat(definitions.getDefaultValue("foo"), nullValue()); - assertThat(definitions.getDefaultValue("two"), is("2")); + @Test + public void should_inspect_plugin_classes() { + PropertyDefinitions def = new PropertyDefinitions(PluginWithProperty.class, PluginWithProperties.class); - assertThat(definitions.getAll().size(), is(3)); + assertProperties(def); } - @Property(key = "foo", name = "Foo") - static final class PluginWithProperty { + @Test + public void test_categories() { + PropertyDefinitions def = new PropertyDefinitions( + PropertyDefinition.build("inCateg").name("In Categ").category("categ").build(), + PropertyDefinition.build("noCateg").name("No categ").build() + ); + + assertThat(def.getCategory("inCateg")).isEqualTo("categ"); + assertThat(def.getCategory("noCateg")).isEmpty(); } - @Properties({ - @Property(key = "one", name = "One"), - @Property(key = "two", name = "Two", defaultValue = "2") - }) - static final class PluginWithProperties { + @Test + public void test_categories_on_annotation_plugin() { + PropertyDefinitions def = new PropertyDefinitions(Categories.class); + + assertThat(def.getCategory("inCateg")).isEqualTo("categ"); + assertThat(def.getCategory("noCateg")).isEqualTo(""); } @Test - public void testCategories() { - PropertyDefinitions def = new PropertyDefinitions(Categories.class); - assertThat(def.getCategory("inCateg"), is("categ")); - assertThat(def.getCategory("noCateg"), is("")); + public void test_default_category() { + PropertyDefinitions def = new PropertyDefinitions(); + def.addComponent(PropertyDefinition.build("inCateg").name("In Categ").category("categ").build(), "default"); + def.addComponent(PropertyDefinition.build("noCateg").name("No categ").build(), "default"); + + assertThat(def.getCategory("inCateg")).isEqualTo("categ"); + assertThat(def.getCategory("noCateg")).isEqualTo("default"); } @Test - public void testDefaultCategory() { + public void test_default_category_on_annotation_plugin() { PropertyDefinitions def = new PropertyDefinitions(); def.addComponent(Categories.class, "default"); - assertThat(def.getCategory("inCateg"), is("categ")); - assertThat(def.getCategory("noCateg"), is("default")); + assertThat(def.getCategory("inCateg")).isEqualTo("categ"); + assertThat(def.getCategory("noCateg")).isEqualTo("default"); } - @Properties({ - @Property(key = "inCateg", name = "In Categ", category = "categ"), - @Property(key = "noCateg", name = "No categ") - }) - static final class Categories { + @Test + public void should_group_by_category() { + PropertyDefinitions def = new PropertyDefinitions( + PropertyDefinition.build("global1").name("Global1").category("catGlobal1").global(true).project(false).module(false).build(), + PropertyDefinition.build("global2").name("Global2").category("catGlobal1").global(true).project(false).module(false).build(), + PropertyDefinition.build("global3").name("Global3").category("catGlobal2").global(true).project(false).module(false).build(), + PropertyDefinition.build("project").name("Project").category("catProject").global(false).project(true).module(false).build(), + PropertyDefinition.build("module").name("Module").category("catModule").global(false).project(false).module(true).build() + ); + + assertThat(def.getGlobalPropertiesByCategory().keySet()).containsOnly("catGlobal1", "catGlobal2"); + assertThat(def.getProjectPropertiesByCategory().keySet()).containsOnly("catProject"); + assertThat(def.getModulePropertiesByCategory().keySet()).containsOnly("catModule"); } @Test - public void should_group_by_category() { + public void should_group_by_category_on_annotation_plugin() { PropertyDefinitions def = new PropertyDefinitions(ByCategory.class); assertThat(def.getGlobalPropertiesByCategory().keySet()).containsOnly("catGlobal1", "catGlobal2"); @@ -98,12 +113,42 @@ public class PropertyDefinitionsTest { assertThat(def.getModulePropertiesByCategory().keySet()).containsOnly("catModule"); } + private void assertProperties(PropertyDefinitions definitions) { + assertThat(definitions.get("foo").name()).isEqualTo("Foo"); + assertThat(definitions.get("one").name()).isEqualTo("One"); + assertThat(definitions.get("two").name()).isEqualTo("Two"); + assertThat(definitions.get("unknown")).isNull(); + + assertThat(definitions.getDefaultValue("foo")).isNull(); + assertThat(definitions.getDefaultValue("two")).isEqualTo("2"); + + assertThat(definitions.getAll().size()).isEqualTo(3); + } + + @Property(key = "foo", name = "Foo") + static final class PluginWithProperty { + } + + @Properties({ + @Property(key = "one", name = "One"), + @Property(key = "two", name = "Two", defaultValue = "2") + }) + static final class PluginWithProperties { + } + + @Properties({ + @Property(key = "inCateg", name = "In Categ", category = "categ"), + @Property(key = "noCateg", name = "No categ") + }) + static final class Categories { + } + @Properties({ - @Property(key = "global1", name = "Global1", category = "catGlobal1", global = true, project = false, module = false), - @Property(key = "global2", name = "Global2", category = "catGlobal1", global = true, project = false, module = false), - @Property(key = "global3", name = "Global3", category = "catGlobal2", global = true, project = false, module = false), - @Property(key = "project", name = "Project", category = "catProject", global = false, project = true, module = false), - @Property(key = "module", name = "Module", category = "catModule", global = false, project = false, module = true) + @Property(key = "global1", name = "Global1", category = "catGlobal1", global = true, project = false, module = false), + @Property(key = "global2", name = "Global2", category = "catGlobal1", global = true, project = false, module = false), + @Property(key = "global3", name = "Global3", category = "catGlobal2", global = true, project = false, module = false), + @Property(key = "project", name = "Project", category = "catProject", global = false, project = true, module = false), + @Property(key = "module", name = "Module", category = "catModule", global = false, project = false, module = true) }) static final class ByCategory { } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/config/SettingsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/config/SettingsTest.java index 745c28d0990..7495215b354 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/config/SettingsTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/config/SettingsTest.java @@ -56,19 +56,19 @@ public class SettingsTest { public ExpectedException thrown = ExpectedException.none(); @Before - public void initDefinitions() { + public void init_definitions() { definitions = new PropertyDefinitions(); definitions.addComponent(Init.class); } @Test - public void defaultValuesShouldBeLoadedFromDefinitions() { + public void default_values_should_be_loaded_from_definitions() { Settings settings = new Settings(definitions); assertThat(settings.getDefaultValue("hello")).isEqualTo("world"); } @Test - public void setProperty_int() { + public void set_property_int() { Settings settings = new Settings(); settings.setProperty("foo", 123); assertThat(settings.getInt("foo")).isEqualTo(123); @@ -77,7 +77,7 @@ public class SettingsTest { } @Test - public void setProperty_boolean() { + public void set_property_boolean() { Settings settings = new Settings(); settings.setProperty("foo", true); settings.setProperty("bar", false); @@ -104,34 +104,34 @@ public class SettingsTest { } @Test - public void allValuesShouldBeTrimmed_set_property() { + public void all_values_should_be_trimmed_set_property() { Settings settings = new Settings(); settings.setProperty("foo", " FOO "); assertThat(settings.getString("foo")).isEqualTo("FOO"); } @Test - public void allValuesShouldBeTrimmed_set_properties() { + public void all_values_should_be_trimmed_set_properties() { Settings settings = new Settings(); settings.setProperties(ImmutableMap.of("foo", " FOO ")); assertThat(settings.getString("foo")).isEqualTo("FOO"); } @Test - public void testGetDefaultValue() { + public void test_get_default_value() { Settings settings = new Settings(definitions); assertThat(settings.getDefaultValue("unknown")).isNull(); } @Test - public void testGetString() { + public void test_get_string() { Settings settings = new Settings(definitions); settings.setProperty("hello", "Russia"); assertThat(settings.getString("hello")).isEqualTo("Russia"); } @Test - public void testGetDate() { + public void test_get_date() { Settings settings = new Settings(definitions); assertThat(settings.getDate("unknown")).isNull(); assertThat(settings.getDate("date").getDate()).isEqualTo(18); @@ -139,13 +139,13 @@ public class SettingsTest { } @Test - public void testGetDateNotFound() { + public void test_get_dat_enot_found() { Settings settings = new Settings(definitions); assertThat(settings.getDate("unknown")).isNull(); } @Test - public void testGetDateTime() { + public void test_get_datetime() { Settings settings = new Settings(definitions); assertThat(settings.getDateTime("unknown")).isNull(); assertThat(settings.getDateTime("datetime").getDate()).isEqualTo(18); @@ -154,7 +154,7 @@ public class SettingsTest { } @Test - public void testGetDouble() { + public void test_get_double() { Settings settings = new Settings(); settings.setProperty("from_double", 3.14159); settings.setProperty("from_string", "3.14159"); @@ -164,7 +164,7 @@ public class SettingsTest { } @Test - public void testGetFloat() { + public void test_get_float() { Settings settings = new Settings(); settings.setProperty("from_float", 3.14159f); settings.setProperty("from_string", "3.14159"); @@ -174,7 +174,7 @@ public class SettingsTest { } @Test - public void testGetBadFloat() { + public void test_get_bad_float() { Settings settings = new Settings(); settings.setProperty("foo", "bar"); @@ -184,7 +184,7 @@ public class SettingsTest { } @Test - public void testGetBadDouble() { + public void test_get_bad_double() { Settings settings = new Settings(); settings.setProperty("foo", "bar"); diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/platform/ComponentContainerTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/platform/ComponentContainerTest.java index d2db710a91f..b7d42445de6 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/platform/ComponentContainerTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/platform/ComponentContainerTest.java @@ -161,7 +161,7 @@ public class ComponentContainerTest { PropertyDefinitions propertyDefinitions = container.getComponentByType(PropertyDefinitions.class); assertThat(propertyDefinitions.get("foo")).isNotNull(); - assertThat(propertyDefinitions.get("foo").getDefaultValue()).isEqualTo("bar"); + assertThat(propertyDefinitions.get("foo").defaultValue()).isEqualTo("bar"); } @Test |