deltaspike-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rmannibu...@apache.org
Subject [1/5] deltaspike git commit: support dynamic converted config instances
Date Wed, 09 Nov 2016 11:52:30 GMT
Repository: deltaspike
Updated Branches:
  refs/heads/master a60cb32e8 -> 8e6fa365a


support dynamic converted config instances


Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/6d0c4a27
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/6d0c4a27
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/6d0c4a27

Branch: refs/heads/master
Commit: 6d0c4a272cbef0e56dd1c60ea4b3f4e4069b8eca
Parents: a60cb32
Author: rmannibucau <rmannibucau@apache.org>
Authored: Mon Nov 7 09:21:25 2016 +0100
Committer: rmannibucau <rmannibucau@apache.org>
Committed: Mon Nov 7 09:21:25 2016 +0100

----------------------------------------------------------------------
 .../core/api/config/ConfigProperty.java         |   7 +
 .../core/api/config/ConfigResolver.java         |  21 ++-
 .../spi/config/BaseConfigPropertyProducer.java  |  50 ++++---
 .../impl/config/ConfigurationExtension.java     | 134 +++++++++++++++++++
 .../config/DefaultConfigPropertyProducer.java   |   6 +-
 .../InjectableConfigPropertyTest.java           |  12 ++
 .../api/config/injectable/SettingsBean.java     |  45 +++++++
 .../META-INF/apache-deltaspike.properties       |   4 +-
 8 files changed, 256 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/6d0c4a27/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigProperty.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigProperty.java
b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigProperty.java
index 260eaa2..a856ad7 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigProperty.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigProperty.java
@@ -144,4 +144,11 @@ public @interface ConfigProperty
      */
     @Nonbinding
     boolean evaluateVariables() default true;
