Repository: incubator-tamaya Updated Branches: refs/heads/master 76524b2e4 -> cd43cfacd
TAMAYA-260 Fixed MP Optional and Provider injection (and a corresponding issue in core in the Optional converter). Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/cd43cfac Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/cd43cfac Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/cd43cfac Branch: refs/heads/master Commit: cd43cfacd837d2adae7c61ff29b4e51ceee7dd21 Parents: 76524b2 Author: Anatole Tresch <[email protected]> Authored: Thu Oct 12 11:46:47 2017 +0200 Committer: Anatole Tresch <[email protected]> Committed: Thu Oct 12 11:47:34 2017 +0200 ---------------------------------------------------------------------- .../apache/tamaya/spi/ConversionContext.java | 14 ++++- .../internal/converters/OptionalConverter.java | 65 +++++++++++++++----- 2 files changed, 62 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd43cfac/code/api/src/main/java/org/apache/tamaya/spi/ConversionContext.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ConversionContext.java b/code/api/src/main/java/org/apache/tamaya/spi/ConversionContext.java index 0bfda0b..4553e52 100644 --- a/code/api/src/main/java/org/apache/tamaya/spi/ConversionContext.java +++ b/code/api/src/main/java/org/apache/tamaya/spi/ConversionContext.java @@ -141,7 +141,7 @@ public class ConversionContext { /** The accessed key, or null. */ private String key; /** The target type. */ - private final TypeLiteral<?> targetType; + private TypeLiteral<?> targetType; /** The injection target (only set with injection used). */ private AnnotatedElement annotatedElement; /** The ordered list of formats tried. */ @@ -219,6 +219,17 @@ public class ConversionContext { } /** + * Sets the target type explicitly. This is required in some rare cases, e.g. injection of {@code Provider} + * instances, where the provider's result type must be produced. + * @param targetType the + * @return the builder for chaining. + */ + public Builder setTargetType(TypeLiteral targetType) { + this.targetType = Objects.requireNonNull(targetType); + return this; + } + + /** * Add the formats provided by a {@link PropertyConverter}. This method should be called by each converter * performing/trying conversion, so the user can be given feedback on the supported formats on failure. * @param converterType the converter type, not {@code null}. @@ -251,5 +262,6 @@ public class ConversionContext { ", supportedFormats=" + supportedFormats + '}'; } + } } http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd43cfac/code/core/src/main/java/org/apache/tamaya/core/internal/converters/OptionalConverter.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/OptionalConverter.java b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/OptionalConverter.java index 2213bcc..58fe898 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/OptionalConverter.java +++ b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/OptionalConverter.java @@ -18,16 +18,22 @@ */ package org.apache.tamaya.core.internal.converters; +import org.apache.tamaya.ConfigException; +import org.apache.tamaya.ConfigQuery; +import org.apache.tamaya.Configuration; import org.apache.tamaya.TypeLiteral; import org.apache.tamaya.core.internal.PropertyConverterManager; import org.apache.tamaya.spi.ConversionContext; import org.apache.tamaya.spi.PropertyConverter; import org.osgi.service.component.annotations.Component; +import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.Locale; +import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.logging.Level; import java.util.logging.Logger; /** @@ -36,24 +42,18 @@ import java.util.logging.Logger; @Component(service = PropertyConverter.class) public class OptionalConverter implements PropertyConverter<Optional> { - private final Logger LOG = Logger.getLogger(getClass().getName()); + private static final Logger LOG = Logger.getLogger(OptionalConverter.class.getName()); @Override - public Optional<?> convert(String value, ConversionContext context) { - TypeLiteral<Optional> target = (TypeLiteral<Optional>)context.getTargetType(); - Object result = null; - Type targetType = TypeLiteral.getTypeParameters(target.getType())[0]; - if(String.class.equals(targetType)){ - result = value; + public Optional convert(String value, ConversionContext context) { + try{ + Type targetType = context.getTargetType().getType(); + ParameterizedType pt = (ParameterizedType) targetType; + ConvertQuery converter = new ConvertQuery(value, TypeLiteral.of(pt.getActualTypeArguments()[0])); + return Optional.ofNullable(context.getConfiguration().query(converter)); + }catch(Exception e){ + throw new ConfigException("Error evaluating config value.", e); } - for(PropertyConverter pv:context.getConfigurationContext().getPropertyConverters( - TypeLiteral.of(targetType))){ - result = pv.convert(value, context); - if(result!=null){ - return Optional.of(result); - } - } - return Optional.ofNullable(result); } @Override @@ -65,4 +65,37 @@ public class OptionalConverter implements PropertyConverter<Optional> { public int hashCode(){ return getClass().hashCode(); } + + + private static final class ConvertQuery<T> implements ConfigQuery<T>{ + + private String rawValue; + private TypeLiteral<T> type; + + public ConvertQuery(String rawValue, TypeLiteral<T> type) { + this.rawValue = Objects.requireNonNull(rawValue); + this.type = Objects.requireNonNull(type); + } + + @Override + public T query(Configuration config) { + List<PropertyConverter<T>> converters = config.getContext().getPropertyConverters(type); + ConversionContext context = new ConversionContext.Builder(type).setConfigurationContext(config.getContext()) + .setConfiguration(config).setKey(ConvertQuery.class.getName()).build(); + for(PropertyConverter<?> conv: converters) { + try{ + if(conv instanceof OptionalConverter){ + continue; + } + T result = (T)conv.convert(rawValue, context); + if(result!=null){ + return result; + } + }catch(Exception e){ + LOG.log(Level.FINEST, e, () -> "Converter "+ conv +" failed to convert to " + type); + } + } + return null; + } + } }
