Oh I see what you mean. Do you mind to re-apply your fix or should I? Btw, I also tested with the -PWeld3 but I was not able to resolve arquillian-weld-embedded:jar:2.0.0-SNAPSHOT We might need to add a <repository> for it in the Weld3 profile.
I also would love to add a Weld profile. I thought we have this already but seems we missed it? txs and LieGrue, strub > Am 08.08.2017 um 12:58 schrieb John D. Ament <johndam...@apache.org>: > > One note - hardcoding "isAlternative" to true breaks in Weld. Unless there > is a base bean of same type, the alternative is ignored. Hence why I only > did isAlternative on the provider type, all others are just regular beans. > > John > > On Tue, Aug 8, 2017 at 6:55 AM <strub...@apache.org> wrote: > Author: struberg > Date: Tue Aug 8 10:55:56 2017 > New Revision: 1804397 > > URL: http://svn.apache.org/viewvc?rev=1804397&view=rev > Log: > GERONIMO-6577 move back to a more dynamic version > > The goal of r1800748 to calculate all information upfront could not be > achieved > so we move back to the old version > > Modified: > geronimo/components/config/trunk/impl/debug-suite.xml > geronimo/components/config/trunk/impl/pom.xml > > geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigExtension.java > > geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java > > geronimo/components/config/trunk/impl/src/test/java/org/apache/geronimo/config/test/internal/ProviderTest.java > geronimo/components/config/trunk/pom.xml > > Modified: geronimo/components/config/trunk/impl/debug-suite.xml > URL: > http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/debug-suite.xml?rev=1804397&r1=1804396&r2=1804397&view=diff > ============================================================================== > --- geronimo/components/config/trunk/impl/debug-suite.xml (original) > +++ geronimo/components/config/trunk/impl/debug-suite.xml Tue Aug 8 10:55:56 > 2017 > @@ -24,7 +24,7 @@ > <classes> > <!-- Issues in the spec --> > <!-- CDI-437 --> > - <class > name="org.eclipse.microprofile.config.tck.CdiOptionalInjectionTest"> > + <class > name="org.eclipse.microprofile.config.tck.CDIPlainInjectionTest"> > <methods> > <include name=".*"/> > </methods> > > Modified: geronimo/components/config/trunk/impl/pom.xml > URL: > http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/pom.xml?rev=1804397&r1=1804396&r2=1804397&view=diff > ============================================================================== > --- geronimo/components/config/trunk/impl/pom.xml (original) > +++ geronimo/components/config/trunk/impl/pom.xml Tue Aug 8 10:55:56 2017 > @@ -27,7 +27,6 @@ > </parent> > > <artifactId>geronimo-config-impl</artifactId> > - <name>Geronimo Microprofile Configuration :: Implementation</name> > > <dependencyManagement> > <dependencies> > > Modified: > geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigExtension.java > URL: > http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigExtension.java?rev=1804397&r1=1804396&r2=1804397&view=diff > ============================================================================== > --- > geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigExtension.java > (original) > +++ > geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigExtension.java > Tue Aug 8 10:55:56 2017 > @@ -16,54 +16,38 @@ > */ > package org.apache.geronimo.config.cdi; > > -import org.apache.geronimo.config.ConfigImpl; > -import org.eclipse.microprofile.config.Config; > -import org.eclipse.microprofile.config.inject.ConfigProperty; > -import org.eclipse.microprofile.config.spi.ConfigProviderResolver; > +import java.lang.reflect.Type; > +import java.util.ArrayList; > +import java.util.HashMap; > +import java.util.HashSet; > +import java.util.List; > +import java.util.Map; > +import java.util.Optional; > +import java.util.Set; > +import java.util.stream.Collectors; > > -import javax.enterprise.context.spi.CreationalContext; > import javax.enterprise.event.Observes; > import javax.enterprise.inject.spi.AfterBeanDiscovery; > import javax.enterprise.inject.spi.AfterDeploymentValidation; > -import javax.enterprise.inject.spi.AnnotatedMember; > -import javax.enterprise.inject.spi.AnnotatedType; > import javax.enterprise.inject.spi.BeanManager; > -import javax.enterprise.inject.spi.BeforeBeanDiscovery; > import javax.enterprise.inject.spi.BeforeShutdown; > +import javax.enterprise.inject.spi.DeploymentException; > import javax.enterprise.inject.spi.Extension; > import javax.enterprise.inject.spi.InjectionPoint; > import javax.enterprise.inject.spi.ProcessInjectionPoint; > import javax.inject.Provider; > -import java.lang.reflect.ParameterizedType; > -import java.lang.reflect.Type; > -import java.util.ArrayList; > -import java.util.Arrays; > -import java.util.Collection; > -import java.util.HashMap; > -import java.util.HashSet; > -import java.util.List; > -import java.util.Map; > -import java.util.Objects; > -import java.util.Optional; > -import java.util.Set; > -import java.util.function.BiFunction; > -import java.util.stream.Stream; > > -import static java.util.function.Function.identity; > -import static java.util.stream.Collectors.toMap; > -import static org.eclipse.microprofile.config.ConfigProvider.getConfig; > +import org.apache.geronimo.config.DefaultConfigProvider; > +import org.eclipse.microprofile.config.Config; > +import org.eclipse.microprofile.config.ConfigProvider; > +import org.eclipse.microprofile.config.inject.ConfigProperty; > > /** > * @author <a href="mailto:strub...@yahoo.de">Mark Struberg</a> > */ > public class ConfigExtension implements Extension { > - private static final Object NULL = new Object(); > - > private Config config; > - private ConfigProviderResolver resolver; > > - private Set<Injection> injections = new HashSet<>(); > - private List<Throwable> deploymentProblems = new ArrayList<>(); > private static final Map<Type, Type> REPLACED_TYPES = new HashMap<>(); > > static { > @@ -74,336 +58,65 @@ public class ConfigExtension implements > REPLACED_TYPES.put(boolean.class, Boolean.class); > } > > - void init(@Observes final BeforeBeanDiscovery beforeBeanDiscovery, final > BeanManager bm) { > - resolver = ConfigProviderResolver.instance(); > - config = getConfig(); > - } > + private Set<InjectionPoint> injectionPoints = new HashSet<>(); > + > > public void collectConfigProducer(@Observes ProcessInjectionPoint<?, ?> > pip) { > - final InjectionPoint injectionPoint = pip.getInjectionPoint(); > - final ConfigProperty configProperty = > injectionPoint.getAnnotated().getAnnotation(ConfigProperty.class); > + ConfigProperty configProperty = > pip.getInjectionPoint().getAnnotated().getAnnotation(ConfigProperty.class); > if (configProperty != null) { > - Type replacedType = > REPLACED_TYPES.getOrDefault(injectionPoint.getType(), > injectionPoint.getType()); > - Injection injection = new Injection(replacedType); > - final String key = getConfigKey(injectionPoint, configProperty); > - final boolean defaultUnset = > isDefaultUnset(configProperty.defaultValue()); > - if (!injections.add(injection)) { > - final Injection ref = injection; > - injection = injections.stream().filter(i -> > i.equals(ref)).findFirst().get(); > - } > - injection.keys.add(key); > - injection.defaultValues.add(configProperty.defaultValue()); > - > - final ConfigImpl configImpl = unwrapConfig(); > - > - // what about lazy runtime lookup, not consistent with tck and > system prop usage, for now assume optional=optional ;) > - boolean hasValue = true; > - if (defaultUnset) { // value validation > - if (ParameterizedType.class.isInstance(injection.type)) { > - final ParameterizedType pt = > ParameterizedType.class.cast(injection.type); > - if (pt.getRawType() != Optional.class && > !configImpl.getOptionalValue(key, String.class).isPresent()) { > - hasValue = false; > - } > - } else if (!configImpl.getOptionalValue(key, > String.class).isPresent()) { > - hasValue = false; > - } > - if (!hasValue) { > - deploymentProblems.add(new IllegalArgumentException("No > configured value for '" + key + "' from " + injectionPoint)); > - } > - } > - > - Class<?> instanceType = null; > - if (ParameterizedType.class.isInstance(injection.type)) { // > converters validation > - final ParameterizedType pt = > ParameterizedType.class.cast(injection.type); > - if (pt.getRawType() == Provider.class && > pt.getActualTypeArguments().length == 1 && > Class.class.isInstance(pt.getActualTypeArguments()[0]) > - && > !configImpl.getConverters().containsKey(Class.class.cast(pt.getActualTypeArguments()[0]))) > { > - instanceType = > Class.class.cast(pt.getActualTypeArguments()[0]); > - } // else if Optional it is fine, else we don't know how to > process > - } else if (Class.class.isInstance(injection.type)) { > - instanceType = Class.class.cast(injection.type); > - } > - if (instanceType != null) { // validate we have a converter + we > can convert the existing value > - if (!configImpl.getConverters().containsKey(instanceType)) { > - deploymentProblems.add(new > IllegalArgumentException("Missing converter for '" + key + "' from " + > injectionPoint)); > - } else if (hasValue) { > - try { > - > configImpl.getConverters().get(injection.type).convert(configImpl.getValue(key)); > - } catch (final RuntimeException re) { > - deploymentProblems.add(re); > - } > - } > - } > + injectionPoints.add(pip.getInjectionPoint()); > } > } > > public void registerConfigProducer(@Observes AfterBeanDiscovery abd, > BeanManager bm) { > - injections.stream() > - .flatMap(injection -> { > - final BiFunction<CreationalContext<?>, > ConfigInjectionBean<?>, String> keyProvider; > - if (injection.keys.size() == 1) { > - final String key = injection.keys.iterator().next(); > - keyProvider = (ctx, bean) -> key; > - } else { > - keyProvider = (ctx, bean) -> > getName(findInjectionPoint(bm, ctx, bean)); > - } > - > - if (ParameterizedType.class.isInstance(injection.type)) { > - final ParameterizedType paramType = > ParameterizedType.class.cast(injection.type); > - final Type rawType = paramType.getRawType(); > - > - // todo: do we care of Instance injection? doesnt > make much sense right? > - if (Provider.class == rawType && > paramType.getActualTypeArguments().length == 1) { > - if > (!Class.class.isInstance(paramType.getActualTypeArguments()[0])) { > - deploymentProblems.add(new > IllegalArgumentException("@ConfigProperty can only be used with Provider<T> > where T is a Class")); > - return Stream.empty(); > - } > - final Class<?> providerType = > Class.class.cast(paramType.getActualTypeArguments()[0]); > - return Stream.of(new > ConfigInjectionBean<Provider<?>>(injection.type, true) { > - @Override > - public Provider<?> create(final > CreationalContext<Provider<?>> context) { > - return () -> > config.getValue(keyProvider.apply(context, this), providerType); > - } > - }); > - } else if (Optional.class == rawType && > paramType.getActualTypeArguments().length == 1) { > - if > (!Class.class.isInstance(paramType.getActualTypeArguments()[0])) { > - deploymentProblems.add(new > IllegalArgumentException("@ConfigProperty can only be used with Optional<T> > where T is a Class")); > - return null; > - } > - final Class<?> optionalType = > Class.class.cast(paramType.getActualTypeArguments()[0]); > - return Stream.of(new > ConfigInjectionBean<Optional<?>>(injection.type) { > - @Override > - public Optional<?> create(final > CreationalContext<Optional<?>> context) { > - return > config.getOptionalValue(keyProvider.apply(context, this), optionalType); > - } > - }); > - } else { > - deploymentProblems.add(new > IllegalArgumentException("Unsupported parameterized type " + paramType)); > - return Stream.empty(); > - } > - } else if (Class.class.isInstance(injection.type)) { > - final Class clazz = Class.class.cast(injection.type); > - final ConfigInjectionBean bean; > - if (injection.defaultValues.isEmpty()) { > - bean = new > ConfigInjectionBean<Object>(injection.type) { > - @Override > - public Object create(final > CreationalContext<Object> context) { > - return > config.getOptionalValue(keyProvider.apply(context, this), clazz); > - } > - }; > - } else if (injection.defaultValues.size() == 1) { // > common enough to be optimized > - final String defVal = > injection.defaultValues.iterator().next(); > - final Object alternativeVal = > isDefaultUnset(defVal) ? null : unwrapConfig().convert(defVal, clazz); > - bean = new > ConfigInjectionBean<Object>(injection.type) { > - @Override > - public Object create(final > CreationalContext<Object> context) { > - final Optional optionalValue = > config.getOptionalValue(keyProvider.apply(context, this), clazz); > - return > optionalValue.orElse(alternativeVal); > - } > - }; > - } else { // sadly we need to get back to the > injection point to know which one we need to use > - final Map<String, Object> prepared = > injection.defaultValues.stream() > - .collect(toMap(identity(), k -> > isDefaultUnset(k) ? NULL : unwrapConfig().convert(k, clazz), (a, b) -> b)); > - bean = new > ConfigInjectionBean<Object>(injection.type) { > - @Override > - public Object create(final > CreationalContext<Object> context) { > - final InjectionPoint ip = > findInjectionPoint(bm, context, this); > - if (ip == null) { > - throw new > IllegalStateException("Could not retrieve InjectionPoint"); > - } > - return > config.getOptionalValue(ConfigExtension.this.getName(ip), clazz) > - .orElseGet(() -> { > - final Object val = > prepared.get(ip.getAnnotated().getAnnotation(ConfigProperty.class).defaultValue()); > - return val == NULL ? null : > val; > - }); > - } > - }; > - } > - > - final Collection<ConfigInjectionBean<?>> beans = new > ArrayList<>(); > - beans.add(bean); > - > - // is adding these beans is that useful? we captured > them all so only a programmatic lookup would justify it > - // and not sure it would be done this way anyway > - final ParameterizedTypeImpl providerType = new > ParameterizedTypeImpl(Provider.class, injection.type); > - if (injections.stream().noneMatch(i -> > i.type.equals(providerType))) { > - beans.add(new > ConfigInjectionBean<Provider<?>>(providerType, true) { > - @Override > - public Provider<?> create(final > CreationalContext<Provider<?>> context) { > - return () -> bean.create(context); > - } > - }); > - } > - > - final ParameterizedTypeImpl optionalType = new > ParameterizedTypeImpl(Optional.class, injection.type); > - if (injections.stream().noneMatch(i -> > i.type.equals(optionalType))) { > - beans.add(new > ConfigInjectionBean<Optional<?>>(optionalType) { > - @Override > - public Optional<?> create(final > CreationalContext<Optional<?>> context) { > - return > Optional.ofNullable(bean.create(context)); > - } > - }); > - } > - > - return beans.stream(); > - } else { > - deploymentProblems.add(new > IllegalArgumentException("Unknown type " + injection.type)); > - return Stream.empty(); > - } > - }) > - .forEach(abd::addBean); > - } > + Set<Class> types = injectionPoints.stream() > + .filter(ip -> ip.getType() instanceof Class) > + .map(ip -> (Class) REPLACED_TYPES.getOrDefault(ip.getType(), > ip.getType())) > + .collect(Collectors.toSet()); > + > + // Provider and Optional are ParameterizedTypes and not a Class, so > we need to add them manually > + types.add(Provider.class); > + types.add(Optional.class); > > - public void validate(@Observes AfterDeploymentValidation add) { > - deploymentProblems.forEach(add::addDeploymentProblem); > - injections.clear(); > - deploymentProblems.clear(); > + types.forEach(type -> abd.addBean(new ConfigInjectionBean(bm, > type))); > } > > - public void shutdown(@Observes BeforeShutdown bsd) { > - resolver.releaseConfig(config); > - } > + public void validate(@Observes AfterDeploymentValidation add) { > + List<String> deploymentProblems = new ArrayList<>(); > > - private ConfigImpl unwrapConfig() { > - return ConfigImpl.class.cast(config); > - } > + config = ConfigProvider.getConfig(); > > - private static String getName(final InjectionPoint ip) { > - final ConfigProperty annotation = > ip.getAnnotated().getAnnotation(ConfigProperty.class); > - final String name = annotation.name(); > - return isDefaultUnset(name) ? getConfigKey(ip, annotation) : name; > - } > + for (InjectionPoint injectionPoint : injectionPoints) { > + Type type = injectionPoint.getType(); > > - /** > - * Get the property key to use. > - * In case the {@link ConfigProperty#name()} is empty we will try to > determine the key name from the InjectionPoint. > - */ > - private static String getConfigKey(InjectionPoint ip, ConfigProperty > configProperty) { > - String key = configProperty.name(); > - if (!key.isEmpty()) { > - return key; > - } > - if (ip.getAnnotated() instanceof AnnotatedMember) { > - AnnotatedMember member = (AnnotatedMember) ip.getAnnotated(); > - AnnotatedType declaringType = member.getDeclaringType(); > - if (declaringType != null) { > - String[] parts = > declaringType.getJavaClass().getCanonicalName().split("\\."); > - String cn = parts[parts.length - 1]; > - parts[parts.length - 1] = > Character.toLowerCase(cn.charAt(0)) + (cn.length() > 1 ? cn.substring(1) : > ""); > - StringBuilder sb = new StringBuilder(parts[0]); > - for (int i = 1; i < parts.length; i++) { > - sb.append(".").append(parts[i]); > + // replace native types with their Wrapper types > + type = REPLACED_TYPES.getOrDefault(type, type); > + > + ConfigProperty configProperty = > injectionPoint.getAnnotated().getAnnotation(ConfigProperty.class); > + if (type instanceof Class) { > + // a direct injection of a ConfigProperty > + // that means a Converter must exist. > + String key = > ConfigInjectionBean.getConfigKey(injectionPoint, configProperty); > + if ((isDefaultUnset(configProperty.defaultValue())) > + && !config.getOptionalValue(key, (Class) > type).isPresent()) { > + deploymentProblems.add("No Config Value exists for " + > key); > } > - > - // now add the field name > - sb.append(".").append(member.getJavaMember().getName()); > - return sb.toString(); > } > } > > - throw new IllegalStateException("Could not find default name for > @ConfigProperty InjectionPoint " + ip); > - } > - > - private static boolean isDefaultUnset(String defaultValue) { > - return defaultValue == null || defaultValue.length() == 0 || > defaultValue.equals(ConfigProperty.UNCONFIGURED_VALUE); > - } > - > - private static InjectionPoint findInjectionPoint(final BeanManager bm, > final CreationalContext<?> ctx, > - ConfigInjectionBean > bean) { > - return > InjectionPoint.class.cast(bm.getInjectableReference(bean.getSimpleInjectionPoint(), > ctx)); > - } > - > - private static final class Injection { > - private final Type type; > - private final Collection<String> keys = new ArrayList<>(); > - private final Collection<String> defaultValues = new ArrayList<>(); > - > - private Injection(final Type type) { > - this.type = type; > - } > - > - @Override > - public boolean equals(final Object o) { > - if (this == o) { > - return true; > - } > - if (o == null || Injection.class != o.getClass()) { > - return false; > - } > - final Injection injection = Injection.class.cast(o); > - return Objects.equals(type, injection.type); > + if (!deploymentProblems.isEmpty()) { > + add.addDeploymentProblem(new DeploymentException("Error while > validating Configuration\n" > + + > String.join("\n", deploymentProblems))); > } > > - @Override > - public int hashCode() { > - return type.hashCode(); > - } > } > > - private class ParameterizedTypeImpl implements ParameterizedType { > - private final Type rawType; > - private final Type[] types; > - > - private ParameterizedTypeImpl(final Type raw, final Type... types) { > - this.rawType = raw; > - this.types = types; > - } > - > - @Override > - public Type[] getActualTypeArguments() { > - return types.clone(); > - } > - > - @Override > - public Type getOwnerType() { > - return null; > - } > - > - @Override > - public Type getRawType() { > - return rawType; > - } > - > - @Override > - public int hashCode() { > - return Arrays.hashCode(types) ^ rawType.hashCode(); > - } > - > - @Override > - public boolean equals(final Object obj) { > - if (this == obj) { > - return true; > - } > - if (ParameterizedType.class.isInstance(obj)) { > - final ParameterizedType that = > ParameterizedType.class.cast(obj); > - final Type thatRawType = that.getRawType(); > - return (rawType == null ? thatRawType == null : > rawType.equals(thatRawType)) > - && Arrays.equals(types, > that.getActualTypeArguments()); > - } > - return false; > - } > + public void shutdown(@Observes BeforeShutdown bsd) { > + DefaultConfigProvider.instance().releaseConfig(config); > + } > > - @Override > - public String toString() { > - final StringBuilder buffer = new StringBuilder(); > - buffer.append(Class.class.cast(rawType).getName()); > - final Type[] actualTypes = getActualTypeArguments(); > - if (actualTypes.length > 0) { > - buffer.append("<"); > - final int length = actualTypes.length; > - for (int i = 0; i < length; i++) { > - if (actualTypes[i] instanceof Class) { > - buffer.append(((Class<?>) > actualTypes[i]).getSimpleName()); > - } else { > - buffer.append(actualTypes[i].toString()); > - } > - if (i != actualTypes.length - 1) { > - buffer.append(","); > - } > - } > > - buffer.append(">"); > - } > - return buffer.toString(); > - } > + static boolean isDefaultUnset(String defaultValue) { > + return defaultValue.equals(ConfigProperty.UNCONFIGURED_VALUE); > } > } > > Modified: > geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java > URL: > http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java?rev=1804397&r1=1804396&r2=1804397&view=diff > ============================================================================== > --- > geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java > (original) > +++ > geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java > Tue Aug 8 10:55:56 2017 > @@ -16,49 +16,59 @@ > */ > package org.apache.geronimo.config.cdi; > > -import org.eclipse.microprofile.config.inject.ConfigProperty; > +import java.io.IOException; > +import java.io.Serializable; > +import java.lang.annotation.Annotation; > +import java.lang.reflect.ParameterizedType; > +import java.lang.reflect.Type; > +import java.util.Collections; > +import java.util.HashSet; > +import java.util.Optional; > +import java.util.Set; > > import javax.enterprise.context.Dependent; > import javax.enterprise.context.spi.CreationalContext; > -import javax.enterprise.inject.Default; > import javax.enterprise.inject.spi.Annotated; > +import javax.enterprise.inject.spi.AnnotatedMember; > +import javax.enterprise.inject.spi.AnnotatedType; > import javax.enterprise.inject.spi.Bean; > +import javax.enterprise.inject.spi.BeanManager; > import javax.enterprise.inject.spi.InjectionPoint; > import javax.enterprise.inject.spi.PassivationCapable; > import javax.enterprise.util.AnnotationLiteral; > -import java.lang.annotation.Annotation; > -import java.lang.reflect.Member; > -import java.lang.reflect.ParameterizedType; > -import java.lang.reflect.Type; > -import java.util.Collections; > -import java.util.HashSet; > -import java.util.Set; > +import javax.inject.Provider; > + > +import org.apache.geronimo.config.ConfigImpl; > +import org.eclipse.microprofile.config.Config; > +import org.eclipse.microprofile.config.ConfigProvider; > +import org.eclipse.microprofile.config.inject.ConfigProperty; > +import org.eclipse.microprofile.config.spi.ConfigProviderResolver; > > /** > * @author <a href="mailto:strub...@yahoo.de">Mark Struberg</a> > */ > -public abstract class ConfigInjectionBean<T> implements Bean<T>, > PassivationCapable { > +public class ConfigInjectionBean<T> implements Bean<T>, PassivationCapable { > > private final static Set<Annotation> QUALIFIERS = new HashSet<>(); > static { > QUALIFIERS.add(new ConfigPropertyLiteral()); > } > > + private final BeanManager bm; > private final Class rawType; > private final Set<Type> types; > - private final String id; > - private final boolean alternative; > - > - ConfigInjectionBean(Type type) { > - this(type,false); > - } > > - ConfigInjectionBean(Type type, boolean alternative) { > - this.types = new HashSet<>(); > - this.types.add(type); > - this.rawType = getRawType(type); > - this.id = "ConfigInjectionBean_" + type.toString(); > - this.alternative = alternative; > + /** > + * only access via {@link #getConfig(} > + */ > + private Config _config; > + > + public ConfigInjectionBean(BeanManager bm, Type type) { > + this.bm = bm; > + > + types = new HashSet<>(); > + types.add(type); > + rawType = getRawType(type); > } > > private Class getRawType(Type type) { > @@ -76,7 +86,7 @@ public abstract class ConfigInjectionBea > > @Override > public Set<InjectionPoint> getInjectionPoints() { > - return Collections.emptySet(); > + return Collections.EMPTY_SET; > } > > @Override > @@ -90,8 +100,90 @@ public abstract class ConfigInjectionBea > } > > @Override > + public T create(CreationalContext<T> context) { > + Set<Bean<?>> beans = bm.getBeans(InjectionPoint.class); > + Bean<?> bean = bm.resolve(beans); > + InjectionPoint ip = (InjectionPoint) bm.getReference(bean, > InjectionPoint.class, context); > + if (ip == null) { > + throw new IllegalStateException("Could not retrieve > InjectionPoint"); > + } > + Annotated annotated = ip.getAnnotated(); > + ConfigProperty configProperty = > annotated.getAnnotation(ConfigProperty.class); > + String key = getConfigKey(ip, configProperty); > + String defaultValue = configProperty.defaultValue(); > + > + if (annotated.getBaseType() instanceof ParameterizedType) { > + ParameterizedType paramType = (ParameterizedType) > annotated.getBaseType(); > + Type rawType = paramType.getRawType(); > + > + // handle Provider<T> > + if (rawType instanceof Class && ((Class) > rawType).isAssignableFrom(Provider.class) && > paramType.getActualTypeArguments().length == 1) { > + Class clazz = (Class) paramType.getActualTypeArguments()[0]; > //X TODO check type again, etc > + return (T) new ConfigValueProvider(getConfig(), key, clazz); > + } > + > + // handle Optional<T> > + if (rawType instanceof Class && ((Class) > rawType).isAssignableFrom(Optional.class) && > paramType.getActualTypeArguments().length == 1) { > + Class clazz = (Class) paramType.getActualTypeArguments()[0]; > //X TODO check type again, etc > + return (T) getConfig().getOptionalValue(key, clazz); > + } > + } > + else { > + Class clazz = (Class) annotated.getBaseType(); > + if (ConfigExtension.isDefaultUnset(defaultValue)) { > + return (T) getConfig().getValue(key, clazz); > + } > + else { > + Config config = getConfig(); > + return (T) config.getOptionalValue(key, clazz) > + .orElse(((ConfigImpl) config).convert(defaultValue, > clazz)); > + } > + } > + > + throw new IllegalStateException("unhandled ConfigProperty"); > + } > + > + > + /** > + * Get the property key to use. > + * In case the {@link ConfigProperty#name()} is empty we will try to > determine the key name from the InjectionPoint. > + */ > + public static String getConfigKey(InjectionPoint ip, ConfigProperty > configProperty) { > + String key = configProperty.name(); > + if (key.length() > 0) { > + return key; > + } > + if (ip.getAnnotated() instanceof AnnotatedMember) { > + AnnotatedMember member = (AnnotatedMember) ip.getAnnotated(); > + AnnotatedType declaringType = member.getDeclaringType(); > + if (declaringType != null) { > + String[] parts = > declaringType.getJavaClass().getCanonicalName().split("\\."); > + String cn = parts[parts.length-1]; > + parts[parts.length-1] = Character.toLowerCase(cn.charAt(0)) > + (cn.length() > 1 ? cn.substring(1) : ""); > + StringBuilder sb = new StringBuilder(parts[0]); > + for (int i = 1; i < parts.length; i++) { > + sb.append(".").append(parts[i]); > + } > + > + // now add the field name > + sb.append(".").append(member.getJavaMember().getName()); > + return sb.toString(); > + } > + } > + > + throw new IllegalStateException("Could not find default name for > @ConfigProperty InjectionPoint " + ip); > + } > + > + public Config getConfig() { > + if (_config == null) { > + _config = ConfigProvider.getConfig(); > + } > + return _config; > + } > + > + @Override > public void destroy(T instance, CreationalContext<T> context) { > - // no-op > + > } > > @Override > @@ -116,21 +208,17 @@ public abstract class ConfigInjectionBea > > @Override > public Set<Class<? extends Annotation>> getStereotypes() { > - return Collections.emptySet(); > + return Collections.EMPTY_SET; > } > > @Override > public boolean isAlternative() { > - return alternative; > + return true; > } > > @Override > public String getId() { > - return id; > - } > - > - InjectionPoint getSimpleInjectionPoint() { > - return simpleInjectionPoint; > + return "ConfigInjectionBean_" + rawType.getName(); > } > > private static class ConfigPropertyLiteral extends > AnnotationLiteral<ConfigProperty> implements ConfigProperty { > @@ -145,41 +233,31 @@ public abstract class ConfigInjectionBea > } > } > > - private final InjectionPoint simpleInjectionPoint = new InjectionPoint() > { > - > - @Override > - public boolean isTransient() { > - return false; > - } > - > - @Override > - public boolean isDelegate() { > - return false; > - } > - > - @Override > - public Type getType() { > - return InjectionPoint.class; > - } > - > - @Override > - public Set<Annotation> getQualifiers() { > - return Collections.singleton(new AnnotationLiteral<Default>() > {}); > - } > - > - @Override > - public Member getMember() { > - return null; > + /** > + * A special Provider<T> > + * This concrete class is needed because we need the injected Provider > for the ConfigProperty > + * to be Serializable. A Lambda would not work in this case > + */ > + public static class ConfigValueProvider<T> implements Provider<T>, > Serializable { > + private transient Config config; > + private final String key; > + private final Class<T> type; > + > + ConfigValueProvider(Config config, String key, Class<T> type) { > + this.config = config; > + this.key = key; > + this.type = type; > } > > @Override > - public Bean<?> getBean() { > - return ConfigInjectionBean.this; > + public T get() { > + return (T) config.getValue(key, type); > + } > + > + private void readObject(java.io.ObjectInputStream in) throws > IOException, ClassNotFoundException { > + in.defaultReadObject(); > + config = ConfigProviderResolver.instance().getConfig(); > } > > - @Override > - public Annotated getAnnotated() { > - return null; > - } > - }; > + } > } > > Modified: > geronimo/components/config/trunk/impl/src/test/java/org/apache/geronimo/config/test/internal/ProviderTest.java > URL: > http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/test/java/org/apache/geronimo/config/test/internal/ProviderTest.java?rev=1804397&r1=1804396&r2=1804397&view=diff > ============================================================================== > --- > geronimo/components/config/trunk/impl/src/test/java/org/apache/geronimo/config/test/internal/ProviderTest.java > (original) > +++ > geronimo/components/config/trunk/impl/src/test/java/org/apache/geronimo/config/test/internal/ProviderTest.java > Tue Aug 8 10:55:56 2017 > @@ -33,9 +33,12 @@ import org.testng.annotations.Test; > > public class ProviderTest extends Arquillian { > private static final String SOME_KEY = > "org.apache.geronimo.config.test.internal.somekey"; > + private static final String ANOTHER_KEY = > "org.apache.geronimo.config.test.internal.anotherkey"; > > @Deployment > public static WebArchive deploy() { > + System.setProperty(SOME_KEY, "someval"); > + System.setProperty(ANOTHER_KEY, "someval"); > JavaArchive testJar = ShrinkWrap > .create(JavaArchive.class, "configProviderTest.jar") > .addClasses(ProviderTest.class, SomeBean.class) > @@ -70,8 +73,16 @@ public class ProviderTest extends Arquil > @ConfigProperty(name=SOME_KEY) > private Provider<String> myconfig; > > + @Inject > + @ConfigProperty(name=ANOTHER_KEY) > + private Provider<String> anotherconfig; > + > public String getMyconfig() { > return myconfig.get(); > } > + > + public Provider<String> getAnotherconfig() { > + return anotherconfig; > + } > } > } > > Modified: geronimo/components/config/trunk/pom.xml > URL: > http://svn.apache.org/viewvc/geronimo/components/config/trunk/pom.xml?rev=1804397&r1=1804396&r2=1804397&view=diff > ============================================================================== > --- geronimo/components/config/trunk/pom.xml (original) > +++ geronimo/components/config/trunk/pom.xml Tue Aug 8 10:55:56 2017 > @@ -27,7 +27,7 @@ > </parent> > > <groupId>org.apache.geronimo.config</groupId> > - <artifactId>config-parent</artifactId> > + <artifactId>geronimo-config</artifactId> > <version>1.1-SNAPSHOT</version> > <packaging>pom</packaging> > <name>Geronimo Microprofile Configuration</name> > @@ -50,7 +50,7 @@ > <properties> > <maven.compiler.source>1.8</maven.compiler.source> > <maven.compiler.target>1.8</maven.compiler.target> > - > <microprofile-config.version>1.1-SNAPSHOT</microprofile-config.version> > + <microprofile-config.version>1.0</microprofile-config.version> > <owb.version>1.7.3</owb.version> > <owb2.version>2.0.1-SNAPSHOT</owb2.version> > <arquillian.version>1.1.13.Final</arquillian.version> > >