+
+    /**
+     * Converter for this property.
+     * @return the converter to use to read this property in the expected type.
+     */
+    @Nonbinding
+    Class<? extends ConfigResolver.Converter> converter() default ConfigResolver.Converter.class;
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/6d0c4a27/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
index f8f522b..effdd4a 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
@@ -18,6 +18,7 @@
  */
 package org.apache.deltaspike.core.api.config;
 
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -760,6 +761,14 @@ public final class ConfigResolver
         <N> TypedResolver<N> as(Class<N> clazz);
 
         /**
+         * @param type target type, includes List and Map using a Converter
+         * @param converter The converter for the target type
+         * @param <N> target type
+         * @return this builder typed.
+         */
+        <N> TypedResolver<N> as(Type type, Converter<N> converter);
+
+        /**
          * Sets the type of the configuration entry to the given class, sets the converter
to the one given and
          * returns this builder as a TypedResolver. If a converter is provided for one of
the types supported by
          * default (see {@link #as(Class)} then the provided converter is used instead of
the built-in one.
@@ -794,7 +803,7 @@ public final class ConfigResolver
 
         private String keyResolved;
 
-        private Class<?> configEntryType = String.class;
+        private Type configEntryType = String.class;
 
         private boolean withDefault = false;
         private T defaultValue;
@@ -845,6 +854,16 @@ public final class ConfigResolver
         }
 
         @Override
+        @SuppressWarnings("unchecked")
+        public <N> TypedResolver<N> as(Type clazz, Converter<N> converter)
+        {
+            configEntryType = clazz;
+            this.converter = converter;
+
+            return (TypedResolver<N>) this;
+        }
+
+        @Override
         public TypedResolver<T> withDefault(T value)
         {
             defaultValue = value;

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/6d0c4a27/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/BaseConfigPropertyProducer.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/BaseConfigPropertyProducer.java
b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/BaseConfigPropertyProducer.java
index dec87f7..7cae68d 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/BaseConfigPropertyProducer.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/BaseConfigPropertyProducer.java
@@ -21,9 +21,11 @@ package org.apache.deltaspike.core.spi.config;
 import javax.enterprise.inject.spi.InjectionPoint;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
 
 import org.apache.deltaspike.core.api.config.ConfigResolver;
 import org.apache.deltaspike.core.api.config.ConfigProperty;
+import org.apache.deltaspike.core.api.provider.BeanProvider;
 import org.apache.deltaspike.core.util.BeanUtils;
 
 /**
@@ -110,6 +112,11 @@ public abstract class BaseConfigPropertyProducer
 
     protected <T> T getPropertyValue(InjectionPoint injectionPoint, Class<T>
ipCls)
     {
+        return getUntypedPropertyValue(injectionPoint, ipCls);
+    }
+
+    protected <T> T getUntypedPropertyValue(InjectionPoint injectionPoint, Type ipCls)
+    {
         ConfigProperty configProperty = getAnnotation(injectionPoint, ConfigProperty.class);
 
         if (configProperty == null)
@@ -117,25 +124,9 @@ public abstract class BaseConfigPropertyProducer
             throw new IllegalStateException("producer method called without @ConfigProperty
being present!");
         }
 
-        ConfigResolver.TypedResolver<T> resolver = ConfigResolver.resolve(configProperty.name())
-                .as(ipCls)
-                .withCurrentProjectStage(configProperty.projectStageAware());
-
-        String stringDefault = configProperty.defaultValue();
-        if (!ConfigProperty.NULL.equals(stringDefault))
-        {
-            resolver.withStringDefault(stringDefault);
-        }
-
-        String parameterizedBy = configProperty.parameterizedBy();
-        if (!ConfigProperty.NULL.equals(parameterizedBy))
-        {
-            resolver.parameterizedBy(parameterizedBy);
-        }
-
-        resolver.evaluateVariables(configProperty.evaluateVariables());
-
-        return resolver.getValue();
+        return readEntry(configProperty.name(), configProperty.defaultValue(), ipCls,
+                configProperty.converter(), configProperty.parameterizedBy(),
+                configProperty.projectStageAware(), configProperty.evaluateVariables());
     }
 
     /**
@@ -169,4 +160,25 @@ public abstract class BaseConfigPropertyProducer
     {
         return BeanUtils.extractAnnotation(injectionPoint.getAnnotated(), targetType);
     }
+
+    public <T> T readEntry(final String key, final String stringDefault, final Type
ipCls,
+                           final Class<? extends ConfigResolver.Converter> converterType,
+                           final String parameterizedBy, final boolean projectStageAware,
final boolean evaluate)
+    {
+        final ConfigResolver.UntypedResolver<String> untypedResolver = ConfigResolver.resolve(key);
+        final ConfigResolver.TypedResolver<T> resolver =
+                (ConfigResolver.Converter.class == converterType ?
+                        untypedResolver.as(Class.class.cast(ipCls)) :
+                        untypedResolver.as(ipCls, BeanProvider.getContextualReference(converterType)))
+                        .withCurrentProjectStage(projectStageAware);
+        if (!ConfigProperty.NULL.equals(stringDefault))
+        {
+            resolver.withStringDefault(stringDefault);
+        }
+        if (!ConfigProperty.NULL.equals(parameterizedBy))
+        {
+            resolver.parameterizedBy(parameterizedBy);
+        }
+        return resolver.evaluateVariables(evaluate).getValue();
+    }
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/6d0c4a27/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigurationExtension.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigurationExtension.java
b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigurationExtension.java
index 09ac956..accabae 100644
--- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigurationExtension.java
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigurationExtension.java
@@ -18,13 +18,24 @@
  */
 package org.apache.deltaspike.core.impl.config;
 
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.spi.CreationalContext;
 import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
 import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
 import javax.enterprise.inject.spi.BeforeBeanDiscovery;
 import javax.enterprise.inject.spi.BeforeShutdown;
 import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
 import javax.enterprise.inject.spi.ProcessAnnotatedType;
+import javax.enterprise.inject.spi.ProcessBean;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -32,10 +43,12 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.deltaspike.core.api.config.ConfigProperty;
 import org.apache.deltaspike.core.api.config.ConfigResolver;
 import org.apache.deltaspike.core.api.config.PropertyFileConfig;
 import org.apache.deltaspike.core.api.exclude.Exclude;
 import org.apache.deltaspike.core.spi.activation.Deactivatable;
+import org.apache.deltaspike.core.spi.config.BaseConfigPropertyProducer;
 import org.apache.deltaspike.core.spi.config.ConfigSource;
 import org.apache.deltaspike.core.spi.config.ConfigValidator;
 import org.apache.deltaspike.core.util.ClassDeactivationUtils;
@@ -69,6 +82,9 @@ public class ConfigurationExtension implements Extension, Deactivatable
     private List<Class<? extends PropertyFileConfig>> propertyFileConfigClasses
         = new ArrayList<Class<?  extends PropertyFileConfig>>();
 
