This is an automated email from the ASF dual-hosted git repository. anatole pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-tamaya-extensions.git
commit ae05ac5b763a257cee8dc24b30cbb72b5e6bcf0b Author: Anatole Tresch <[email protected]> AuthorDate: Fri Feb 22 09:39:54 2019 +0100 TAMAYA-378 Improved injection API for more transparent key resolution. --- .../tamaya/ext/examples/injection/Example.java | 6 ++-- .../ext/examples/injection/ExampleTemplate.java | 6 ++-- .../tamaya/springexample/WelcomeController.java | 6 ++-- .../java/org/apache/tamaya/inject/api/Config.java | 41 ++++++++++++++-------- .../apache/tamaya/inject/spi/AutoKeyResolver.java | 23 ++++++++---- .../apache/tamaya/inject/spi/InjectionUtils.java | 2 +- .../tamaya/inject/spi/InjectionUtilsTest.java | 35 ++++++++++++++++-- .../apache/tamaya/inject/TamayaInjectionTest.java | 10 +++--- .../apache/tamaya/inject/TestPropertySource.java | 7 ++-- .../inject/internal/DefaultDynamicValueTest.java | 6 ++-- 10 files changed, 96 insertions(+), 46 deletions(-) diff --git a/examples/03-injection-example/src/main/java/org/apache/tamaya/ext/examples/injection/Example.java b/examples/03-injection-example/src/main/java/org/apache/tamaya/ext/examples/injection/Example.java index 6f78e58..e9726df 100644 --- a/examples/03-injection-example/src/main/java/org/apache/tamaya/ext/examples/injection/Example.java +++ b/examples/03-injection-example/src/main/java/org/apache/tamaya/ext/examples/injection/Example.java @@ -19,12 +19,12 @@ package org.apache.tamaya.ext.examples.injection; import org.apache.tamaya.inject.api.Config; -import org.apache.tamaya.inject.api.ConfigDefaultSections; +import org.apache.tamaya.inject.api.ConfigSection; /** * Simple example bean, mapped by default names mostly. */ -@ConfigDefaultSections("example") +@ConfigSection("example") @SuppressWarnings("all") public class Example { @@ -33,7 +33,7 @@ public class Example { @Config(defaultValue = "No description available.") private String description; private int version; - @Config("author") + @Config(key="author") private String exampleAuthor; @Override diff --git a/examples/03-injection-example/src/main/java/org/apache/tamaya/ext/examples/injection/ExampleTemplate.java b/examples/03-injection-example/src/main/java/org/apache/tamaya/ext/examples/injection/ExampleTemplate.java index 8eb6839..9e9b984 100644 --- a/examples/03-injection-example/src/main/java/org/apache/tamaya/ext/examples/injection/ExampleTemplate.java +++ b/examples/03-injection-example/src/main/java/org/apache/tamaya/ext/examples/injection/ExampleTemplate.java @@ -19,12 +19,12 @@ package org.apache.tamaya.ext.examples.injection; import org.apache.tamaya.inject.api.Config; -import org.apache.tamaya.inject.api.ConfigDefaultSections; +import org.apache.tamaya.inject.api.ConfigSection; /** * Simple example bean, mapped by default names mostly. */ -@ConfigDefaultSections("example") +@ConfigSection("example") public interface ExampleTemplate { String getType(); @@ -36,7 +36,7 @@ public interface ExampleTemplate { int getVersion(); - @Config("author") + @Config(key="author") String getExampleAuthor(); } diff --git a/examples/05-spring-example/src/main/java/org/apache/tamaya/springexample/WelcomeController.java b/examples/05-spring-example/src/main/java/org/apache/tamaya/springexample/WelcomeController.java index 352822b..8de47e8 100644 --- a/examples/05-spring-example/src/main/java/org/apache/tamaya/springexample/WelcomeController.java +++ b/examples/05-spring-example/src/main/java/org/apache/tamaya/springexample/WelcomeController.java @@ -36,13 +36,13 @@ public class WelcomeController { @Value("${application.message:Hello World}") private String message = "Hello World"; - @Config(value = "background.color", required = false) + @Config(key = "background.color", required = false) private String backgroundColor = "#BBBBBB"; - @Config(value = "foreground.color", required = false, defaultValue = FOREGROUND_DEFAULT) + @Config(key = "foreground.color", required = false, defaultValue = FOREGROUND_DEFAULT) private DynamicValue<String> foregroundColor; - @Config(value = "background.color", required = false) + @Config(key = "background.color", required = false) private Color bgColor; @GetMapping("/") diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/Config.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/Config.java index d18f8bf..5e6c811 100644 --- a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/Config.java +++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/Config.java @@ -25,6 +25,8 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.lang.reflect.Field; +import java.lang.reflect.Method; /** * Annotation to define injection of a configured property or define the configuration data @@ -44,27 +46,33 @@ import java.lang.annotation.Target; * Configuration resolution is implemented as follows: * <ul> * <li>The current valid Configuration is evaluated by calling {@code Configuration cfg = Configuration.current();}</li> - * <li>The current possible property keys are evaluated by calling {@code cfg.current("a.b.ConfigureItem.aValue");}, - * {@code cfg.current("ConfigureItem.aValue");}, {@code cfg.current("aValue");}</li> - * <li>if not successful, and since no @ConfigDefault annotation is present, the configured default createValue is used. - * <li>If no createValue could be evaluated a ({@link org.apache.tamaya.ConfigException} is thrown.</li> - * <li>On success, since no type conversion is involved, the createValue is injected.</li> + * <li>The current possible property keys are evaluated by calling {@link org.apache.tamaya.inject.spi.InjectionUtils#getKeys(Field)} + * or {@link org.apache.tamaya.inject.spi.InjectionUtils#getKeys(Method)} . Hereby the key resolution is delegated + * to an instance of {@link KeyResolver}, which can be defined on the configured class with the {@link ConfigSection} + * or (overriding) on the configured field/method with the {@link Config} annotation. The default key resolver + * is {@link org.apache.tamaya.inject.spi.AutoKeyResolver}.</li> + * <li>Each key evaluated is looked up in the configuration, until a configuration value has been found.</li> + * <li>if not successful, {@link Config#defaultValue()} is used, if present.</li> + * <li>If no value could be evaluated a ({@link org.apache.tamaya.ConfigException} is thrown, unless {@link Config#required()} + * is set to {@code true} (default is {@code false}).</li> + * <li>If necessary, the final <i>raw</i> value is converted into the required type to be injected, using a + * {@link org.apache.tamaya.spi.PropertyConverter}, then the value is injected.</li> * </ul> * * <h3>Explicit annotations</h3> * In the next example we explicitly define the configuration keys to be used: * <pre> - * &ConfigDefaultSections("section1") + * &ConfigSection("section1") * public class ConfiguredItem { * - * &Config(createValue = {"b", "[a.b.deprecated.keys]", "a"}, defaultValue = "myDefaultValue") + * &Config(key = {"b"}, fallbackKeys="[a.b.deprecated.keys]", "a"}, defaultValue = "myDefaultValue") * private String aValue; * } * </pre> * * Within this example we evaluate multiple possible keys: {@code section1.b, a.b.deprecated.keys, section1.a}. * Evaluation is aborted if a key is resolved successfully. Hereby the ordering of the annotation values - * define the ordering of resolution. If no createValue can be found, the configured default {@code myDefaultValue} is + * define the ordering of resolution. If no value can be found, the configured default {@code myDefaultValue} is * injected. * * <h3>Using explicit field annotation only</h3> @@ -75,14 +83,13 @@ import java.lang.annotation.Target; * * public class ConfiguredItem { * - * &Config(createValue = {"b", "[a.b.deprecated.keys]", "a"}, defaultValue = "myDefaultValue") + * &Config(key = {"b"}, fallbackKeys={"[a.b.deprecated.keys]", "a"}, defaultValue = "myDefaultValue") * private String aValue; * } * </pre> * - * Key resolution is similar to above, but now the default package names are used, resulting in - * {@code a.b.ConfiguredItem.b, ConfiguredItem.b, a.b.deprecated.keys, a.b.ConfiguredItem.a, ConfiguredItem.a} - * being evaluated. + * Key resolution is similar to above, but now the default section resolution allies, resulting in the keys + * {@code ConfiguredItem.b, a.b.deprecated.keys, ConfiguredItem.a} being looked up. */ @Qualifier @Retention(RetentionPolicy.RUNTIME) @@ -94,7 +101,7 @@ public @interface Config { /** * Defines the main configuration property key to be used. The final target property is evaluated based on - * the {@link #keyResolver()} strategy, by default {@link KeyResolution#AUTO}. + * the {@link #keyResolver()} strategy, by default {@link org.apache.tamaya.inject.spi.AutoKeyResolver}. * * @return the main property key, not null. If empty, the field or property name (of a setter method) being injected * is used by default. @@ -116,6 +123,12 @@ public @interface Config { * {@code areaAnnotation.getValue() + '.' + propertyKey}.</li> * </ol> * + * Note that on field or method injection without any {@link Config} annotation multiple main keys are generated, e.g.: + * <ul> + * <li>a field named {@code a_b_property} evaluates to {@code a_b_property, a.b.property}}</li> + * <li>a field named {@code aProperty} evaluates to {@code aProperty, a.property}}</li> + * </ul> + * * @return the key resolution strategy, never null. */ @Nonbinding @@ -123,7 +136,7 @@ public @interface Config { /** * Defines the alternate configuration property keys to be used, if no value could be evaluated using the main - * {@link #key()}. All key values given are resolved using the {@link KeyResolution#ABSOLUTE} strategy. + * {@link #key()}. * * @return the property keys, not null. */ diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/AutoKeyResolver.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/AutoKeyResolver.java index 446c0f5..8db240e 100644 --- a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/AutoKeyResolver.java +++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/AutoKeyResolver.java @@ -31,9 +31,10 @@ import java.util.List; /** * Default key resolver which uses the following resolution strategy: * <ol> - * <li>The containing class <b>does not</b> have a {@link ConfigSection} annotation and the field/method does not have - * a {@link Config} annotation: the main key equals to - * {@code Owning.class.getSimpleName() + '.' + propertyKey}.</li> + * <li>The containing class <b>does</b> have a {@link ConfigSection} annotation: the main key equals to + * * {@code Owning.class.getSimpleName() + '.' + propertyKey}.</li> + * <li>The containing class <b>does not</b> have a {@link ConfigSection} annotation: the main key equals to + * {@code propertyKey}.</li> * <li>The containing class <b>does not</b> have a {@link ConfigSection} annotation: the main key equals to * {@code propertyKey}.</li> * <li>The containing class <b>does</b> have a {@link ConfigSection} annotation: the main key equals to @@ -50,7 +51,11 @@ public final class AutoKeyResolver implements KeyResolver { if (sectionName != null) { result.add(evaluateKey(sectionName, key)); } else { - result.add(key); + if(key.startsWith("[") && key.endsWith("]")) { + result.add(key.substring(1, key.length() - 1)); + }else{ + result.add(key); + } } } for(String fk:alternateKeys){ @@ -84,9 +89,13 @@ public final class AutoKeyResolver implements KeyResolver { private String getSectionName(Class owner) { ConfigSection sectionAnnot = (ConfigSection)owner.getAnnotation(ConfigSection.class); - if(sectionAnnot!=null && !sectionAnnot.value().isEmpty()){ - return sectionAnnot.value(); + if(sectionAnnot!=null){ + if(sectionAnnot.value().isEmpty()) { + return owner.getSimpleName(); + }else { + return sectionAnnot.value(); + } } - return owner.getSimpleName(); + return null; } } diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/InjectionUtils.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/InjectionUtils.java index 806f3ce..ccfc59b 100644 --- a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/InjectionUtils.java +++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/InjectionUtils.java @@ -165,7 +165,7 @@ public final class InjectionUtils { private static List<String> expandKey(String key) { List<String> result = new ArrayList<>(); result.add(key); - if(result.contains("_")){ + if(key.contains("_")){ result.add(key.replace("_", ".")); } String splittedCamelCase = trySplitCamelCase(key); diff --git a/modules/injection/injection-api/src/test/java/org/apache/tamaya/inject/spi/InjectionUtilsTest.java b/modules/injection/injection-api/src/test/java/org/apache/tamaya/inject/spi/InjectionUtilsTest.java index 144eab4..c818ed6 100644 --- a/modules/injection/injection-api/src/test/java/org/apache/tamaya/inject/spi/InjectionUtilsTest.java +++ b/modules/injection/injection-api/src/test/java/org/apache/tamaya/inject/spi/InjectionUtilsTest.java @@ -44,9 +44,9 @@ public class InjectionUtilsTest { assertThat(foundKeys) .isNotNull() .hasSize(3) - .contains("Klazz.val", + .contains("val", "val2", - "Klazz.vvv"); + "vvv"); } @Test @@ -119,7 +119,35 @@ public class InjectionUtilsTest { List<String> foundKeys = InjectionUtils.getKeys(field); assertThat(foundKeys).hasSize(1); - assertThat(foundKeys.get(0)).isEqualTo("Klazz.field"); + assertThat(foundKeys.get(0)).isEqualTo("field"); + } + + @Test + public void getKeysReturns2ForNonAnnotatedField_Underscore() { + class Klazz { + public String a_field; + } + + Field field = Klazz.class.getFields()[0]; + + List<String> foundKeys = InjectionUtils.getKeys(field); + assertThat(foundKeys).hasSize(2); + assertThat(foundKeys.get(0)).isEqualTo("a_field"); + assertThat(foundKeys.get(1)).isEqualTo("a.field"); + } + + @Test + public void getKeysReturns2ForNonAnnotatedField_CamelCase() { + class Klazz { + public String aField; + } + + Field field = Klazz.class.getFields()[0]; + + List<String> foundKeys = InjectionUtils.getKeys(field); + assertThat(foundKeys).hasSize(2); + assertThat(foundKeys.get(0)).isEqualTo("aField"); + assertThat(foundKeys.get(1)).isEqualTo("a.field"); } @Test @@ -161,6 +189,7 @@ public class InjectionUtilsTest { @Test public void getKeysWithMemberAnnotation() { + @ConfigSection class Klazz { @Config(key="val", alternateKeys = "[absoluteVal]") public String field; diff --git a/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TamayaInjectionTest.java b/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TamayaInjectionTest.java index c329093..d8cf413 100644 --- a/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TamayaInjectionTest.java +++ b/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TamayaInjectionTest.java @@ -63,13 +63,13 @@ public class TamayaInjectionTest { assertThat(testInstance.myParameter).isNull(); assertThat(testInstance.simpleValue).isNull(); ConfigurationInjection.getConfigurationInjector().configure(testInstance); - assertThat(testInstance.getHostName()).isEqualTo("tamaya01.incubator.apache.org"); + assertThat(testInstance.getHostName()).isEqualTo("tamaya02.incubator.apache.org"); assertThat(testInstance.getAnotherValue()).isEqualTo("HALLO!"); assertThat(testInstance.myParameter).isEqualTo("ET"); assertThat(testInstance.simpleValue).isEqualTo("aSimpleValue"); assertThat(testInstance.getDynamicValue()).isNotNull(); assertThat(testInstance.getDynamicValue().isPresent()).isTrue(); - assertThat(testInstance.getDynamicValue().get()).isEqualTo("tamaya01.incubator.apache.org"); + assertThat(testInstance.getDynamicValue().get()).isEqualTo("tamaya02.incubator.apache.org"); assertThat(testInstance.getHostName()).isEqualTo(testInstance.getDynamicValue().get()); assertThat(testInstance.javaVersion).isEqualTo(System.getProperty("java.version")); } @@ -85,13 +85,13 @@ public class TamayaInjectionTest { assertThat(testInstance.someMoreValue).isNull(); assertThat(testInstance.notConfigured).isNull(); ConfigurationInjection.getConfigurationInjector().configure(testInstance); - assertThat(testInstance.getHostName()).isEqualTo("tamaya01.incubator.apache.org"); + assertThat(testInstance.getHostName()).isEqualTo("tamaya02.incubator.apache.org"); assertThat(testInstance.getAnotherValue()).isEqualTo("HALLO!"); assertThat(testInstance.myParameter).isEqualTo("ET"); assertThat(testInstance.simpleValue).isEqualTo("aSimpleValue"); assertThat(testInstance.getDynamicValue()).isNotNull(); assertThat(testInstance.getDynamicValue().isPresent()).isTrue(); - assertThat(testInstance.getDynamicValue().get()).isEqualTo("tamaya01.incubator.apache.org"); + assertThat(testInstance.getDynamicValue().get()).isEqualTo("tamaya02.incubator.apache.org"); assertThat(testInstance.getHostName()).isEqualTo(testInstance.getDynamicValue().get()); assertThat(testInstance.javaVersion).isEqualTo(System.getProperty("java.version")); assertThat(testInstance.someMoreValue).isEqualTo("s'more"); @@ -107,7 +107,7 @@ public class TamayaInjectionTest { assertThat(testInstance.simpleValue()).isEqualTo("aSimpleValue"); assertThat(testInstance.getDynamicValue()).isNotNull(); assertThat(testInstance.getDynamicValue().isPresent()).isTrue(); - assertThat(testInstance.getDynamicValue().get()).isEqualTo("tamaya01.incubator.apache.org"); + assertThat(testInstance.getDynamicValue().get()).isEqualTo("tamaya02.incubator.apache.org"); assertThat(testInstance.hostName()).isEqualTo(testInstance.getDynamicValue().get()); } diff --git a/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TestPropertySource.java b/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TestPropertySource.java index 0a1f988..1b12f01 100644 --- a/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TestPropertySource.java +++ b/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TestPropertySource.java @@ -46,10 +46,9 @@ public class TestPropertySource implements PropertySource { properties.put("AnnotatedConfigTemplate.simple_value", "aSimpleValue2"); - properties.put("NonAnnotatedConfigBean.simple_value", "aSimpleValue3"); - properties.put("NonAnnotatedConfigBean.classFieldKey", "Class-Field-Value"); - properties.put("NonAnnotatedConfigBean.fieldKey", "Field-Value"); - properties.put("NonAnnotatedConfigBean.fullKey", "Fullkey-Value"); + properties.put("class.field.key", "Class-Field-Value"); + properties.put("fieldKey", "Field-Value"); + properties.put("fullKey", "Fullkey-Value"); } @Override diff --git a/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/internal/DefaultDynamicValueTest.java b/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/internal/DefaultDynamicValueTest.java index e0c8d36..2aed714 100644 --- a/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/internal/DefaultDynamicValueTest.java +++ b/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/internal/DefaultDynamicValueTest.java @@ -41,13 +41,13 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class DefaultDynamicValueTest { - @Config(key="[a]") + @Config(key="a") String myValue; - @Config(key="[a]") + @Config(key="a") String myValue2; - @Config(key="[a]") + @Config(key="a") void setterMethod(String value){ }
