TAMAYA-274 Reduced API footprint by using Java 8 features. Added some lambdas. TAMAYA-355 Enable mapping of lists and arrays into internal datastructures. TAMAYA-353 Adding support for different classloaders.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/e45effd2 Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/e45effd2 Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/e45effd2 Branch: refs/heads/master Commit: e45effd223ff2601e6251c3bcee3641dea27566c Parents: bf18659 Author: Anatole Tresch <[email protected]> Authored: Tue Oct 23 18:37:52 2018 +0200 Committer: Anatole Tresch <[email protected]> Committed: Tue Oct 23 18:37:53 2018 +0200 ---------------------------------------------------------------------- .../java/org/apache/tamaya/ConfigOperator.java | 2 + .../java/org/apache/tamaya/ConfigQuery.java | 5 +- .../java/org/apache/tamaya/Configuration.java | 184 ++++- .../apache/tamaya/ConfigurationProvider.java | 33 +- .../org/apache/tamaya/spi/ClassloaderAware.java | 50 ++ .../apache/tamaya/spi/ConfigurationBuilder.java | 59 +- .../apache/tamaya/spi/ConfigurationContext.java | 73 +- .../tamaya/spi/ConfigurationContextBuilder.java | 21 + .../tamaya/spi/ConfigurationProviderSpi.java | 52 +- .../apache/tamaya/spi/ConversionContext.java | 103 ++- .../org/apache/tamaya/spi/FilterContext.java | 85 +- .../apache/tamaya/spi/PropertyConverter.java | 14 +- .../org/apache/tamaya/spi/PropertyFilter.java | 7 +- .../org/apache/tamaya/spi/PropertySource.java | 8 +- .../tamaya/spi/PropertySourceProvider.java | 4 +- .../org/apache/tamaya/spi/PropertyValue.java | 787 ++++++++++++++++--- .../apache/tamaya/spi/PropertyValueBuilder.java | 138 ++-- .../spi/PropertyValueCombinationPolicy.java | 13 +- .../org/apache/tamaya/spi/ServiceContext.java | 58 +- .../tamaya/spi/ServiceContextManager.java | 70 +- .../tamaya/ConfigurationProviderTest.java | 10 +- .../org/apache/tamaya/ConfigurationTest.java | 86 +- .../org/apache/tamaya/TestConfiguration.java | 17 +- .../tamaya/TestConfigurationProvider.java | 4 +- .../spi/ConfigurationProviderSpiTest.java | 4 +- .../tamaya/spi/ConversionContextTest.java | 112 +-- .../apache/tamaya/spi/FilterContextTest.java | 107 ++- .../tamaya/spi/PropertyValueBuilderTest.java | 490 +++++------- .../spi/PropertyValueCombinationPolicyTest.java | 16 +- .../apache/tamaya/spi/PropertyValueTest.java | 391 ++++++--- .../tamaya/spi/ServiceContextManagerTest.java | 22 +- .../apache/tamaya/spi/ServiceContextTest.java | 21 +- .../spi/TestLowerOrdinalServiceContext.java | 13 +- .../apache/tamaya/spi/TestServiceContext.java | 25 +- .../core/internal/CoreConfigurationBuilder.java | 11 +- .../internal/CoreConfigurationProvider.java | 41 +- .../core/internal/OSGIServiceContext.java | 15 +- .../converters/BigDecimalConverter.java | 9 +- .../converters/BigIntegerConverter.java | 41 +- .../internal/converters/BooleanConverter.java | 5 +- .../core/internal/converters/ByteConverter.java | 5 +- .../core/internal/converters/CharConverter.java | 5 +- .../internal/converters/ClassConverter.java | 5 +- .../core/internal/converters/ConvertQuery.java | 29 +- .../internal/converters/CurrencyConverter.java | 5 +- .../internal/converters/DoubleConverter.java | 7 +- .../internal/converters/DurationConverter.java | 7 +- .../core/internal/converters/FileConverter.java | 5 +- .../internal/converters/FloatConverter.java | 8 +- .../internal/converters/InstantConverter.java | 5 +- .../internal/converters/IntegerConverter.java | 5 +- .../internal/converters/LocalDateConverter.java | 5 +- .../converters/LocalDateTimeConverter.java | 5 +- .../internal/converters/LocalTimeConverter.java | 5 +- .../core/internal/converters/LongConverter.java | 5 +- .../internal/converters/NumberConverter.java | 9 +- .../converters/OffsetDateTimeConverter.java | 5 +- .../converters/OffsetTimeConverter.java | 5 +- .../internal/converters/OptionalConverter.java | 6 +- .../core/internal/converters/PathConverter.java | 5 +- .../internal/converters/ShortConverter.java | 5 +- .../internal/converters/SupplierConverter.java | 6 +- .../core/internal/converters/URIConverter.java | 5 +- .../core/internal/converters/URLConverter.java | 5 +- .../tamaya/core/ConfigurationBuilderTest.java | 32 +- .../core/ConfigurationContextBuilderTest.java | 32 +- .../apache/tamaya/core/ConfigurationTest.java | 8 +- .../apache/tamaya/core/OSGIActivatorTest.java | 8 +- .../apache/tamaya/core/TestPropertySource.java | 8 +- .../tamaya/core/internal/BannerManagerTest.java | 2 +- .../java/org/apache/tamaya/core/internal/C.java | 2 +- .../tamaya/core/internal/CTestConverter.java | 3 +- .../internal/CoreConfigurationBuilderTest.java | 17 +- .../internal/CoreConfigurationProviderTest.java | 18 +- .../core/internal/CoreConfigurationTest.java | 13 +- .../core/internal/OSGIServiceContextTest.java | 4 +- .../converters/BigDecimalConverterTest.java | 19 +- .../converters/BigIntegerConverterTest.java | 24 +- .../converters/BooleanConverterTest.java | 12 +- .../internal/converters/ByteConverterTest.java | 16 +- .../internal/converters/CharConverterTest.java | 35 +- .../internal/converters/ClassConverterTest.java | 21 +- .../internal/converters/ConvertQueryTest.java | 9 +- .../converters/CurrencyConverterTest.java | 26 +- .../converters/DoubleConverterTest.java | 29 +- .../converters/DurationConverterTest.java | 20 +- .../internal/converters/FileConverterTest.java | 7 +- .../internal/converters/FloatConverterTest.java | 30 +- .../converters/InstantConverterTest.java | 12 +- .../converters/IntegerConverterTest.java | 19 +- .../converters/LocalDateConverterTest.java | 12 +- .../converters/LocalDateTimeConverterTest.java | 12 +- .../converters/LocalTimeConverterTest.java | 12 +- .../internal/converters/LongConverterTest.java | 19 +- .../converters/NumberConverterTest.java | 23 +- .../converters/OffsetDateTimeConverterTest.java | 13 +- .../converters/OffsetTimeConverterTest.java | 12 +- .../converters/OptionalConverterTest.java | 22 +- .../internal/converters/PathConverterTest.java | 19 +- .../internal/converters/ShortConverterTest.java | 19 +- .../converters/SupplierConverterTest.java | 18 +- .../internal/converters/URIConverterTest.java | 22 +- .../internal/converters/URLConverterTest.java | 22 +- .../testdata/TestPropertyDefaultSource.java | 2 +- .../core/testdata/TestPropertyFilter.java | 13 +- .../testdata/TestRemovingPropertyFilter.java | 14 +- .../tamaya/spisupport/ConfigValueEvaluator.java | 55 +- .../tamaya/spisupport/ConfigurationBuilder.java | 334 -------- .../tamaya/spisupport/DefaultConfiguration.java | 86 +- .../spisupport/DefaultConfigurationBuilder.java | 301 +++++-- .../spisupport/DefaultConfigurationContext.java | 45 +- .../DefaultConfigurationContextBuilder.java | 32 +- .../spisupport/DefaultServiceContext.java | 135 ++-- .../apache/tamaya/spisupport/EnumConverter.java | 6 +- .../spisupport/PropertyConverterManager.java | 39 +- .../tamaya/spisupport/PropertyFiltering.java | 103 ++- .../tamaya/spisupport/RegexPropertyFilter.java | 9 +- .../propertysource/BasePropertySource.java | 4 +- .../EnvironmentPropertySource.java | 15 +- .../JavaConfigurationPropertySource.java | 34 +- .../PropertiesResourcePropertySource.java | 7 +- .../propertysource/SimplePropertySource.java | 14 +- .../propertysource/SystemPropertySource.java | 13 +- .../java/org/apache/tamaya/spisupport/C.java | 2 +- .../tamaya/spisupport/CTestConverter.java | 3 +- .../DefaultConfigValueEvaluatorTest.java | 5 +- .../DefaultConfigurationBuilderTest.java | 20 +- .../DefaultConfigurationContextBuilderTest.java | 44 +- .../spisupport/DefaultConfigurationTest.java | 43 +- .../spisupport/EmptyConfigurationContext.java | 5 + .../EmptyConfigurationContextBuilder.java | 16 +- .../tamaya/spisupport/EnumConverterTest.java | 9 +- .../tamaya/spisupport/IntegerTestConverter.java | 6 +- .../spisupport/MockedConfigurationContext.java | 15 +- .../tamaya/spisupport/MockedPropertyFilter.java | 3 +- .../tamaya/spisupport/MockedPropertySource.java | 2 +- .../PropertyConverterManagerTest.java | 60 +- .../PropertyFilterComparatorTest.java | 6 +- .../spisupport/RegexPropertyFilterTest.java | 29 +- .../spisupport/TestConfigurationProvider.java | 6 +- .../propertysource/EnumConverterTest.java | 8 +- .../EnvironmentPropertySourceTest.java | 8 +- .../JavaConfigurationProviderTest.java | 5 +- .../PropertiesResourcePropertySourceTest.java | 5 +- .../SimplePropertySourceTest.java | 4 +- .../SystemPropertySourceTest.java | 4 +- .../TestPropertyDefaultSource.java | 3 +- .../WrappedPropertySourceTest.java | 2 +- .../services/DefaultServiceContext.java | 40 +- .../src/main/assembly/distribution-src.xml | 2 +- distribution/src/main/assembly/index.html | 2 +- 151 files changed, 3518 insertions(+), 2114 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/code/api/src/main/java/org/apache/tamaya/ConfigOperator.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/ConfigOperator.java b/code/api/src/main/java/org/apache/tamaya/ConfigOperator.java index 52f97c1..64853c5 100644 --- a/code/api/src/main/java/org/apache/tamaya/ConfigOperator.java +++ b/code/api/src/main/java/org/apache/tamaya/ConfigOperator.java @@ -22,8 +22,10 @@ package org.apache.tamaya; * Models a function that maps a given {@link org.apache.tamaya.Configuration} to another {@link org.apache.tamaya.Configuration}. This can be used * to model additional functionality and applying it to a given {@link org.apache.tamaya.Configuration} instance by calling * the {@link org.apache.tamaya.Configuration#with(org.apache.tamaya.ConfigOperator)} method. + * @deprecated Use {@link java.util.function.UnaryOperator} */ @FunctionalInterface +@Deprecated public interface ConfigOperator { /** http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/code/api/src/main/java/org/apache/tamaya/ConfigQuery.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/ConfigQuery.java b/code/api/src/main/java/org/apache/tamaya/ConfigQuery.java index 25ed2ec..bc1e444 100644 --- a/code/api/src/main/java/org/apache/tamaya/ConfigQuery.java +++ b/code/api/src/main/java/org/apache/tamaya/ConfigQuery.java @@ -22,9 +22,12 @@ package org.apache.tamaya; * Models a function that maps a given {@link Configuration} to something else. This can be used * to model additional functionality and applying it to a given {@link Configuration} instance by * calling the {@link Configuration#query(ConfigQuery)} method. + * + * @deprecated Use {@link java.util.function.Function} */ @FunctionalInterface -public interface ConfigQuery<T> { +@Deprecated +public interface ConfigQuery<T>{ /** * Creates a result based on the given {@link Configuration}. Queries basically act similar to http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/code/api/src/main/java/org/apache/tamaya/Configuration.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/Configuration.java b/code/api/src/main/java/org/apache/tamaya/Configuration.java index 5a8c895..7363a8f 100644 --- a/code/api/src/main/java/org/apache/tamaya/Configuration.java +++ b/code/api/src/main/java/org/apache/tamaya/Configuration.java @@ -20,8 +20,14 @@ package org.apache.tamaya; import org.apache.tamaya.spi.ConfigurationBuilder; import org.apache.tamaya.spi.ConfigurationContext; +import org.apache.tamaya.spi.ConfigurationProviderSpi; +import org.apache.tamaya.spi.ServiceContextManager; +import java.util.Collections; import java.util.Map; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.UnaryOperator; /** @@ -70,6 +76,40 @@ public interface Configuration { } /** + * Access a String property, using an an {@link Optional} instance. + * + * @param key the property's key, not {@code null}. + * @return the property's keys. + */ + default Optional<String> getOptional(String key){ + return Optional.ofNullable(getOrDefault(key, String.class, null)); + } + + /** + * Access a property, using an an {@link Optional} instance. + * + * @param key the property's key, not {@code null}. + * @param type the target type, not null. + * @param <T> the type of the class modeled by the type parameter + * @return the property's keys. + */ + default <T> Optional<T> getOptional(String key, Class<T> type){ + return Optional.ofNullable(getOrDefault(key, TypeLiteral.of(type), null)); + } + + /** + * Access a property, using an an {@link Optional} instance. + * + * @param key the property's key, not {@code null}. + * @param type the target type, not null. + * @param <T> the type of the class modeled by the type parameter + * @return the property's keys. + */ + default <T> Optional<T> getOptional(String key, TypeLiteral<T> type){ + return Optional.ofNullable(getOrDefault(key, type, null)); + } + + /** * Gets the property keys as type T. This will implicitly require a corresponding {@link * org.apache.tamaya.spi.PropertyConverter} to be available that is capable of providing type T * fromMap for the given String keys. @@ -135,7 +175,7 @@ public interface Configuration { * Access all currently known configuration properties as a full {@code Map<String,String>}. * Be aware that entries from non scannable parts of the registered {@link org.apache.tamaya.spi.PropertySource} * instances may not be contained in the result, but nevertheless be accessible by calling one of the - * {@code get(...)} methods. + * {@code current(...)} methods. * @return all currently known configuration properties. */ Map<String,String> getProperties(); @@ -146,23 +186,49 @@ public interface Configuration { * @param operator A configuration operator, e.g. a filter, or an adjuster * combining configurations, never {@code null}. * @return the new adjusted configuration returned by the {@code operator}, never {@code null}. + * @deprecated use {@link #map(UnaryOperator)} */ + @Deprecated default Configuration with(ConfigOperator operator){ return operator.operate(this); } /** + * Extension point for adjusting configuration. + * + * @param operator A configuration operator, e.g. a filter, or an adjuster + * combining configurations, never {@code null}. + * @return the new adjusted configuration returned by the {@code operator}, never {@code null}. + */ + default Configuration map(UnaryOperator<Configuration> operator){ + return operator.apply(this); + } + + /** * Query a configuration. * * @param <T> the type of the configuration. * @param query the query, not {@code null}. * @return the result returned by the {@code query}. + * @deprecated Use {@link #adapt(Function)} */ + @Deprecated default <T> T query(ConfigQuery<T> query){ return query.query(this); } /** + * Query a configuration. + * + * @param <T> the type of the configuration. + * @param query the query, not {@code null}. + * @return the result returned by the {@code query}. + */ + default <T> T adapt(Function<Configuration, T> query){ + return query.apply(this); + } + + /** * Access a configuration's context. * @return the configuration context, never null. */ @@ -173,7 +239,121 @@ public interface Configuration { * @return a new builder, never null. */ default ConfigurationBuilder toBuilder() { - return ConfigurationProvider.getConfigurationBuilder().setConfiguration(this); + return getContext().getServiceContext() + .getService(ConfigurationProviderSpi.class).getConfigurationBuilder().setConfiguration(this); + } + + /** + * This method allows replacement of the current default {@link org.apache.tamaya.Configuration} with a new + * instance. It is the responsibility of the ConfigurationProvider to trigger + * corresponding update events for the current {@link org.apache.tamaya.Configuration}, so observing + * listeners can do whatever is appropriate to react to any given configuration change. + * + * @param config the new Configuration to be applied, not {@code null} + * @throws java.lang.UnsupportedOperationException if the current provider is read-only and + * does not support + * applying a new Configuration. + */ + static void setCurrent(Configuration config) { + ServiceContextManager.getServiceContext() + .getService(ConfigurationProviderSpi.class).setConfiguration(config, Thread.currentThread().getContextClassLoader()); + } + + /** + * This method allows replacement of the current default {@link org.apache.tamaya.Configuration} with a new + * instance. It is the responsibility of the ConfigurationProvider to trigger + * corresponding update events for the current {@link org.apache.tamaya.Configuration}, so observing + * listeners can do whatever is appropriate to react to any given configuration change. + * + * @param config the new Configuration to be applied, not {@code null} + * @param classLoader the target classloader, not null. + * @throws java.lang.UnsupportedOperationException if the current provider is read-only and + * does not support + * applying a new Configuration. + */ + static void setCurrent(Configuration config, ClassLoader classLoader) { + ServiceContextManager.getServiceContext(classLoader) + .getService(ConfigurationProviderSpi.class).setConfiguration(config, classLoader); + } + + /** + * Access the configuration instance for the current thread's context classloader. + * @return the configuration instance, never null. + */ + static Configuration current(){ + return ServiceContextManager.getServiceContext() + .getService(ConfigurationProviderSpi.class).getConfiguration(Thread.currentThread().getContextClassLoader()); + } + + /** + * Accesses the configuration for a given classloader. + * @param classloader the classloader, not null. + * @return the configuration instance, never null. + */ + static Configuration current(ClassLoader classloader){ + return ServiceContextManager.getServiceContext(classloader) + .getService(ConfigurationProviderSpi.class).getConfiguration(classloader); + } + + /** + * Access a new configuration builder initialized with the current thread's context classloader. + * @return the builder, never null. + */ + static ConfigurationBuilder createConfigurationBuilder(){ + return ServiceContextManager.getServiceContext() + .getService(ConfigurationProviderSpi.class).getConfigurationBuilder(); } + + /** + * Immutable and reusable, thread-safe implementation of an empty propertySource. + */ + Configuration EMPTY = new Configuration() { + + @Override + public String get(String key) { + return null; + } + + @Override + public String getOrDefault(String key, String defaultValue) { + return defaultValue; + } + + @Override + public <T> T getOrDefault(String key, Class<T> type, T defaultValue) { + return defaultValue; + } + + @Override + public <T> T get(String key, Class<T> type) { + return null; + } + + @Override + public <T> T get(String key, TypeLiteral<T> type) { + return null; + } + + @Override + public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) { + return defaultValue; + } + + @Override + public Map<String, String> getProperties() { + return Collections.emptyMap(); + } + + @Override + public ConfigurationContext getContext() { + return ConfigurationContext.EMPTY; + } + + @Override + public String toString(){ + return "Configuration<empty>"; + } + }; + } http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/code/api/src/main/java/org/apache/tamaya/ConfigurationProvider.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/ConfigurationProvider.java b/code/api/src/main/java/org/apache/tamaya/ConfigurationProvider.java index bb32550..54d82f4 100644 --- a/code/api/src/main/java/org/apache/tamaya/ConfigurationProvider.java +++ b/code/api/src/main/java/org/apache/tamaya/ConfigurationProvider.java @@ -24,7 +24,9 @@ import java.util.logging.Logger; /** * Static access to the {@link Configuration} of the whole application. + * @deprecated Use static methods of {@link Configuration} */ +@Deprecated public final class ConfigurationProvider { private static final Logger LOG = Logger.getLogger(ConfigurationProvider.class.getName()); @@ -36,7 +38,7 @@ public final class ConfigurationProvider { throw new IllegalStateException("ConfigurationProviderSpi not available."); } LOG.finest("TAMAYA Delegate : " + spi.getClass().getName()); - LOG.info("TAMAYA Configuration : " + spi.getConfiguration()); + LOG.info("TAMAYA Configuration : " + spi.getConfiguration(Thread.currentThread().getContextClassLoader())); return spi; } @@ -50,7 +52,16 @@ public final class ConfigurationProvider { * @return the corresponding Configuration instance, never {@code null}. */ public static Configuration getConfiguration() { - return spi().getConfiguration(); + return spi().getConfiguration(Thread.currentThread().getContextClassLoader()); + } + + /** + * Access the current configuration. + * @param classLoader the target classloader, not null. + * @return the corresponding Configuration instance, never {@code null}. + */ + public static Configuration getConfiguration(ClassLoader classLoader) { + return spi().getConfiguration(classLoader); } /** @@ -103,8 +114,24 @@ public final class ConfigurationProvider { * applying a new Configuration. */ public static void setConfiguration(Configuration config) { + setConfiguration(config, Thread.currentThread().getContextClassLoader()); + } + + /** + * This method allows replacement of the current default {@link org.apache.tamaya.Configuration} with a new + * instance. It is the responsibility of the ConfigurationProvider to trigger + * corresponding update events for the current {@link org.apache.tamaya.Configuration}, so observing + * listeners can do whatever is appropriate to react to any given configuration change. + * + * @param config the new Configuration to be applied, not {@code null} + * @param classLoader the target classloader, not null. + * @throws java.lang.UnsupportedOperationException if the current provider is read-only and + * does not support + * applying a new Configuration. + */ + public static void setConfiguration(Configuration config, ClassLoader classLoader) { LOG.info("TAMAYA Applying new Configuration: " + config); - spi().setConfiguration(config); + spi().setConfiguration(config, classLoader); } /** http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/code/api/src/main/java/org/apache/tamaya/spi/ClassloaderAware.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ClassloaderAware.java b/code/api/src/main/java/org/apache/tamaya/spi/ClassloaderAware.java new file mode 100644 index 0000000..9e7863a --- /dev/null +++ b/code/api/src/main/java/org/apache/tamaya/spi/ClassloaderAware.java @@ -0,0 +1,50 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ +package org.apache.tamaya.spi; + + + +/** + * <p>This interface models a provider that serves configuration properties that is also dependent on the + * target classloader of the current configuration. </p> + * @see PropertySource + * @see PropertySourceProvider + * <h3>Implementation Requirements</h3> + * <p>Implementations of this interface must be</p> + * <ul> + * <li>Thread safe.</li> + * </ul> + */ +public interface ClassloaderAware{ + + /** + * Initializes this instance with the classloader to be used. + * This method is called by the implementation when the instance is loaded + * through the {@link ServiceContextManager}. + * @param classLoader the target classloader, not not null. + */ + void init(ClassLoader classLoader); + + /** + * Get the currently assigned cassloader instance. + * @return the classloader, never null. + */ + ClassLoader getClassLoader(); + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java index ada9430..586faac 100644 --- a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java +++ b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java @@ -21,10 +21,7 @@ package org.apache.tamaya.spi; import org.apache.tamaya.Configuration; import org.apache.tamaya.TypeLiteral; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.Map; +import java.util.*; /** * A builder for creating new instances of {@link Configuration}. @@ -43,6 +40,21 @@ import java.util.Map; public interface ConfigurationBuilder { /** + * Set the classloader to be used for loading of configuration resources, equals to + * {@code setServiceContext(ServiceContextManager.getServiceContext(classLoader))}. + * @param classLoader the classloader, not null. + * @return the builder for chaining. + */ + ConfigurationBuilder setClassLoader(ClassLoader classLoader); + + /** + * Sets the ServiceContext to be used. + * @param serviceContext the serviceContext, nuo null. + * @return this instance for chaining. + */ + ConfigurationBuilder setServiceContext(ServiceContext serviceContext); + + /** * Init this builder instance with the given {@link Configuration} instance. This * method will use any existing property sources, filters, converters and the combination * policy of the given {@link Configuration} and initialize the current builder @@ -52,7 +64,9 @@ public interface ConfigurationBuilder { * @param config the {@link Configuration} instance to be used, not {@code null}. * @return this builder, for chaining, never null. */ - ConfigurationBuilder setConfiguration(Configuration config); + default ConfigurationBuilder setConfiguration(Configuration config){ + return setContext(config.getContext()); + } /** * Init this builder instance with the given {@link ConfigurationContext} instance. This @@ -77,7 +91,9 @@ public interface ConfigurationBuilder { * @throws IllegalArgumentException If a property source with a given name already * exists. */ - ConfigurationBuilder addPropertySources(PropertySource... propertySources); + default ConfigurationBuilder addPropertySources(PropertySource... propertySources){ + return addPropertySources(Arrays.asList(propertySources)); + } /** * This method can be used for programmatically adding {@link PropertySource}s. @@ -107,7 +123,9 @@ public interface ConfigurationBuilder { * @param propertySources the property sources to remove, not {@code null}. * @return the builder for chaining. */ - ConfigurationBuilder removePropertySources(PropertySource... propertySources); + default ConfigurationBuilder removePropertySources(PropertySource... propertySources){ + return removePropertySources(Arrays.asList(propertySources)); + } /** * Removes the given property sources, if existing. The existing order of property @@ -200,7 +218,9 @@ public interface ConfigurationBuilder { * @param filters the filters to add * @return this builder, for chaining, never null. */ - ConfigurationBuilder addPropertyFilters(PropertyFilter... filters); + default ConfigurationBuilder addPropertyFilters(PropertyFilter... filters){ + return addPropertyFilters(Arrays.asList(filters)); + } /** * Adds the given {@link PropertyFilter} instances, hereby the instances are added @@ -226,16 +246,18 @@ public interface ConfigurationBuilder { * @param filters the filter to remove * @return this builder, for chaining, never null. */ - ConfigurationBuilder removePropertyFilters(PropertyFilter... filters); + default ConfigurationBuilder removePropertyFilters(PropertyFilter... filters){ + return removePropertyFilters(Arrays.asList(filters)); + } /** * Removes the given {@link PropertyFilter} instances, if existing. The order of the remaining * filters is preserved. * - * @param filters the filter to remove + * @param filter the filter to remove * @return this builder, for chaining, never null. */ - ConfigurationBuilder removePropertyFilters(Collection<PropertyFilter> filters); + ConfigurationBuilder removePropertyFilters(Collection<PropertyFilter> filter); /** * This method can be used for adding {@link PropertyConverter}s. @@ -248,8 +270,11 @@ public interface ConfigurationBuilder { * @param <T> the target type. * @return this builder, for chaining, never null. */ - <T> ConfigurationBuilder addPropertyConverters(TypeLiteral<T> typeToConvert, - @SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters); + default <T> ConfigurationBuilder addPropertyConverters(TypeLiteral<T> typeToConvert, + @SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters){ + return addPropertyConverters(typeToConvert, Arrays.asList(propertyConverters)); + } + /** * This method can be used for adding {@link PropertyConverter}s. @@ -280,8 +305,10 @@ public interface ConfigurationBuilder { * @param <T> the target type. * @return this builder, for chaining, never null. */ - <T> ConfigurationBuilder removePropertyConverters(TypeLiteral<T> typeToConvert, - @SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters); + default <T> ConfigurationBuilder removePropertyConverters(TypeLiteral<T> typeToConvert, + @SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters){ + return removePropertyConverters(typeToConvert, Arrays.asList(propertyConverters)); + } /** * Removes the given PropertyConverter instances for the given type, @@ -330,7 +357,9 @@ public interface ConfigurationBuilder { * * @param policy the {@link PropertyValueCombinationPolicy} used, not {@code null}. * @return this builder, for chaining, never null. + * @deprecated Will be removed. */ + @Deprecated ConfigurationBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy); /** http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java index 448a9d1..c85d73c 100644 --- a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java +++ b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java @@ -21,6 +21,7 @@ package org.apache.tamaya.spi; import org.apache.tamaya.TypeLiteral; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -31,6 +32,13 @@ import java.util.Map; */ public interface ConfigurationContext { + + /** + * Access the underlying {@link ServiceContext}. + * @return the service context, never null. + */ + ServiceContext getServiceContext(); + /** * This method can be used for programmatically adding {@link PropertySource}s. * It is not needed for normal 'usage' by end users, but only for Extension Developers! @@ -46,7 +54,7 @@ public interface ConfigurationContext { * This method returns the current list of registered {@link PropertySource}s ordered via their ordinal. * {@link PropertySource}s with a lower ordinal come last. The {@link PropertySource} with the * highest ordinal comes first. - * If two {@link PropertySource}s have the same ordinal number they will get sorted + * If two {@link PropertySource}s have the same ordinal number they will current sorted * using their class name just to ensure the user at least gets the same ordering * after a JVM restart, hereby names before are added last. * {@link PropertySource}s are loaded when this method is called the first time, which basically is @@ -107,7 +115,7 @@ public interface ConfigurationContext { * <p> * {@link PropertyConverter}s with a higher {@link javax.annotation.Priority} come first. * The {@link PropertyConverter} with the lowest {@link javax.annotation.Priority} comes last. - * If two {@link PropertyConverter}s have the same ordinal number they will get sorted + * If two {@link PropertyConverter}s have the same ordinal number they will current sorted * using their class name just to ensure the user at least gets the same ordering * after a JVM restart. * </p> @@ -171,4 +179,65 @@ public interface ConfigurationContext { @Deprecated ConfigurationContextBuilder toBuilder(); + /** + * An empty configuration context. The implementation can be shared and is thread safe. + */ + ConfigurationContext EMPTY = new ConfigurationContext() { + @Override + public ServiceContext getServiceContext() { + return ServiceContextManager.getServiceContext(getClass().getClassLoader()); + } + + @Override + public void addPropertySources(PropertySource... propertySourcesToAdd) { + // ignore + } + + @Override + public List<PropertySource> getPropertySources() { + return Collections.emptyList(); + } + + @Override + public PropertySource getPropertySource(String name) { + return null; + } + + @Override + public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) { + // ignore + } + + @Override + public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() { + return Collections.emptyMap(); + } + + @Override + public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> type) { + return Collections.emptyList(); + } + + @Override + public List<PropertyFilter> getPropertyFilters() { + return Collections.emptyList(); + } + + @Override + public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy() { + return PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR; + } + + @Override + public ConfigurationContextBuilder toBuilder() { + throw new UnsupportedOperationException("Cannot build from ConfigurationContext.EMPTY."); + } + + @Override + public String toString(){ + return "ConfigurationContext.EMPTY"; + } + }; + + } http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java index 17c1bf4..e3b73cb 100644 --- a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java +++ b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java @@ -43,6 +43,21 @@ import java.util.Map; public interface ConfigurationContextBuilder { /** + * Set the classloader to be used for loading of configuration resources, equals to + * {@code setServiceContext(ServiceContextManager.getServiceContext(classLoader))}. + * @param classLoader the classloader, not null. + * @return the builder for chaining. + */ + ConfigurationContextBuilder setClassLoader(ClassLoader classLoader); + + /** + * Sets the ServiceContext to be used. + * @param serviceContext the serviceContext, nuo null. + * @return this instance for chaining. + */ + ConfigurationContextBuilder setServiceContext(ServiceContext serviceContext); + + /** * Init this builder instance with the given {@link ConfigurationContext} instance. This * method will use any existing property sources, filters, converters and the combination * policy of the given {@link ConfigurationContext} and initialize the current builder @@ -322,6 +337,12 @@ public interface ConfigurationContextBuilder { ConfigurationContextBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy); /** + * Access the serviceContext used by the builder. + * @return the serviceContext, never null. + */ + ServiceContext getServiceContext(); + + /** * Builds a new {@link ConfigurationContext} based on the data in this builder. The ordering of property * sources and property filters is not changed, regardless of their ordinals. For ensure a certain * ordering/significance call {@link #sortPropertyFilter(Comparator)} and/or {@link #sortPropertySources(Comparator)} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java index fb93ab4..9c35e4c 100644 --- a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java +++ b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java @@ -30,10 +30,20 @@ public interface ConfigurationProviderSpi { /** * Access the current {@link org.apache.tamaya.Configuration}. - * + * @param classLoader the classloader to be used. + * @return the current {@link org.apache.tamaya.Configuration} instance, never null. + */ + Configuration getConfiguration(ClassLoader classLoader); + + /** + * Access the current {@link org.apache.tamaya.Configuration}. * @return the current {@link org.apache.tamaya.Configuration} instance, never null. + * @deprecated Use {@link #getConfiguration(ClassLoader)} instead of. */ - Configuration getConfiguration(); + @Deprecated + default Configuration getConfiguration(){ + return getConfiguration(Thread.currentThread().getContextClassLoader()); + } /** * Create a {@link Configuration} instance using the given context. The configuration @@ -67,19 +77,36 @@ public interface ConfigurationProviderSpi { * corresponding update events for the current {@link org.apache.tamaya.Configuration}. * * @param config the new Configuration to be applied. + * @param classloader the classloader to be used. + * @throws java.lang.UnsupportedOperationException if the current provider is read-only. + */ + void setConfiguration(Configuration config, ClassLoader classloader); + + /** + * This method allows to replace the current {@link org.apache.tamaya.Configuration} with a new + * instance. This can be used to update the configuration with a new one, e.g. because some of the + * data has changed and must be updated. It is the responsibility of the ConfigurationProvider to trigger + * corresponding update events for the current {@link org.apache.tamaya.Configuration}. + * + * @param config the new Configuration to be applied. * @throws java.lang.UnsupportedOperationException if the current provider is read-only. + * @deprecated Use {@link #setConfiguration(Configuration, ClassLoader)} instead of. */ - void setConfiguration(Configuration config); + @Deprecated + default void setConfiguration(Configuration config){ + setConfiguration(config, Thread.currentThread().getContextClassLoader()); + } /** * Method that allows to determine if a new {@link org.apache.tamaya.Configuration} can be applied * programmatically. * - * @return true, if {@link #setConfiguration(org.apache.tamaya.Configuration)} is supported + * @param classloader the target classloader + * @return true, if {@link #setConfiguration(org.apache.tamaya.Configuration, ClassLoader)} is supported * by the current implementation. - * @see #setConfiguration(org.apache.tamaya.Configuration) + * @see #setConfiguration(org.apache.tamaya.Configuration, ClassLoader classloader) */ - default boolean isConfigurationSettable(){ + default boolean isConfigurationSettable(ClassLoader classloader){ return true; } @@ -91,7 +118,9 @@ public interface ConfigurationProviderSpi { */ @Deprecated default ConfigurationContext getConfigurationContext(){ - return getConfiguration().getContext(); + return getConfiguration( + Thread.currentThread().getContextClassLoader() + ).getContext(); } /** @@ -103,11 +132,11 @@ public interface ConfigurationProviderSpi { * * @param context the new ConfigurationContext to be applied. * @throws java.lang.UnsupportedOperationException if the current provider is read-only. - * @deprecated use {@link #setConfiguration(Configuration)} + * @deprecated use {@link #setConfiguration(Configuration, ClassLoader)} */ @Deprecated default void setConfigurationContext(ConfigurationContext context){ - setConfiguration(createConfiguration(context)); + setConfiguration(createConfiguration(context), Thread.currentThread().getContextClassLoader()); } /** @@ -117,11 +146,12 @@ public interface ConfigurationProviderSpi { * @return true, if {@link #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)} is supported * by the current implementation. * @see #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext) - * @deprecated use {@link #isConfigurationSettable()} + * @deprecated use {@link #isConfigurationSettable(ClassLoader)} */ @Deprecated default boolean isConfigurationContextSettable(){ - return isConfigurationSettable(); + return isConfigurationSettable(Thread.currentThread() + .getContextClassLoader()); } http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/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 5fc3273..1c5f626 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 @@ -22,11 +22,8 @@ import org.apache.tamaya.Configuration; import org.apache.tamaya.TypeLiteral; import java.lang.reflect.AnnotatedElement; -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; +import java.util.*; +import java.util.function.Consumer; /** * A conversion context containing all the required values for implementing conversion. Use the included #Builder @@ -37,10 +34,46 @@ public class ConversionContext { private final Configuration configuration; private final String key; + private final List<PropertyValue> values; private final TypeLiteral<?> targetType; private final AnnotatedElement annotatedElement; private final Set<String> supportedFormats = new LinkedHashSet<>(); - private final ConfigurationContext configurationContext; + + private static ThreadLocal<ConversionContext> CONTEXT = new ThreadLocal<>(); + + /** + * Access the current conversion context. + * @return the current conversion context, or null. + */ + public static ConversionContext current(){ + return CONTEXT.get(); + } + + /** + * If the current conversoin context is available, this performs the given action. + * @param action the consumer to be executed, not null. + */ + public static void doOptional(Consumer<ConversionContext> action){ + ConversionContext ctx = current(); + if(ctx!=null){ + action.accept(ctx); + } + } + + /** + * Sets the current conversion context. + * @param context the conversion context, not null. + */ + public static void set(ConversionContext context){ + CONTEXT.set(context); + } + + /** + * Removes the current conversion context. + */ + public static void reset(){ + CONTEXT.remove(); + } /** * Private constructor used from builder. @@ -52,7 +85,9 @@ public class ConversionContext { this.targetType = builder.targetType; this.supportedFormats.addAll(builder.supportedFormats); this.configuration = builder.configuration; - this.configurationContext = builder.configurationContext; + List<PropertyValue> tempValues = new ArrayList<>(); + tempValues.addAll(builder.values); + this.values = Collections.unmodifiableList(tempValues); } /** @@ -66,6 +101,15 @@ public class ConversionContext { } /** + * Get the correspnoding underlying property values matching the given key, in order of significance + * (most significant last). + * @return the underlying values evaluated, never null. + */ + public List<PropertyValue> getValues(){ + return this.values; + } + + /** * Get the target type required. * @return the target type required. */ @@ -96,7 +140,7 @@ public class ConversionContext { * @param converterType the converters, which implements the formats provided. * @param formatDescriptors the format descriptions in a human readable form, e.g. as regular expressions. */ - public void addSupportedFormats(@SuppressWarnings("rawtypes") Class<? extends PropertyConverter> converterType, String... formatDescriptors){ + public void addSupportedFormats(@SuppressWarnings("rawtypes") Class<?> converterType, String... formatDescriptors){ synchronized (supportedFormats){ for(String format: formatDescriptors) { supportedFormats.add(format + " (" + converterType.getSimpleName() + ")"); @@ -126,8 +170,14 @@ public class ConversionContext { '}'; } + /** + * Get the current configuration context. + * @deprecated Use {@link #getConfiguration()} and {@link Configuration#getContext()}. + * @return the current configuration context. + */ + @Deprecated public ConfigurationContext getConfigurationContext() { - return configurationContext; + return getConfiguration().getContext(); } /** @@ -136,15 +186,17 @@ public class ConversionContext { public static final class Builder{ /** The backing configuration. */ private Configuration configuration; - /** The configuration context. */ - private ConfigurationContext configurationContext; /** The accessed key, or null. */ private String key; + /** The corresponding property values, as delivered from the corresponding property sources, + * in order of significance (highest last). + */ + private final List<PropertyValue> values = new ArrayList<>(); /** The target type. */ private TypeLiteral<?> targetType; - /** The injection target (only set with injection used). */ + /** The injection target (only setCurrent with injection used). */ private AnnotatedElement annotatedElement; - /** The ordered set of formats tried. */ + /** The ordered setCurrent of formats tried. */ private final Set<String> supportedFormats = new LinkedHashSet<>(); /** @@ -152,7 +204,7 @@ public class ConversionContext { * @param targetType the target type */ public Builder(TypeLiteral<?> targetType) { - this(null, null, null, targetType); + this(null, null, targetType); } /** @@ -161,20 +213,18 @@ public class ConversionContext { * @param targetType the target type */ public Builder(String key, TypeLiteral<?> targetType) { - this(null, null, key, targetType); + this(null, key, targetType); } /** * Creates a new Builder instance. * @param configuration the configuration, not {@code null}. - * @param configurationContext configuration context, not {@code null}. * @param key the requested key, may be {@code null}. * @param targetType the target type */ - public Builder(Configuration configuration, ConfigurationContext configurationContext, String key, TypeLiteral<?> targetType){ + public Builder(Configuration configuration, String key, TypeLiteral<?> targetType){ this.key = key; this.configuration = configuration; - this.configurationContext = configurationContext; this.targetType = Objects.requireNonNull(targetType); } @@ -189,22 +239,22 @@ public class ConversionContext { } /** - * Sets the configuration. - * @param configuration the configuration, not {@code null} + * Sets the underlying values evaluated. + * @param values the values, not {@code null}. * @return the builder instance, for chaining */ - public Builder setConfiguration(Configuration configuration){ - this.configuration = Objects.requireNonNull(configuration); + public Builder setValues(List<PropertyValue> values){ + this.values.addAll(values); return this; } /** * Sets the configuration. - * @param configurationContext the configuration, not {@code null} + * @param configuration the configuration, not {@code null} * @return the builder instance, for chaining */ - public Builder setConfigurationContext(ConfigurationContext configurationContext){ - this.configurationContext = Objects.requireNonNull(configurationContext); + public Builder setConfiguration(Configuration configuration){ + this.configuration = Objects.requireNonNull(configuration); return this; } @@ -236,7 +286,7 @@ public class ConversionContext { * @param formatDescriptors the formats supported in a human readable form, e.g. as regular expressions. * @return the builder instance, for chaining */ - public Builder addSupportedFormats(@SuppressWarnings("rawtypes") Class<? extends PropertyConverter> converterType, String... formatDescriptors){ + public Builder addSupportedFormats(@SuppressWarnings("rawtypes") Class<?> converterType, String... formatDescriptors){ for(String format: formatDescriptors) { supportedFormats.add(format + " (" + converterType.getSimpleName() + ")"); } @@ -255,7 +305,6 @@ public class ConversionContext { public String toString() { return "Builder{" + "configuration=" + configuration + - "context=" + configurationContext + ", key='" + key + '\'' + ", targetType=" + targetType + ", annotatedElement=" + annotatedElement + http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java b/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java index 2851697..2d3f155 100644 --- a/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java +++ b/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java @@ -20,10 +20,8 @@ package org.apache.tamaya.spi; import org.apache.tamaya.Configuration; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; +import java.util.function.Consumer; /** * A filter context containing all the required values for implementing filtering. @@ -32,7 +30,7 @@ import java.util.Objects; */ public class FilterContext { /** The key. */ - private final PropertyValue value; + private final List<PropertyValue> values; /** The current context. */ private final ConfigurationContext context; @Experimental @@ -40,6 +38,42 @@ public class FilterContext { @Experimental private boolean singlePropertyScoped; + private static ThreadLocal<FilterContext> CONTEXT = new ThreadLocal<>(); + + /** + * Access the current filter context. + * @return the current filter context, or null. + */ + public static FilterContext get(){ + return CONTEXT.get(); + } + + /** + * If the current conversoin context is available, this performs the given action. + * @param action the consumer to be executed, not null. + */ + public static void doOptional(Consumer<FilterContext> action){ + FilterContext ctx = get(); + if(ctx!=null){ + action.accept(ctx); + } + } + + /** + * Sets the current filter context. + * @param context the FilterContext, not null. + */ + public static void set(FilterContext context){ + CONTEXT.set(context); + } + + /** + * Removes the current filter context. + */ + public static void reset(){ + CONTEXT.remove(); + } + /** * Creates a new FilterContext, for filtering of a multi value access @@ -56,7 +90,7 @@ public class FilterContext { Objects.requireNonNull(context, "Context must be not null."); this.singlePropertyScoped = false; - this.value = Objects.requireNonNull(value); + this.values = Collections.singletonList(Objects.requireNonNull(value)); this.context = Objects.requireNonNull(context); this.configEntries.putAll(configEntries); this.configEntries = Collections.unmodifiableMap(this.configEntries); @@ -74,7 +108,23 @@ public class FilterContext { this.singlePropertyScoped = true; this.context = Objects.requireNonNull(context); - this.value = Objects.requireNonNull(value); + this.values = Collections.singletonList(Objects.requireNonNull(value)); + this.configEntries = Collections.unmodifiableMap(this.configEntries); + } + + /** + * Creates a new FilterContext, for filtering of a single value access + * using {@link Configuration#getProperties()}. + * @param values the value under evaluation, not {@code null}. + * @param context the current context, not {@code null}. + */ + public FilterContext(List<PropertyValue> values, ConfigurationContext context) { + Objects.requireNonNull(values, "Value must not be null."); + Objects.requireNonNull(context, "Context must be not null."); + + this.singlePropertyScoped = true; + this.context = Objects.requireNonNull(context); + this.values = Collections.unmodifiableList(new ArrayList<>(values)); this.configEntries = Collections.unmodifiableMap(this.configEntries); } @@ -82,7 +132,7 @@ public class FilterContext { * Get the current context. * @return the current context, not {@code null}. */ - public ConfigurationContext getContext(){ + public ConfigurationContext current(){ return context; } @@ -94,7 +144,18 @@ public class FilterContext { * key/value configuration is present. */ public PropertyValue getProperty() { - return value; + return values.get(0); + } + + /** + * Get the property value under evaluation. This information is very useful to evaluate additional metadata needed to determine/ + * control further aspects of the conversion. + * + * @return the key. This may be null in case where a default value has to be converted and no unique underlying + * key/value configuration is present. + */ + public List<PropertyValue> getAllValues() { + return values; } /** @@ -112,7 +173,7 @@ public class FilterContext { * <ul> * <li>the original value <b>before</b> any filters were applied on it.</li> * <li>all values starting with an {@code _<key>.}, for example {@code a.value} - * may have a map set with {@code a.value} (oringinal value), {@code _a.value.origin, + * may have a map setCurrent with {@code a.value} (oringinal value), {@code _a.value.origin, * _a.value.type, etc}. The exact contents is determine by the {@link PropertySource}s * active.</li> * </ul> @@ -123,7 +184,7 @@ public class FilterContext { * passed as input to the filter process will not be affected by any such removal (but the final properties * returned are affected, of course). * - * Finally, when a single property is accessed, e.g. by calling {@code Configuration.get(String)}. + * Finally, when a single property is accessed, e.g. by calling {@code Configuration.current(String)}. * * @return the configuration instance, or null. */ @@ -134,7 +195,7 @@ public class FilterContext { @Override public String toString() { - return "FilterContext{value='" + value + "', configEntries=" + configEntries.keySet() + '}'; + return "FilterContext{value='" + values + "', configEntries=" + configEntries.keySet() + '}'; } } http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/code/api/src/main/java/org/apache/tamaya/spi/PropertyConverter.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertyConverter.java b/code/api/src/main/java/org/apache/tamaya/spi/PropertyConverter.java index ab96b6b..e89e3b6 100644 --- a/code/api/src/main/java/org/apache/tamaya/spi/PropertyConverter.java +++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertyConverter.java @@ -18,6 +18,8 @@ */ package org.apache.tamaya.spi; +import java.util.List; + /** * Interface for an property that converts a configured String into something else. * This is used for implementing type conversion from a property (String) to a certain target @@ -30,15 +32,15 @@ public interface PropertyConverter<T>{ /** * Convert the given configuration keys from its String representation into the required target type. - * The context instance passed also allows to add a list of supported formats, which is very handy in case a + * Additional context can be obtained from {@link ConversionContext}, this also allows to add a list + * of supported formats, which is very handy in case a * value could not be converted. This list of supported formats can then shown to the user to give some hints * how a value could be configured. - * + * * @param value configuration key that needs to be converted - * @param context the {@link ConversionContext}, containing the String value and the requested configuration key. - * @return converted keys - * @see ConversionContext#addSupportedFormats(Class, String...) + * @return the converted value + * @see ConversionContext */ - T convert(String value, ConversionContext context); + T convert(String value); } http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java b/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java index 3054496..9be6ce8 100644 --- a/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java +++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java @@ -26,7 +26,7 @@ package org.apache.tamaya.spi; * <p>Filters </p> */ @FunctionalInterface -public interface PropertyFilter { +public interface PropertyFilter{ /** * <p>Maps the current {@code valueToBeFiltered} value to a new value. The resulting value will be used as the result @@ -41,11 +41,10 @@ public interface PropertyFilter { * <li>thread-safe</li> * </ul> * @param value the value to be filtered, which also can be {@code null} if removed by another filter. - * @param context the filter context, not {@code null}. * @return the filtered value, or {@code null} if the value should be removed alltogether. * @see PropertyValue - * @see PropertyValueBuilder + * @see FilterContext */ - PropertyValue filterProperty(PropertyValue value, FilterContext context); + PropertyValue filterProperty(PropertyValue value); } http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java b/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java index 864cd95..23d42a5 100644 --- a/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java +++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java @@ -35,7 +35,7 @@ import java.util.Map; * <li>Thread safe.</li> * </ul> * - * <p>A PropertySourceProvider will get picked up via the + * <p>A PropertySourceProvider will current picked up via the * {@link java.util.ServiceLoader} mechanism and can be registered via * {@code META-INF/services/org.apache.tamaya.spi.PropertySource} * </p> @@ -45,7 +45,7 @@ import java.util.Map; * interface. * </p> */ -public interface PropertySource { +public interface PropertySource{ /** * property name to override default tamaya ordinals @@ -142,7 +142,7 @@ public interface PropertySource { * Access a property. * * @param key the property's key, not {@code null}. - * @return the property value map, where {@code map.get(key) == value}, including also any metadata. In case a + * @return the property value map, where {@code map.current(key) == value}, including also any metadata. In case a * value is null, simply return {@code null}. */ PropertyValue get(String key); @@ -166,7 +166,9 @@ public interface PropertySource { * * @return {@code true} if this PropertySource can be scanned for its list of properties, * {@code false} if it cannot/should not be scanned. + * @deprecated will be removed. */ + @Deprecated default boolean isScannable(){ return true; } http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/e45effd2/code/api/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java ---------------------------------------------------------------------- diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java b/code/api/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java index 3f7beea..1e46daa 100644 --- a/code/api/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java +++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java @@ -30,8 +30,8 @@ import java.util.Collections; * to implement it via the PropertySourceProvider but should directly * expose a {@link PropertySource}.</p> * - * <p>A PropertySourceProvider will get picked up via the - * {@link java.util.ServiceLoader} mechanism and must get registered via + * <p>A PropertySourceProvider will current picked up via the + * {@link java.util.ServiceLoader} mechanism and must current registered via * META-INF/services/org.apache.tamaya.spi.PropertySourceProvider</p> */ @FunctionalInterface