+    private final Set<Type> dynamicConfigTypes = new HashSet<Type>();
+    private Bean<DynamicBeanProducer> dynamicProducer;
+
     @SuppressWarnings("UnusedDeclaration")
     protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery)
     {
@@ -104,6 +120,33 @@ public class ConfigurationExtension implements Extension, Deactivatable
         propertyFileConfigClasses.add(pcsClass);
     }
 
+    public void findDynamicProducer(@Observes ProcessBean<DynamicBeanProducer> processBean)
+    {
+        dynamicProducer = processBean.getBean();
+    }
+
+    public void collectDynamicTypes(@Observes ProcessBean<?> processBean)
+    {
+        for (final InjectionPoint ip : processBean.getBean().getInjectionPoints())
+        {
+            final ConfigProperty annotation = ip.getAnnotated().getAnnotation(ConfigProperty.class);
+            if (annotation == null || annotation.converter() == ConfigResolver.Converter.class)
+            {
+                continue;
+            }
+
+            dynamicConfigTypes.add(ip.getType());
+        }
+    }
+
+    public void addDynamicBean(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager
bm)
+    {
+        if (dynamicProducer != null && !dynamicConfigTypes.isEmpty())
+        {
+            afterBeanDiscovery.addBean(new DynamicBean(dynamicProducer, dynamicConfigTypes));
+        }
+    }
+
     @SuppressWarnings("UnusedDeclaration")
     public void registerUserConfigSources(@Observes AfterDeploymentValidation adv)
     {
@@ -229,4 +272,95 @@ public class ConfigurationExtension implements Extension, Deactivatable
             }
         }
     }
