This is an automated email from the ASF dual-hosted git repository. anatole pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-tamaya.git
commit b3089cde2b635ce2ec0e4cc73f1578c47efac573 Author: Anatole Tresch <atsti...@gmail.com> AuthorDate: Tue May 14 14:41:37 2019 +0200 TAMAYA-398 TAMAYA-399 TAMAYA-400 TAMAYA-401 TAMAYA-402 TAMAYA-403 TAMAYA-404 TAMAYA-405 TAMAYA-406 TAMAYA-407 Implemented MP 1.3 spec. --- .../main/java/org/apache/tamaya/Configuration.java | 2 +- .../apache/tamaya/spi/ConfigurationBuilder.java | 10 ++++ .../org/apache/tamaya/spi/ConversionContext.java | 14 ++++++ .../java/org/apache/tamaya/spi/PropertyValue.java | 16 ------ .../java/org/apache/tamaya/spi/ServiceContext.java | 44 ++++++++++++++--- .../apache/tamaya/spi/ServiceContextManager.java | 9 +++- .../tamaya/spi/ConfigurationBuilderTest.java | 5 ++ .../org/apache/tamaya/spi/PropertyValueTest.java | 17 ------- .../tamaya/spi/ServiceContextManagerTest.java | 5 +- .../tamaya/spi/TestLowerOrdinalServiceContext.java | 2 +- .../org/apache/tamaya/spi/TestServiceContext.java | 14 +++++- code/core/pom.xml | 2 +- .../core/internal/CoreConfigurationProvider.java | 2 +- .../core/internal/OSGIServiceComparator.java | 9 ++-- .../tamaya/core/internal/OSGIServiceContext.java | 4 +- .../converters/LocalDateTimeConverter.java | 2 + ...teTimeConverter.java => MonthDayConverter.java} | 16 +++--- ...alDateTimeConverter.java => YearConverter.java} | 16 +++--- ...eTimeConverter.java => YearMonthConverter.java} | 17 ++++--- .../org.apache.tamaya.spi.PropertyConverter | 3 ++ .../core/internal/OSGIServiceContextTest.java | 7 +-- .../tamaya/spisupport/DefaultConfiguration.java | 29 +++++++++-- .../spisupport/DefaultConfigurationBuilder.java | 21 ++++++-- .../spisupport/DefaultConfigurationContext.java | 57 ++++++++++++++++++---- .../spisupport/DefaultConfigurationSnapshot.java | 8 ++- .../tamaya/spisupport/DefaultServiceContext.java | 1 - .../spisupport/PriorityServiceComparator.java | 10 ++-- .../spisupport/PropertyConverterManager.java | 40 ++++++++++----- .../spisupport/PropertyFilterComparator.java | 17 +++++-- .../spisupport/PropertySourceComparator.java | 3 +- .../propertysource/EnvironmentPropertySource.java | 15 ++++-- .../JavaConfigurationPropertySource.java | 17 ++----- .../PropertiesResourcePropertySource.java | 10 +++- .../spisupport/services/DefaultServiceContext.java | 25 +++++++--- 34 files changed, 325 insertions(+), 144 deletions(-) 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 7c47211..083f494 100644 --- a/code/api/src/main/java/org/apache/tamaya/Configuration.java +++ b/code/api/src/main/java/org/apache/tamaya/Configuration.java @@ -461,7 +461,7 @@ public interface Configuration { * @return the builder, never null. */ static ConfigurationBuilder createConfigurationBuilder(){ - return ServiceContextManager.getServiceContext(Configuration.class.getClassLoader()) + return ServiceContextManager.getServiceContext(ServiceContextManager.getDefaultClassLoader()) .getService(ConfigurationProviderSpi.class).getConfigurationBuilder(); } 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 d8f1393..ccc6244 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 @@ -378,6 +378,16 @@ public interface ConfigurationBuilder { ConfigurationBuilder sortPropertyFilter(Comparator<PropertyFilter> comparator); /** + * Sorts the current registered property converters using the given comparator. + * + * <p>NOTE: property converters at the beginning have minimal significance. + * + * @param comparator the comparator to be used, not {@code null}. + * @return this instance for chaining. + */ + ConfigurationBuilder sortPropertyConverter(Comparator<PropertyConverter> comparator); + + /** * Builds a new {@link Configuration} 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 use {@link #sortPropertyFilter(Comparator)} and/or {@link #sortPropertySources(Comparator)} 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 a52b884..c7156fb 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,6 +141,20 @@ public class ConversionContext { } } + /** + * Creates a builder based on this instance. + */ + public Builder toBuilder(){ + Builder builder = new Builder(key, targetType) + .setConfiguration(this.configuration) + .setValues(this.values); + if(annotatedElement!=null) { + builder.setAnnotatedElement(annotatedElement); + } + builder.supportedFormats.addAll(this.supportedFormats); + return builder; + } + @Override public String toString() { return "ConversionContext{" + diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java index 712f1d6..3e9da06 100644 --- a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java +++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java @@ -63,22 +63,6 @@ public class PropertyValue implements Serializable, Iterable<PropertyValue>{ } -// /** -// * Creates a new builder instance. -// * @param key the key, not {@code null}. -// * @param source the source, typically the name of the {@link PropertySource} -// * providing the createValue, not {@code null}. -// * @return a new builder instance. -// * @deprecated Will be removed, use {@link PropertyValue} directly. -// */ -// @Deprecated -// public static PropertyValueBuilder builder(String key, String source){ -// Objects.requireNonNull(key, "Key must be given."); -// Objects.requireNonNull(source, "Source must be given"); -// -// return new PropertyValueBuilder(key, null).setSource(source); -// } - /** * Creates a new (invisible) root, which is a node with an empty name. * @return a new empty root, never null. diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java b/code/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java index 3d97e93..ae82c07 100644 --- a/code/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java +++ b/code/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java @@ -23,6 +23,8 @@ import java.io.IOException; import java.net.URL; import java.util.*; import java.util.function.Supplier; +import java.util.logging.Level; +import java.util.logging.Logger; /** @@ -32,6 +34,24 @@ import java.util.function.Supplier; public interface ServiceContext extends ClassloaderAware{ /** + * True if the {@link Priority} annotation class is available on the classpath. + */ + boolean PRIORITY_ANNOTATION_AVAILABLE = checkPriorityAnnotation(ServiceContextManager.getDefaultClassLoader()); + + /** + * Checks if the {@link Priority} annotation class is on the classpath. + * @param classLoader the target classloader, not null. + * @return true, if the annotation is loaded. + */ + static boolean checkPriorityAnnotation(ClassLoader classLoader) { + try{ + Class.forName("javax.annotation.Priority", true, classLoader); + return true; + }catch(Exception e){ + return false; + } + } + /** * Get the ordinal of the ServiceContext. * @return ordinal of the ServiceContext. The one with the highest ordinal will be taken. */ @@ -46,10 +66,12 @@ public interface ServiceContext extends ClassloaderAware{ * @return a priority, by default 1. */ static int getPriority(Object o){ - int prio = 1; //X TODO discuss default priority - Priority priority = o.getClass().getAnnotation(Priority.class); - if (priority != null) { - prio = priority.value(); + int prio = 1; + if(PRIORITY_ANNOTATION_AVAILABLE) { + Priority priority = o.getClass().getAnnotation(Priority.class); + if (priority != null) { + prio = priority.value(); + } } return prio; } @@ -149,8 +171,18 @@ public interface ServiceContext extends ClassloaderAware{ * @return the resources found * @throws IOException if load fails. */ - default Enumeration<URL> getResources(String resource) throws IOException{ - return getClassLoader().getResources(resource); + default Collection<URL> getResources(String resource){ + List<URL> urls = new ArrayList<>(); + try { + Enumeration<URL> found = getClassLoader().getResources(resource); + while (found.hasMoreElements()) { + urls.add(found.nextElement()); + } + }catch(Exception e){ + Logger.getLogger(ServiceContext.class.getName()) + .log(Level.FINEST, e, () -> "Failed to lookup resources: " + resource); + } + return urls; } /** diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java b/code/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java index 2acbfca..7d81fe1 100644 --- a/code/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java +++ b/code/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java @@ -140,10 +140,15 @@ public final class ServiceContextManager { } /** - * Evaluate the default classloader: This class's classloader. + * Evaluate the default classloader: This return the current thread context classloader, or this + * class's classloader as fallback. * @return the classloder, not null. */ public static ClassLoader getDefaultClassLoader() { - return ServiceContextManager.class.getClassLoader(); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if(cl==null) { + cl = ServiceContextManager.class.getClassLoader(); + } + return cl; } } diff --git a/code/api/src/test/java/org/apache/tamaya/spi/ConfigurationBuilderTest.java b/code/api/src/test/java/org/apache/tamaya/spi/ConfigurationBuilderTest.java index cdd3414..3fde90e 100644 --- a/code/api/src/test/java/org/apache/tamaya/spi/ConfigurationBuilderTest.java +++ b/code/api/src/test/java/org/apache/tamaya/spi/ConfigurationBuilderTest.java @@ -231,6 +231,11 @@ public class ConfigurationBuilderTest { } @Override + public ConfigurationBuilder sortPropertyConverter(Comparator<PropertyConverter> comparator) { + return null; + } + + @Override public Configuration build() { return null; } diff --git a/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java b/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java index b3f03ff..694ef50 100644 --- a/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java +++ b/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java @@ -30,23 +30,6 @@ import static org.assertj.core.api.Assertions.assertThatCode; @SuppressWarnings("unchecked") public class PropertyValueTest { -// @Test -// public void builder() throws Exception { -// PropertyValueBuilder b = PropertyValue.builder("a", "b"); -// assertThat(b).isNotNull(); -// assertThat("a").isEqualTo(b.key); -// assertThat("b").isEqualTo(b.source); -// } -// -// -// @Test -// public void builder() throws Exception { -// PropertyValueBuilder b = PropertyValue.builder("a", "b"); -// assertThat(b).isNotNull(); -// assertThat("a").isEqualTo(b.key); -// assertThat("b").isEqualTo(b.source); -// } - @Test public void from(){ diff --git a/code/api/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java b/code/api/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java index a72ea2b..761a429 100644 --- a/code/api/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java +++ b/code/api/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java @@ -22,6 +22,7 @@ import org.junit.Test; import java.io.IOException; import java.net.URL; +import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.List; @@ -88,8 +89,8 @@ public class ServiceContextManagerTest { } @Override - public Enumeration<URL> getResources(String resource) throws IOException { - return null; + public Collection<URL> getResources(String resource) { + return Collections.emptySet(); } @Override diff --git a/code/api/src/test/java/org/apache/tamaya/spi/TestLowerOrdinalServiceContext.java b/code/api/src/test/java/org/apache/tamaya/spi/TestLowerOrdinalServiceContext.java index 6c5beb4..39bc87a 100644 --- a/code/api/src/test/java/org/apache/tamaya/spi/TestLowerOrdinalServiceContext.java +++ b/code/api/src/test/java/org/apache/tamaya/spi/TestLowerOrdinalServiceContext.java @@ -77,7 +77,7 @@ public final class TestLowerOrdinalServiceContext implements ServiceContext { } @Override - public Enumeration<URL> getResources(String resource) throws IOException { + public Collection<URL> getResources(String resource) { throw ex; } diff --git a/code/api/src/test/java/org/apache/tamaya/spi/TestServiceContext.java b/code/api/src/test/java/org/apache/tamaya/spi/TestServiceContext.java index b00a7a0..765c032 100644 --- a/code/api/src/test/java/org/apache/tamaya/spi/TestServiceContext.java +++ b/code/api/src/test/java/org/apache/tamaya/spi/TestServiceContext.java @@ -113,8 +113,18 @@ public final class TestServiceContext implements ServiceContext { } @Override - public Enumeration<URL> getResources(String resource) throws IOException { - return classLoader.getResources(resource); + public Collection<URL> getResources(String resource) { + List<URL> urls = new ArrayList<>(); + try { + Enumeration<URL> found = getClassLoader().getResources(resource); + while (found.hasMoreElements()) { + urls.add(found.nextElement()); + } + }catch(Exception e){ + Logger.getLogger(ServiceContext.class.getName()) + .log(Level.FINEST, e, () -> "Failed to lookup resources: " + resource); + } + return urls; } @Override diff --git a/code/core/pom.xml b/code/core/pom.xml index 51397cf..8220e62 100644 --- a/code/core/pom.xml +++ b/code/core/pom.xml @@ -98,7 +98,7 @@ under the License. <!-- ! Add -Djava.security.debug=all for debugging if needed !--> - <argLine>-Djava.security.policy=${project.basedir}/src/test/resources/java-security.policy ${argLine}</argLine> + <argLine>-Djava.security.policy=${project.basedir}/src/test/resources/java-security.policy</argLine> </configuration> </plugin> </plugins> diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/CoreConfigurationProvider.java b/code/core/src/main/java/org/apache/tamaya/core/internal/CoreConfigurationProvider.java index bbfecf6..989821b 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/CoreConfigurationProvider.java +++ b/code/core/src/main/java/org/apache/tamaya/core/internal/CoreConfigurationProvider.java @@ -82,7 +82,7 @@ public class CoreConfigurationProvider implements ConfigurationProviderSpi { Objects.requireNonNull(config.getContext()); Configuration old = this.configurations.put(classLoader, Objects.requireNonNull(config)); if(old != null){ - LOG.warning(String.format("Replaced config %S with %S for classloader %S", old, config, classLoader)); + LOG.warning(String.format("Replaced config %s with %s for classloader %s", old, config, classLoader)); } } diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceComparator.java b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceComparator.java index f039d27..6cd16e9 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceComparator.java +++ b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceComparator.java @@ -18,6 +18,7 @@ */ package org.apache.tamaya.core.internal; +import org.apache.tamaya.spi.ServiceContext; import org.osgi.framework.ServiceReference; import javax.annotation.Priority; @@ -61,9 +62,11 @@ class OSGIServiceComparator implements Comparator<ServiceReference> { */ public static int getPriority(Class<? extends Object> type) { int prio = 1; - Priority priority = type.getAnnotation(Priority.class); - if (priority != null) { - prio = priority.value(); + if(ServiceContext.PRIORITY_ANNOTATION_AVAILABLE) { + Priority priority = type.getAnnotation(Priority.class); + if (priority != null) { + prio = priority.value(); + } } return prio; } diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceContext.java b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceContext.java index 2d67dc8..9eeac72 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceContext.java +++ b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceContext.java @@ -167,7 +167,7 @@ public class OSGIServiceContext implements ServiceContext{ } @Override - public Enumeration<URL> getResources(String resource) throws IOException{ + public Collection<URL> getResources(String resource){ LOG.finest("TAMAYA Loading resources: " + resource); List<URL> result = new ArrayList<>(); URL url = osgiServiceLoader.getBundleContext().getBundle() @@ -191,7 +191,7 @@ public class OSGIServiceContext implements ServiceContext{ result.add(url); } } - return Collections.enumeration(result); + return result; } @Override diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java index 92f2d75..b7fedee 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java +++ b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java @@ -23,6 +23,7 @@ import org.apache.tamaya.spi.PropertyConverter; import org.osgi.service.component.annotations.Component; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; @@ -35,6 +36,7 @@ public class LocalDateTimeConverter implements PropertyConverter<LocalDateTime> private static final Logger LOG = Logger.getLogger(LocalDateTimeConverter.class.getName()); + @Override public LocalDateTime convert(String value, ConversionContext ctx) { ctx.addSupportedFormats(getClass(), LocalDateTime.now().toString()); diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/MonthDayConverter.java similarity index 73% copy from code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java copy to code/core/src/main/java/org/apache/tamaya/core/internal/converters/MonthDayConverter.java index 92f2d75..f6331b7 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java +++ b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/MonthDayConverter.java @@ -22,29 +22,29 @@ import org.apache.tamaya.spi.ConversionContext; import org.apache.tamaya.spi.PropertyConverter; import org.osgi.service.component.annotations.Component; -import java.time.LocalDateTime; +import java.time.MonthDay; import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; /** - * Converter, converting from String to LocalDateTime. + * Converter, converting from String to Year. */ @Component(service = PropertyConverter.class) -public class LocalDateTimeConverter implements PropertyConverter<LocalDateTime> { +public class MonthDayConverter implements PropertyConverter<MonthDay> { - private static final Logger LOG = Logger.getLogger(LocalDateTimeConverter.class.getName()); + private static final Logger LOG = Logger.getLogger(MonthDayConverter.class.getName()); @Override - public LocalDateTime convert(String value, ConversionContext ctx) { - ctx.addSupportedFormats(getClass(), LocalDateTime.now().toString()); + public MonthDay convert(String value, ConversionContext ctx) { + ctx.addSupportedFormats(getClass(), MonthDay.now().toString()); if(value==null){ return null; } try{ - return LocalDateTime.parse(value); + return MonthDay.parse(value); }catch(Exception e){ - LOG.log(Level.FINEST, e, () -> "Cannot parse LocalDateTime: " + value); + LOG.log(Level.FINEST, e, () -> "Cannot parse MonthDay: " + value); return null; } } diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/YearConverter.java similarity index 73% copy from code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java copy to code/core/src/main/java/org/apache/tamaya/core/internal/converters/YearConverter.java index 92f2d75..414d891 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java +++ b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/YearConverter.java @@ -22,29 +22,29 @@ import org.apache.tamaya.spi.ConversionContext; import org.apache.tamaya.spi.PropertyConverter; import org.osgi.service.component.annotations.Component; -import java.time.LocalDateTime; +import java.time.Year; import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; /** - * Converter, converting from String to LocalDateTime. + * Converter, converting from String to Year. */ @Component(service = PropertyConverter.class) -public class LocalDateTimeConverter implements PropertyConverter<LocalDateTime> { +public class YearConverter implements PropertyConverter<Year> { - private static final Logger LOG = Logger.getLogger(LocalDateTimeConverter.class.getName()); + private static final Logger LOG = Logger.getLogger(YearConverter.class.getName()); @Override - public LocalDateTime convert(String value, ConversionContext ctx) { - ctx.addSupportedFormats(getClass(), LocalDateTime.now().toString()); + public Year convert(String value, ConversionContext ctx) { + ctx.addSupportedFormats(getClass(), Year.now().toString()); if(value==null){ return null; } try{ - return LocalDateTime.parse(value); + return Year.parse(value); }catch(Exception e){ - LOG.log(Level.FINEST, e, () -> "Cannot parse LocalDateTime: " + value); + LOG.log(Level.FINEST, e, () -> "Cannot parse Year: " + value); return null; } } diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/YearMonthConverter.java similarity index 73% copy from code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java copy to code/core/src/main/java/org/apache/tamaya/core/internal/converters/YearMonthConverter.java index 92f2d75..a66bffe 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/converters/LocalDateTimeConverter.java +++ b/code/core/src/main/java/org/apache/tamaya/core/internal/converters/YearMonthConverter.java @@ -22,29 +22,30 @@ import org.apache.tamaya.spi.ConversionContext; import org.apache.tamaya.spi.PropertyConverter; import org.osgi.service.component.annotations.Component; -import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.YearMonth; import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; /** - * Converter, converting from String to LocalDateTime. + * Converter, converting from String to YearMonth. */ @Component(service = PropertyConverter.class) -public class LocalDateTimeConverter implements PropertyConverter<LocalDateTime> { +public class YearMonthConverter implements PropertyConverter<YearMonth> { - private static final Logger LOG = Logger.getLogger(LocalDateTimeConverter.class.getName()); + private static final Logger LOG = Logger.getLogger(YearMonthConverter.class.getName()); @Override - public LocalDateTime convert(String value, ConversionContext ctx) { - ctx.addSupportedFormats(getClass(), LocalDateTime.now().toString()); + public YearMonth convert(String value, ConversionContext ctx) { + ctx.addSupportedFormats(getClass(), YearMonth.now().toString()); if(value==null){ return null; } try{ - return LocalDateTime.parse(value); + return YearMonth.parse(value); }catch(Exception e){ - LOG.log(Level.FINEST, e, () -> "Cannot parse LocalDateTime: " + value); + LOG.log(Level.FINEST, e, () -> "Cannot parse YearMonth: " + value); return null; } } diff --git a/code/core/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter b/code/core/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter index 396aef1..1320a98 100644 --- a/code/core/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter +++ b/code/core/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter @@ -28,6 +28,7 @@ org.apache.tamaya.core.internal.converters.ShortConverter org.apache.tamaya.core.internal.converters.BigDecimalConverter org.apache.tamaya.core.internal.converters.BigIntegerConverter org.apache.tamaya.core.internal.converters.CurrencyConverter +org.apache.tamaya.core.internal.converters.MonthDayConverter org.apache.tamaya.core.internal.converters.NumberConverter org.apache.tamaya.core.internal.converters.URIConverter org.apache.tamaya.core.internal.converters.URLConverter @@ -42,3 +43,5 @@ org.apache.tamaya.core.internal.converters.OffsetTimeConverter org.apache.tamaya.core.internal.converters.InstantConverter org.apache.tamaya.core.internal.converters.OptionalConverter org.apache.tamaya.core.internal.converters.SupplierConverter +org.apache.tamaya.core.internal.converters.YearConverter +org.apache.tamaya.core.internal.converters.YearMonthConverter diff --git a/code/core/src/test/java/org/apache/tamaya/core/internal/OSGIServiceContextTest.java b/code/core/src/test/java/org/apache/tamaya/core/internal/OSGIServiceContextTest.java index e3227cc..9c69039 100644 --- a/code/core/src/test/java/org/apache/tamaya/core/internal/OSGIServiceContextTest.java +++ b/code/core/src/test/java/org/apache/tamaya/core/internal/OSGIServiceContextTest.java @@ -20,6 +20,7 @@ package org.apache.tamaya.core.internal; import java.io.IOException; import java.net.URL; +import java.util.Collection; import java.util.Enumeration; import java.util.List; @@ -98,11 +99,11 @@ public class OSGIServiceContextTest { mockBundleContext.installBundle(startedBundle); OSGIServiceContext instance = new OSGIServiceContext(loader); - Enumeration<URL> resources = instance.getResources("dummy"); + Collection<URL> resources = instance.getResources("dummy"); assertThat(resources).isNotNull(); - URL resource = (URL)resources.nextElement(); + URL resource = (URL)resources.iterator().next(); assertThat(resource.toString()).contains("mockbundle.service"); - assertThat(resources.hasMoreElements()).isFalse(); + assertThat(resources.size()).isEqualTo(1); } /** diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java index a5cf45b..a41c068 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java @@ -29,6 +29,10 @@ import org.apache.tamaya.spi.ConversionContext; import org.apache.tamaya.spi.PropertyConverter; import org.apache.tamaya.spi.PropertyValue; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; @@ -38,7 +42,7 @@ import java.util.logging.Logger; * chain of {@link org.apache.tamaya.spi.PropertySource} and {@link org.apache.tamaya.spi.PropertyFilter} * instances to evaluate the current Configuration. */ -public class DefaultConfiguration implements Configuration { +public class DefaultConfiguration implements Configuration, Serializable { /** * The logger. */ @@ -47,12 +51,12 @@ public class DefaultConfiguration implements Configuration { /** * The current {@link ConfigurationContext} of the current instance. */ - private final ConfigurationContext configurationContext; + private ConfigurationContext configurationContext; /** * EvaluationStrategy */ - private ConfigValueEvaluator configEvaluator; + private transient ConfigValueEvaluator configEvaluator; private ConfigValueEvaluator loadConfigValueEvaluator() { @@ -301,4 +305,23 @@ public class DefaultConfiguration implements Configuration { configurationContext + '}'; } + + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + configurationContext = (ConfigurationContext)ois.readObject(); + configEvaluator = loadConfigValueEvaluator(); + } + + private void writeObject(ObjectOutputStream oos) throws IOException { + if(configurationContext instanceof Serializable){ + oos.writeObject(configurationContext); + }else{ + oos.writeObject(new DefaultConfigurationContext( + this.configurationContext.getServiceContext(), + this.configurationContext.getPropertyFilters(), + this.configurationContext.getPropertySources(), + this.configurationContext.getPropertyConverters(), + this.configurationContext.getServiceContext().getService(MetadataProvider.class, + () -> new DefaultMetaDataProvider()))); + } + } } diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java index 0123148..d050638 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java @@ -61,6 +61,7 @@ public class DefaultConfigurationBuilder implements ConfigurationBuilder { * Creates a new builder instance. */ public DefaultConfigurationBuilder() { + } @@ -87,6 +88,7 @@ public class DefaultConfigurationBuilder implements ConfigurationBuilder { @Override public ConfigurationBuilder setClassLoader(ClassLoader classLoader) { setServiceContext(ServiceContextManager.getServiceContext(classLoader)); + serviceContext.reset(); return this; } @@ -149,9 +151,14 @@ public class DefaultConfigurationBuilder implements ConfigurationBuilder { public ConfigurationBuilder addPropertySources(Collection<PropertySource> sources){ checkBuilderState(); for(PropertySource source:sources) { - if (!this.propertySources.contains(source)) { - this.propertySources.add(source); + if(this.propertySources.stream() + .filter(ex -> Objects.equals(ex.getName(), source.getName())) + .findAny() + .isPresent()){ + LOG.finest(() -> "Omitting already present property source: " + source.getName()); + continue; } + this.propertySources.add(source); } return this; } @@ -308,7 +315,7 @@ public class DefaultConfigurationBuilder implements ConfigurationBuilder { if (!converters.contains(propertyConverter)) { converters.add(propertyConverter); } else { - LOG.warning("Converter ignored, already registered: " + propertyConverter); + LOG.finest("Converter ignored, already registered: " + propertyConverter); } } return this; @@ -346,6 +353,14 @@ public class DefaultConfigurationBuilder implements ConfigurationBuilder { } @Override + public ConfigurationBuilder sortPropertyConverter(Comparator<PropertyConverter> comparator) { + for(List<PropertyConverter<?>> converters:this.propertyConverters.values()) { + Collections.sort(converters, comparator); + } + return this; + } + + @Override public List<PropertyFilter> getPropertyFilters() { return this.propertyFilters; } diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java index e01adb5..7d65fa5 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java @@ -19,25 +19,26 @@ package org.apache.tamaya.spisupport; import org.apache.tamaya.TypeLiteral; -import org.apache.tamaya.spi.ConfigurationContext; -import org.apache.tamaya.spi.PropertyConverter; -import org.apache.tamaya.spi.PropertyFilter; -import org.apache.tamaya.spi.PropertySource; -import org.apache.tamaya.spi.PropertyValue; -import org.apache.tamaya.spi.ServiceContext; +import org.apache.tamaya.spi.*; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; import java.util.*; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.logging.Logger; +import java.util.stream.Collectors; /** * Default implementation of a simple {@link ConfigurationContext}. */ -public class DefaultConfigurationContext implements ConfigurationContext { +public class DefaultConfigurationContext implements ConfigurationContext, Serializable { /** The logger used. */ private final static Logger LOG = Logger.getLogger(DefaultConfigurationContext.class.getName()); - private final MetadataProvider metaDataProvider; + + private MetadataProvider metaDataProvider; /** * Subcomponent handling {@link PropertyConverter} instances. @@ -61,7 +62,7 @@ public class DefaultConfigurationContext implements ConfigurationContext { /** * Lock for internal synchronization. */ - private final ReentrantReadWriteLock propertySourceLock = new ReentrantReadWriteLock(); + private ReentrantReadWriteLock propertySourceLock = new ReentrantReadWriteLock(); @SuppressWarnings("unchecked") protected DefaultConfigurationContext(DefaultConfigurationBuilder builder) { @@ -268,4 +269,42 @@ public class DefaultConfigurationContext implements ConfigurationContext { return immutablePropertyFilters; } + /** + * Evaluates all present keys from the property sources loaded. + * @return the keys found, never null. + */ + private Set<String> getKeys() { + Set<String> keys = new HashSet<>(); + for(PropertySource ps:immutablePropertySources){ + keys.addAll(ps.getProperties().keySet()); + } + return keys; + } + + /** + * Deserialization only reads the property source snapshots from the stream. Converters, filters, + * meta data provider and the service context are reinitialized based on the current environment. + * @param ois the input stream + * @throws IOException if the stream is corrupted + * @throws ClassNotFoundException if s property source class cannot be serialized. + */ + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + this.serviceContext = ServiceContextManager.getServiceContext(); + this.propertyConverterManager = new PropertyConverterManager( + this.serviceContext, true); + this.immutablePropertySources = Collections.unmodifiableList( + (List<PropertySource>)ois.readObject()); + this.immutablePropertyFilters = Collections.unmodifiableList( + this.serviceContext.getServices(PropertyFilter.class)); + this.metaDataProvider = this.serviceContext.getService(MetadataProvider.class); + propertySourceLock = new ReentrantReadWriteLock(); + } + + private void writeObject(ObjectOutputStream oos)throws IOException{ + // omit converters, they will be reloaded from scratch. + oos.writeObject(this.immutablePropertySources.stream() + .map(ps -> DefaultPropertySourceSnapshot.of(ps, getKeys())).collect(Collectors.toList())); + // omit filters, they will be reloaded from scratch + } + } diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationSnapshot.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationSnapshot.java index ac4fe8b..15ee71c 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationSnapshot.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationSnapshot.java @@ -24,6 +24,8 @@ import org.apache.tamaya.TypeLiteral; import org.apache.tamaya.spi.ConfigurationContext; import org.apache.tamaya.spi.PropertyConverter; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.*; import java.util.stream.Collectors; @@ -40,10 +42,10 @@ public class DefaultConfigurationSnapshot implements ConfigurationSnapshot, Seri /** * The properties frozen. */ - private Configuration snapshot; + private DefaultConfiguration snapshot; private long frozenAt = System.nanoTime(); private UUID id = UUID.randomUUID(); - private transient ConfigurationContext context; + private DefaultConfigurationContext context; private Set<String> keys = new HashSet<>(); /** @@ -101,6 +103,7 @@ public class DefaultConfigurationSnapshot implements ConfigurationSnapshot, Seri * Get the evaluated keys of this frozen coinfiguration. * @return the keys, not null. */ + @Override public Set<String> getKeys() { return keys; } @@ -209,4 +212,5 @@ public class DefaultConfigurationSnapshot implements ConfigurationSnapshot, Seri public UUID getId() { return id; } + } diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java index 9b63a99..9bd1040 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java @@ -22,7 +22,6 @@ import org.apache.tamaya.ConfigException; import org.apache.tamaya.spi.ClassloaderAware; import org.apache.tamaya.spi.ServiceContext; -import javax.annotation.Priority; import java.text.MessageFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java index ef68eed..25bdbc3 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java @@ -18,6 +18,8 @@ */ package org.apache.tamaya.spisupport; +import org.apache.tamaya.spi.ServiceContext; + import javax.annotation.Priority; import java.io.Serializable; import java.util.Comparator; @@ -75,9 +77,11 @@ public class PriorityServiceComparator implements Comparator<Object>, Serializab @SuppressWarnings({ "rawtypes", "unchecked" }) public static int getPriority(Class type) { int prio = 1; - Priority priority = (Priority)type.getAnnotation(Priority.class); - if (priority != null) { - prio = priority.value(); + if(ServiceContext.PRIORITY_ANNOTATION_AVAILABLE) { + Priority priority = (Priority) type.getAnnotation(Priority.class); + if (priority != null) { + prio = priority.value(); + } } return prio; } diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java index 5782526..0654712 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java @@ -28,6 +28,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; +import java.net.URI; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.*; @@ -254,6 +255,15 @@ public class PropertyConverterManager { readLock.unlock(); } } + if(converterList.isEmpty() && targetType.getRawType().isArray() && + !targetType.getRawType().getComponentType().isPrimitive()){ + try { + readLock.lock(); + addConvertersToList(List.class.cast(this.converters.get(TypeLiteral.of(Object[].class))), converterList); + } finally { + readLock.unlock(); + } + } if (converterList.isEmpty() && !TypeLiteral.of(String.class).equals(targetType)) { // adding any converters created on the fly, e.g. for enum types. PropertyConverter<T> defaultConverter = createDefaultPropertyConverter(targetType); @@ -364,36 +374,38 @@ public class PropertyConverterManager { return new EnumConverter<>(targetType.getRawType()); } PropertyConverter<T> converter = null; - final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "createValue", "instanceOf", "getInstance", "from", "fromString", "parse"); + final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "valueOf", "createValue", "instanceOf", "getInstance", "from", "fromString", "parse"); if (factoryMethod != null) { converter = new DefaultPropertyConverter<>(factoryMethod, targetType.getRawType()); } if (converter == null) { - final Constructor<T> constr; + Constructor<T> constr; try { constr = targetType.getRawType().getDeclaredConstructor(String.class); } catch (NoSuchMethodException e) { - LOG.log(Level.FINEST, "No matching constructor for " + targetType, e); - return null; + try { + constr = targetType.getRawType().getDeclaredConstructor(CharSequence.class); + } catch (NoSuchMethodException e2) { + LOG.log(Level.FINEST, "No matching constructor found for " + targetType); + return null; + } } + Constructor<T> finalConstr = constr; converter = new PropertyConverter<T>() { @Override public T convert(String value, ConversionContext context) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { - AccessController.doPrivileged(new PrivilegedAction<Object>() { - @Override - public Object run() { - constr.setAccessible(true); - return null; - } + AccessController.doPrivileged((PrivilegedAction<Object>) () -> { + finalConstr.setAccessible(true); + return null; }); return null; } }); try { - return constr.newInstance(value); + return finalConstr.newInstance(value); } catch (Exception e) { LOG.log(Level.SEVERE, "Error creating new PropertyConverter instance " + targetType, e); } @@ -418,6 +430,12 @@ public class PropertyConverterManager { m = type.getDeclaredMethod(name, String.class); return m; } catch (NoSuchMethodException | RuntimeException e) { + // continue, try also with CharSequence + } + try { + m = type.getDeclaredMethod(name, CharSequence.class); + return m; + } catch (NoSuchMethodException | RuntimeException e) { LOG.finest("No such factory method found on type: " + type.getName() + ", methodName: " + name); } } diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java index c1d5520..3d0d501 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java @@ -19,6 +19,7 @@ package org.apache.tamaya.spisupport; import org.apache.tamaya.spi.PropertyFilter; +import org.apache.tamaya.spi.ServiceContext; import javax.annotation.Priority; import java.io.Serializable; @@ -51,11 +52,19 @@ public final class PropertyFilterComparator implements Comparator<PropertyFilter * @return the comparison result */ private int comparePropertyFilters(PropertyFilter filter1, PropertyFilter filter2) { - Priority prio1 = filter1.getClass().getAnnotation(Priority.class); - Priority prio2 = filter2.getClass().getAnnotation(Priority.class); - int ord1 = prio1 != null ? prio1.value() : 0; - int ord2 = prio2 != null ? prio2.value() : 0; + int ord1 = 0; + int ord2 = 0; + if(ServiceContext.PRIORITY_ANNOTATION_AVAILABLE) { + Priority prio1 = filter1.getClass().getAnnotation(Priority.class); + Priority prio2 = filter2.getClass().getAnnotation(Priority.class); + if(prio1!=null) { + ord1 = prio1.value(); + } + if(prio2!=null) { + ord2 = prio2.value(); + } + } if (ord1 < ord2) { return -1; } else if (ord1 > ord2) { diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java index 3222635..3a35c37 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java @@ -21,7 +21,6 @@ package org.apache.tamaya.spisupport; import org.apache.tamaya.spi.PropertySource; import org.apache.tamaya.spi.PropertyValue; -import javax.annotation.Priority; import java.io.Serializable; import java.util.Comparator; import java.util.logging.Logger; @@ -76,7 +75,7 @@ public class PropertySourceComparator implements Comparator<PropertySource>, Ser * to convert it to an {@code int} createValue, using {@link Integer#parseInt(String)}.</li> * <li>It tries to find and evaluate a method {@code int getOrdinal()}.</li> * <li>It tries to find and evaluate a static field {@code int ORDINAL}.</li> - * <li>It tries to find and evaluate a class level {@link Priority} annotation.</li> + * <li>It tries to find and evaluate a class level {@link javax.annotation.Priority} annotation.</li> * <li>It uses the default priority ({@code 0}.</li> * </ol> * @param propertySource the property source, not {@code null}. diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySource.java index c53bd76..ae156f5 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySource.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySource.java @@ -198,6 +198,13 @@ public class EnvironmentPropertySource extends BasePropertySource { return "environment-properties"; } + /* + Exact match (i.e. com.ACME.size) + +Replace the character that is neither alphanumeric nor _ with _ (i.e. com_ACME_size) + +Replace the character that is neither alphanumeric nor _ with _ and convert to upper case (i.e. COM_ACME_SIZE) + */ @Override public PropertyValue get(String key) { if (isDisabled()) { @@ -209,12 +216,13 @@ public class EnvironmentPropertySource extends BasePropertySource { String value = getPropertiesProvider().getenv(effectiveKey); // Replace all . by _ (i.e. com_ACME_size) if(value==null){ - value = getPropertiesProvider().getenv(effectiveKey.replaceAll("\\.", "_")); + effectiveKey = effectiveKey.replaceAll("\\W", "_"); + value = getPropertiesProvider().getenv(effectiveKey); } // Replace all . by _ and convert to upper case (i.e. COM_ACME_SIZE) if(value==null){ - value = getPropertiesProvider().getenv(effectiveKey.replaceAll("\\.", "_") - .toUpperCase()); + effectiveKey = effectiveKey.toUpperCase(); + value = getPropertiesProvider().getenv(effectiveKey); } if(value==null){ return null; @@ -222,6 +230,7 @@ public class EnvironmentPropertySource extends BasePropertySource { return PropertyValue.createValue(key, value).setMeta("source", getName()); } + private boolean hasPrefix() { return null != prefix && prefix.isEmpty(); } diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/JavaConfigurationPropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/JavaConfigurationPropertySource.java index 598808d..990a025 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/JavaConfigurationPropertySource.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/JavaConfigurationPropertySource.java @@ -86,23 +86,12 @@ public class JavaConfigurationPropertySource extends BasePropertySource implemen private Collection<? extends PropertySource> loadPropertySourcesByName(String filename, ClassLoader classLoader) { List<PropertySource> propertySources = new ArrayList<>(); - Enumeration<URL> propertyLocations; - try { - propertyLocations = ServiceContextManager.getServiceContext(classLoader) + Collection<URL> propertyLocations = ServiceContextManager.getServiceContext(classLoader) .getResources(filename); - } catch (IOException e) { - String msg = format("Error while searching for %s", filename); - throw new ConfigException(msg, e); + for (URL currentUrl:propertyLocations) { + propertySources.add(new SimplePropertySource(currentUrl)); } - - while (propertyLocations.hasMoreElements()) { - URL currentUrl = propertyLocations.nextElement(); - SimplePropertySource sps = new SimplePropertySource(currentUrl); - - propertySources.add(sps); - } - return propertySources; } diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/PropertiesResourcePropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/PropertiesResourcePropertySource.java index 13dfd7d..9cd264a 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/PropertiesResourcePropertySource.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/PropertiesResourcePropertySource.java @@ -18,12 +18,14 @@ */ package org.apache.tamaya.spisupport.propertysource; +import org.apache.tamaya.ConfigException; import org.apache.tamaya.spi.ChangeSupport; import org.apache.tamaya.spi.PropertySource; import org.apache.tamaya.spi.PropertyValue; import org.apache.tamaya.spi.ServiceContextManager; import org.apache.tamaya.spisupport.PropertySourceChangeSupport; +import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.*; @@ -88,8 +90,12 @@ public class PropertiesResourcePropertySource extends BasePropertySource { * @return the loaded properties. */ private Map<String, PropertyValue> loadProps(String path, ClassLoader cl) { - URL url = ServiceContextManager.getServiceContext(cl).getResource(path); - return loadProps(url); + try { + URL url = ServiceContextManager.getServiceContext(cl).getResource(path); + return loadProps(url); + }catch(Exception e){ + throw new ConfigException("Failed to load properties from " + path, e); + } } /** diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/services/DefaultServiceContext.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/services/DefaultServiceContext.java index 257baab..7bd0506 100644 --- a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/services/DefaultServiceContext.java +++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/services/DefaultServiceContext.java @@ -22,6 +22,7 @@ import org.apache.tamaya.ConfigException; import org.apache.tamaya.spi.ClassloaderAware; import org.apache.tamaya.spi.ServiceContext; import org.apache.tamaya.spisupport.PriorityServiceComparator; +import org.apache.tamaya.spisupport.propertysource.SimplePropertySource; import javax.annotation.Priority; import java.io.IOException; @@ -150,10 +151,12 @@ public final class DefaultServiceContext implements ServiceContext { * @return a priority, by default 1. */ public static int getPriority(Object o){ - int prio = 1; //X TODO discuss default priority - Priority priority = o.getClass().getAnnotation(Priority.class); - if (priority != null) { - prio = priority.value(); + int prio = 1; + if(ServiceContext.PRIORITY_ANNOTATION_AVAILABLE) { + Priority priority = o.getClass().getAnnotation(Priority.class); + if (priority != null) { + prio = priority.value(); + } } return prio; } @@ -213,8 +216,18 @@ public final class DefaultServiceContext implements ServiceContext { } @Override - public Enumeration<URL> getResources(String resource) throws IOException { - return classLoader.getResources(resource); + public Collection<URL> getResources(String resource) { + List<URL> urls = new ArrayList<>(); + try { + Enumeration<URL> found = getClassLoader().getResources(resource); + while (found.hasMoreElements()) { + urls.add(found.nextElement()); + } + }catch(Exception e){ + Logger.getLogger(ServiceContext.class.getName()) + .log(Level.FINEST, e, () -> "Failed to lookup resources: " + resource); + } + return urls; } @Override