+
+    @ApplicationScoped
+    @Typed(DynamicBeanProducer.class) // used as an internal bean
+    static class DynamicBeanProducer extends BaseConfigPropertyProducer
+    {
+        @Produces
+        @ConfigProperty(name = "ignored")
+        public Object create(final InjectionPoint ip)
+        {
+            return super.getUntypedPropertyValue(ip, ip.getType());
+        }
+    }
+
+    @Typed
+    private static final class DynamicBean<T> implements Bean<T>
+    {
+        private final Bean<T> producer;
+        private final Set<Type> types;
+
+        private DynamicBean(final Bean<T> producer, final Set<Type> types)
+        {
+            this.producer = producer;
+            this.types = types;
+        }
+
+        @Override
+        public Set<Type> getTypes()
+        {
+            return types;
+        }
+
+        @Override
+        public Set<Annotation> getQualifiers()
+        {
+            return producer.getQualifiers();
+        }
+
+        @Override
+        public Class<? extends Annotation> getScope()
+        {
+            return producer.getScope();
+        }
+
+        @Override
+        public String getName()
+        {
+            return producer.getName();
+        }
+
+        @Override
+        public boolean isNullable()
+        {
+            return producer.isNullable();
+        }
+
+        @Override
+        public Set<InjectionPoint> getInjectionPoints()
+        {
+            return producer.getInjectionPoints();
+        }
+
+        @Override
+        public Class<?> getBeanClass()
+        {
+            return producer.getBeanClass();
+        }
+
+        @Override
+        public Set<Class<? extends Annotation>> getStereotypes()
+        {
+            return producer.getStereotypes();
+        }
+
+        @Override
+        public boolean isAlternative()
+        {
+            return producer.isAlternative();
+        }
+
+        @Override
+        public T create(final CreationalContext<T> creationalContext)
+        {
+            return producer.create(creationalContext);
+        }
+
+        @Override
+        public void destroy(final T t, final CreationalContext<T> creationalContext)
+        {
+            producer.destroy(t, creationalContext);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/6d0c4a27/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigPropertyProducer.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigPropertyProducer.java
b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigPropertyProducer.java
index 8546c71..7e7efeb 100644
--- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigPropertyProducer.java
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigPropertyProducer.java
@@ -26,6 +26,8 @@ import javax.enterprise.inject.spi.InjectionPoint;
 import org.apache.deltaspike.core.spi.config.BaseConfigPropertyProducer;
 import org.apache.deltaspike.core.api.config.ConfigProperty;
 
+import java.lang.reflect.Type;
+
 /**
  * This class contains producer methods for injecting
  * configuration provided with the {@link ConfigProperty}
@@ -93,11 +95,11 @@ public class DefaultConfigPropertyProducer extends BaseConfigPropertyProducer
 
     }
 
-    private <T> T getPropertyWithException(InjectionPoint ip, Class<T> ipCls)
+    private <T> T getPropertyWithException(InjectionPoint ip, Type ipCls)
     {
         try
         {
-            return getPropertyValue(ip, ipCls);
+            return getUntypedPropertyValue(ip, ipCls);
         }
         catch (RuntimeException rte)
         {

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/6d0c4a27/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/InjectableConfigPropertyTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/InjectableConfigPropertyTest.java
b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/InjectableConfigPropertyTest.java
index 568d26e..d6f11c2 100644
--- a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/InjectableConfigPropertyTest.java
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/InjectableConfigPropertyTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.deltaspike.test.core.api.config.injectable;
 
+import java.net.MalformedURLException;
 import java.net.URL;
 
 import org.apache.deltaspike.core.api.provider.BeanProvider;
@@ -37,6 +38,10 @@ import org.junit.runner.RunWith;
 
 import org.apache.deltaspike.test.core.api.config.injectable.numberconfig.NumberConfiguredBean;
 
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.junit.Assert.assertEquals;
+
 
 @RunWith(Arquillian.class)
 @Category(SeCategory.class) //X TODO this is only SeCategory as there is currently an Arq
problem with properties!
@@ -104,4 +109,11 @@ public class InjectableConfigPropertyTest
         Assert.assertEquals(Float.valueOf(123.45f), numberBean.getPropertyFromConfig());
         Assert.assertEquals(Float.valueOf(42.42f), numberBean.getPropertyNonexistingDefaulted());
     }
+
+    @Test
+    public void checkDynamicConvertedInjections() throws MalformedURLException {
+        SettingsBean settingsBean = BeanProvider.getContextualReference(SettingsBean.class,
false);
+        assertEquals(asList(new URL("http://localhost"), new URL("http://127.0.0.1")), settingsBean.getUrlList());
+        assertEquals(singletonList(new URL("http://127.0.0.2")), settingsBean.getUrlListFromProperties());
+    }
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/6d0c4a27/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/SettingsBean.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/SettingsBean.java
b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/SettingsBean.java
index d180aca..b542e77 100644
--- a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/SettingsBean.java
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/SettingsBean.java
@@ -19,9 +19,14 @@
 package org.apache.deltaspike.test.core.api.config.injectable;
 
 import org.apache.deltaspike.core.api.config.ConfigProperty;
+import org.apache.deltaspike.core.api.config.ConfigResolver;
 
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
 
 @ApplicationScoped
 public class SettingsBean
@@ -92,6 +97,14 @@ public class SettingsBean
     @ConfigProperty(name = "testDbConfig")
     private String dbConfig;
 
+    @Inject
+    @ConfigProperty(name = "urlList", converter = UrlList.class, defaultValue = "http://localhost,http://127.0.0.1")
+    private List<URL> urlList;
+
+    @Inject
+    @ConfigProperty(name = "urlListFromProperties", converter = UrlList.class)
+    private List<URL> urlListFromProperties;
+
     protected SettingsBean()
     {
     }
@@ -193,4 +206,36 @@ public class SettingsBean
     {
         return dbConfig;
     }
+
+    public List<URL> getUrlList() {
+        return urlList;
+    }
+
+    public List<URL> getUrlListFromProperties() {
+        return urlListFromProperties;
+    }
+
+    public static class UrlList implements ConfigResolver.Converter<List<URL>>
+    {
+        @Override
+        public List<URL> convert(final String value)
+        {
+            final List<URL> urls = new ArrayList<URL>();
+            if (value != null)
+            {
+                for (final String segment : value.split(","))
+                {
+                    try
+                    {
+                        urls.add(new URL(segment));
+                    }
+                    catch (final MalformedURLException e)
+                    {
+                        throw new IllegalArgumentException(e);
+                    }
+                }
+            }
+            return urls;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/6d0c4a27/deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties
b/deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties
index d8fee1c..61a86bf 100644
--- a/deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties
+++ b/deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties
@@ -47,4 +47,6 @@ propertyFloat=123.45
 
 my.very.secret=onlyIDoKnowIt
 
-deactivate.org.apache.deltaspike.test.core.impl.activation.DeactivatedClass=true
\ No newline at end of file
+deactivate.org.apache.deltaspike.test.core.impl.activation.DeactivatedClass=true
+
+urlListFromProperties = http://127.0.0.2


Mime
View raw message