http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java ---------------------------------------------------------------------- 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 f870c46..9c940ae 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 @@ -26,6 +26,7 @@ import javax.annotation.Priority; import java.text.MessageFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; @@ -49,24 +50,36 @@ public final class DefaultServiceContext implements ServiceContext { private Map<Class, Class> factoryTypes = new ConcurrentHashMap<>(); @Override - public <T> T getService(Class<T> serviceType) { - Object cached = singletons.get(serviceType); - if (cached == null) { - cached = create(serviceType); - if(cached!=null) { - singletons.put(serviceType, cached); + public <T> T getService(Class<T> serviceType, Supplier<T> supplier) { + T service = (T)singletons.get(serviceType); + if(service!=null){ + return service; + } + Collection<T> services = loadServices(serviceType, null); + if (services.isEmpty() && supplier!=null){ + T instance = supplier.get(); + if(instance instanceof ClassloaderAware){ + ((ClassloaderAware)instance).init(this.classLoader); } + register(serviceType, instance, true); + return instance; + } + T t = getServiceWithHighestPriority(services, serviceType); + if(t!=null) { + this.singletons.put(serviceType, t); } - return serviceType.cast(cached); + return t; } @Override - public <T> T create(Class<T> serviceType) { - @SuppressWarnings("unchecked") - Class<? extends T> implType = factoryTypes.get(serviceType); + public <T> T create(Class<T> serviceType, Supplier<T> supplier) { + Class<? extends T> implType = factoryTypes.get(serviceType); if(implType==null) { - Collection<T> services = getServices(serviceType); + Collection<T> services = loadServices(serviceType, null); if (services.isEmpty()) { + if(supplier!=null){ + return supplier.get(); + } return null; } else { return getServiceWithHighestPriority(services, serviceType); @@ -75,7 +88,7 @@ public final class DefaultServiceContext implements ServiceContext { try { return implType.newInstance(); } catch (Exception e) { - LOG.log(Level.SEVERE, "Failed to create instance of " + implType.getName(), e); + LOG.log(Level.SEVERE, "Failed to createObject instance of " + implType.getName(), e); return null; } } @@ -90,7 +103,7 @@ public final class DefaultServiceContext implements ServiceContext { */ private <T> T getServiceWithHighestPriority(Collection<T> services, Class<T> serviceType) { T highestService = null; - // we do not need the priority stuff if the list contains only one element + // we do not need the priority stuff if the createList contains only one element if (services.size() == 1) { highestService = services.iterator().next(); this.factoryTypes.put(serviceType, highestService.getClass()); @@ -118,7 +131,9 @@ public final class DefaultServiceContext implements ServiceContext { highestPriority, services)); } - this.factoryTypes.put(serviceType, highestService.getClass()); + if(highestService!=null) { + this.factoryTypes.put(serviceType, highestService.getClass()); + } return highestService; } @@ -130,12 +145,26 @@ public final class DefaultServiceContext implements ServiceContext { * @return the items found, never {@code null}. */ @Override - public <T> List<T> getServices(final Class<T> serviceType) { + public <T> List<T> getServices(final Class<T> serviceType, Supplier<List<T>> supplier) { @SuppressWarnings("unchecked") List<T> found = (List<T>) servicesLoaded.get(serviceType); if (found != null) { return found; } + List<T> services = loadServices(serviceType, supplier); + @SuppressWarnings("unchecked") + final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>) services)); + return previousServices != null ? previousServices : services; + } + + /** + * Loads services. + * + * @param <T> the concrete type. + * @param serviceType The service type. + * @return the items found, never {@code null}. + */ + private <T> List<T> loadServices(final Class<T> serviceType, Supplier<List<T>> supplier) { List<T> services = new ArrayList<>(); try { for (T t : ServiceLoader.load(serviceType, classLoader)) { @@ -144,27 +173,40 @@ public final class DefaultServiceContext implements ServiceContext { } services.add(t); } - // TODO does this make sense here...? -// if(services.isEmpty()) { -// for (T t : ServiceLoader.load(serviceType, serviceType.getClassLoader())) { -// if(t instanceof ClassloaderAware){ -// ((ClassloaderAware)t).init(classLoader); -// } -// services.add(t); -// } -// } Collections.sort(services, PriorityServiceComparator.getInstance()); services = Collections.unmodifiableList(services); } catch (ServiceConfigurationError e) { - LOG.log(Level.WARNING, - "Error loading services current type " + serviceType, e); + if(supplier!=null){ + services = supplier.get(); + }else { + LOG.log(Level.WARNING, + "Error loading services current type " + serviceType, e); + } if(services==null){ services = Collections.emptyList(); } } - @SuppressWarnings("unchecked") - final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>) services)); - return previousServices != null ? previousServices : services; + return services; + } + + @Override + public <T> T register(Class<T> serviceType, T instance, boolean force) { + if(force){ + singletons.put(serviceType, instance); + }else { + singletons.putIfAbsent(serviceType, instance); + } + return (T)singletons.get(serviceType); + } + + @Override + public <T> List<T> register(Class<T> type, List<T> instances, boolean force) { + if(force){ + servicesLoaded.put(type, (List)instances); + }else { + servicesLoaded.putIfAbsent(type, (List)instances); + } + return (List<T>)servicesLoaded.get(type); }
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java index 029c93d..2c0054f 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java @@ -24,6 +24,7 @@ import org.apache.tamaya.spi.PropertyConverter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.math.RoundingMode; import java.util.Locale; import java.util.Objects; import java.util.logging.Level; @@ -45,7 +46,7 @@ public class EnumConverter<T> implements PropertyConverter<T> { try { this.factory = enumType.getMethod("valueOf", String.class); } catch (NoSuchMethodException e) { - throw new ConfigException("Uncovertible enum type without valueOf method found, please provide a custom " + + throw new ConfigException("Uncovertible enum type without createValue method found, please provide a custom " + "PropertyConverter for: " + enumType.getName()); } } @@ -57,12 +58,12 @@ public class EnumConverter<T> implements PropertyConverter<T> { try { return (T) factory.invoke(null, value); } catch (InvocationTargetException | IllegalAccessException e) { - LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + enumType.getName(), e); + LOG.log(Level.FINEST, "Invalid enum createValue '" + value + "' for " + enumType.getName(), e); } try { return (T) factory.invoke(null, value.toUpperCase(Locale.ENGLISH)); } catch (InvocationTargetException | IllegalAccessException e) { - LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + enumType.getName(), e); + LOG.log(Level.FINEST, "Invalid enum createValue '" + value + "' for " + enumType.getName(), e); } return null; } http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/main/java/org/apache/tamaya/spisupport/MetadataProvider.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/MetadataProvider.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/MetadataProvider.java new file mode 100644 index 0000000..24e28ef --- /dev/null +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/MetadataProvider.java @@ -0,0 +1,75 @@ +/* + * 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.spisupport; + +import org.apache.tamaya.spi.ConfigurationContext; + +import java.util.Map; + +/** + * This interface allows to plugin different metadata mechanism. The default implementation + * does load metadata information along the same property sources hierarchy as configuration. + * MetaData entries are identified by a {@code [META]} prefix. Alternate implementations can + * choose whatever is appropriate, including loading metadata from external sources. + */ +public interface MetadataProvider { + + /** + * Initializes the provider with the given context. Each context must manage it's own + * provider instance. + * @param context the target context, never null. + * @return this instance, for chaining. + */ + MetadataProvider init(ConfigurationContext context); + + /** + * Access the current metadata for the given configuration context. The MetaData will be + * accessible from {@link ConfigurationContext#getMetadata()}. Note that the metadata must not + * to be cached by it's consumers, so caching/optimazitation is delegated to this implementation. + * @return the (immutable) metadata of this configuration context. + */ + Map<String,String> getMetaData(); + + /** + * Adds additional metadata. This metadata entries typically override all entries + * from alternate sources. + * + * @param key the key, not null. + * @param value the value, not null. + * @return this instance, for chaining. + */ + MetadataProvider setMeta(String key, String value); + + /** + * Adds additional metadata. This metadata entries typically override all entries + * from alternate sources. + * + * @param metaData the metadata to set/replace. + * @return this instance, for chaining. + */ + MetadataProvider setMeta(Map<String, String> metaData); + + /** + * Resets this instance, which means it reloads metadata based on the given context and + * + * @return this instance, for chaining. + */ + MetadataProvider reset(); + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java ---------------------------------------------------------------------- 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 8cc1fef..2f484a1 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 @@ -55,7 +55,7 @@ public class PriorityServiceComparator implements Comparator<Object>, Serializab } /** - * Checks the given instance for a @Priority annotation. If present the annotation's value is evaluated. If no such + * Checks the given instance for a @Priority annotation. If present the annotation's createValue is evaluated. If no such * annotation is present, a default priority {@code 1} is returned. * * @param o the instance, not {@code null}. @@ -66,7 +66,7 @@ public class PriorityServiceComparator implements Comparator<Object>, Serializab } /** - * Checks the given type optionally annotated with a @Priority. If present the annotation's value is evaluated. + * Checks the given type optionally annotated with a @Priority. If present the annotation's createValue is evaluated. * If no such annotation is present, a default priority {@code 1} is returned. * * @param type the type, not {@code null}. http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java ---------------------------------------------------------------------- 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 a672fe7..22fe67e 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 @@ -205,16 +205,16 @@ public class PropertyConverterManager { /** - * Get the list of all current registered converters for the given target type. + * Get the createList of all current registered converters for the given target type. * * <p> - * If no converters are registered, the component tries to create and register dynamic + * If no converters are registered, the component tries to createObject and register dynamic * converters based on String constructor or static factory methods available. * The converters provided are of the following type and returned in the following order: * <ul> * <li>Converters mapped explicitly to the required target type are returned first, ordered * by decreasing priority. This means, if explicit converters are registered these are used - * primarily for converting a value.</li> + * primarily for converting a createValue.</li> * <li>The target type of each explicitly registered converter can also be transitively mapped to * 1) all directly implemented interfaces, 2) all its superclasses (except Object), 3) all the interfaces * implemented by its superclasses. This group of transitive converters is returned similarly in the @@ -224,14 +224,14 @@ public class PropertyConverterManager { * compares the configuration values with the different enum members defined (case sensitive mapping).</li> * </ul> * <p> - * The above list of directly registered mappings are always tried first, before any transitive mapping + * The above createList of directly registered mappings are always tried first, before any transitive mapping * should be used. Also in all cases @Priority annotations are honored for ordering of the converters in place. * Transitive conversion is supported for all directly implemented interfaces (including inherited ones) and * the inheritance hierarchy (exception Object). Superinterfaces of implemented interfaces are ignored. * * @param targetType the target type, not {@code null}. * @param <T> the type class - * @return the ordered list of converters (may be empty for not convertible types). + * @return the ordered createList of converters (may be empty for not convertible types). * @see #createDefaultPropertyConverter(org.apache.tamaya.TypeLiteral) */ public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) { @@ -365,7 +365,7 @@ public class PropertyConverterManager { return new EnumConverter<>(targetType.getRawType()); } PropertyConverter<T> converter = null; - final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "valueOf", "instanceOf", "getInstance", "from", "fromString", "parse"); + final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "createValue", "instanceOf", "getInstance", "from", "fromString", "parse"); if (factoryMethod != null) { converter = new DefaultPropertyConverter<>(factoryMethod, targetType.getRawType()); } @@ -374,7 +374,7 @@ public class PropertyConverterManager { try { constr = targetType.getRawType().getDeclaredConstructor(String.class); } catch (NoSuchMethodException e) { - LOG.log(Level.FINEST, "No matching constrctor for " + targetType, e); + LOG.log(Level.FINEST, "No matching constructor for " + targetType, e); return null; } converter = new PropertyConverter<T>() { @@ -406,7 +406,7 @@ public class PropertyConverterManager { } /** - * Tries to evaluate a factory method that can be used to create an instance based on a String. + * Tries to evaluate a factory method that can be used to createObject an instance based on a String. * * @param type the target type * @param methodNames the possible static method names http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFiltering.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFiltering.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFiltering.java index c910a0d..9e63770 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFiltering.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFiltering.java @@ -46,10 +46,10 @@ public final class PropertyFiltering{ private PropertyFiltering(){} /** - * Filters a single value. - * @param value the raw value, not {@code null}. + * Filters a single createValue. + * @param value the raw createValue, not {@code null}. * @param context the context - * @return the filtered value, including {@code null}. + * @return the filtered createValue, including {@code null}. */ public static PropertyValue applyFilter(PropertyValue value, ConfigurationContext context) { FilterContext filterContext = new FilterContext(value, context); @@ -57,10 +57,10 @@ public final class PropertyFiltering{ } /** - * Filters a single value. + * Filters a single createValue. * @param values the full values, not {@code null}. * @param context the context - * @return the filtered value, including {@code null}. + * @return the filtered createValue, including {@code null}. */ public static List<PropertyValue> applyFilters(List<PropertyValue> values, ConfigurationContext context) { List<PropertyValue> result = new ArrayList<>(); @@ -83,7 +83,7 @@ public final class PropertyFiltering{ * Filters all properties. * @param rawProperties the unfiltered properties, not {@code null}. * @param context the context - * @return the filtered value, including {@code null}. + * @return the filtered createValue, including {@code null}. */ public static Map<String, PropertyValue> applyFilters(Map<String, PropertyValue> rawProperties, ConfigurationContext context) { Map<String, PropertyValue> result = new HashMap<>(); @@ -106,7 +106,7 @@ public final class PropertyFiltering{ /** * Basic filter logic. * @param context the filter context, not {@code null}. - * @return the filtered value. + * @return the filtered createValue. */ private static PropertyValue filterValue(PropertyValue inputValue, FilterContext context) { PropertyValue filteredValue = inputValue; http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java ---------------------------------------------------------------------- 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 92057c4..cccdd34 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 @@ -71,18 +71,18 @@ public class PropertySourceComparator implements Comparator<PropertySource>, Ser } /** - * Evaluates an ordinal value from a {@link PropertySource}, whereby the ordinal of type {@code int} + * Evaluates an ordinal createValue from a {@link PropertySource}, whereby the ordinal of type {@code int} * is evaluated as follows: * <ol> - * <li>It evaluates the {@code String} value for {@link PropertySource#TAMAYA_ORDINAL} and tries - * to convert it to an {@code int} value, using {@link Integer#parseInt(String)}.</li> + * <li>It evaluates the {@code String} createValue for {@link PropertySource#TAMAYA_ORDINAL} and tries + * 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 uses the default priority ({@code 0}.</li> * </ol> * @param propertySource the property source, not {@code null}. - * @return the ordinal value to compare the property source. + * @return the ordinal createValue to compare the property source. */ public static int getOrdinal(PropertySource propertySource) { return getOrdinal(propertySource, null); http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BasePropertySource.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BasePropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BasePropertySource.java index c026a11..bf75fb9 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BasePropertySource.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BasePropertySource.java @@ -125,7 +125,7 @@ public abstract class BasePropertySource implements PropertySource{ } /** - * Returns the default ordinal used, when no ordinal is setCurrent, or the ordinal was not parseable to an int value. + * Returns the default ordinal used, when no ordinal is setCurrent, or the ordinal was not parseable to an int createValue. * @return the default ordinal used, by default 0. */ public int getDefaultOrdinal(){ http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySource.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySource.java index fbea188..a5a5a05 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySource.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySource.java @@ -140,7 +140,7 @@ public class BuildablePropertySource implements PropertySource{ * With simple property builder. * * @param key the key - * @param value the value + * @param value the createValue * @return the builder */ public Builder withSimpleProperty(String key, String value) { @@ -151,7 +151,7 @@ public class BuildablePropertySource implements PropertySource{ * With simple property builder. * * @param key the key - * @param value the value + * @param value the createValue * @param source the source * @return the builder */ http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/CLIPropertySource.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/CLIPropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/CLIPropertySource.java index 8364ec2..f7bf8a3 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/CLIPropertySource.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/CLIPropertySource.java @@ -73,7 +73,7 @@ public class CLIPropertySource extends BasePropertySource { /** * Configure the main arguments, hereby parsing and mapping the main arguments into - * configuration properties as key-value pairs. + * configuration properties as key-createValue pairs. * @param args the main arguments, not null. */ public static void initMainArgs(String... args){ http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySource.java ---------------------------------------------------------------------- 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 df16b76..f16903f 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 @@ -26,8 +26,8 @@ import java.util.Map; /** * <p>{@link org.apache.tamaya.spi.PropertySource} to access environment variables via Tamaya - * which are setCurrent via {@code export VARIABLE=value} on UNIX systems or - * {@code setCurrent VARIABLE=value} on Windows systems.</p> + * which are setCurrent via {@code export VARIABLE=createValue} on UNIX systems or + * {@code setCurrent VARIABLE=createValue} on Windows systems.</p> * * <p>Using the {@linkplain EnvironmentPropertySource} without any * additional configuration gives access to all existing environment @@ -71,7 +71,7 @@ import java.util.Map; * $ java -Dtamaya.envprops.prefix=a81 -jar application.jar * </pre> * - * <p>The application specific value can now be accessed from the code of the + * <p>The application specific createValue can now be accessed from the code of the * application like this:</p> * * <pre> @@ -153,7 +153,7 @@ public class EnvironmentPropertySource extends BasePropertySource { } /** - * Creates a new instance using a fixed ordinal value. + * Creates a new instance using a fixed ordinal createValue. * @param ordinal the ordinal number. */ public EnvironmentPropertySource(int ordinal){ http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SimplePropertySource.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SimplePropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SimplePropertySource.java index 335ed23..690a809 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SimplePropertySource.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SimplePropertySource.java @@ -262,7 +262,7 @@ public class SimplePropertySource extends BasePropertySource { * Sets the {@code properties} and returns a reference to this Builder so that the methods can be chained together. * * @param key the {@code properties} key to setCurrent - * @param val the {@code properties} value to setCurrent + * @param val the {@code properties} createValue to setCurrent * @return a reference to this Builder */ public Builder withProperty(String key, String val) { http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SystemPropertySource.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SystemPropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SystemPropertySource.java index 7f7fac2..f3e9dd1 100644 --- a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SystemPropertySource.java +++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SystemPropertySource.java @@ -101,7 +101,7 @@ public class SystemPropertySource extends BasePropertySource { } /** - * Creates a new instance using a fixed ordinal value. + * Creates a new instance using a fixed ordinal createValue. * @param ordinal the ordinal number. */ public SystemPropertySource(int ordinal){ http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/test/java/org/apache/tamaya/spisupport/C.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/C.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/C.java index 9d51bb0..648cd15 100644 --- a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/C.java +++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/C.java @@ -38,8 +38,8 @@ public class C extends B implements Readable{ } /** - * Returns the input value, setCurrent on creation. Used for test assertion. - * @return the in value. + * Returns the input createValue, setCurrent on creation. Used for test assertion. + * @return the in createValue. */ public String getInValue() { return inValue; http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultConfigurationTest.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultConfigurationTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultConfigurationTest.java index afe5db6..6dd14d7 100644 --- a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultConfigurationTest.java +++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultConfigurationTest.java @@ -164,7 +164,7 @@ public class DefaultConfigurationTest { } /** - * Tests for convertValue(String key, String value, TypeLiteral<T> type) + * Tests for convertValue(String key, String createValue, TypeLiteral<T> type) */ @Test public void testConvertValue() { http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultServiceContextTest.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultServiceContextTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultServiceContextTest.java index 0cb21ab..934a0e3 100644 --- a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultServiceContextTest.java +++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultServiceContextTest.java @@ -23,6 +23,7 @@ import org.apache.tamaya.spi.ConfigurationProviderSpi; import org.junit.Test; import javax.annotation.Priority; +import java.util.Arrays; import java.util.Collection; import java.util.List; import static org.assertj.core.api.Assertions.*; @@ -104,6 +105,22 @@ public class DefaultServiceContextTest { assertThat(services.isEmpty()).isTrue(); } + @Test + public void testRegister_One() throws Exception { + context.register(Long.class, Long.valueOf(11L), true); + Long service = context.getService(Long.class); + assertThat(service).isNotNull(); + } + + @Test + public void testRegister_Many() throws Exception { + context.register(Double.class, Arrays.asList(Double.valueOf(1.2345), Double.valueOf(2345), Double.valueOf(345)), false); + List<Double> services = context.getServices(Double.class); + assertThat(services).isNotNull(); + assertThat(services.isEmpty()).isFalse(); + assertThat(services.size()).isEqualTo(3); + } + // some test interfaces and classes http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContext.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContext.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContext.java deleted file mode 100644 index 96d2cd4..0000000 --- a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContext.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.spisupport; - -import org.apache.tamaya.TypeLiteral; -import org.apache.tamaya.spi.*; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public class EmptyConfigurationContext implements ConfigurationContext{ - - private static final ConfigurationContext INSTANCE = new EmptyConfigurationContext(); - - @Override - public ServiceContext getServiceContext() { - return ServiceContextManager.getServiceContext(getClass().getClassLoader()); - } - - @Override - public void addPropertySources(PropertySource... propertySources) { - } - - @Override - public List<PropertySource> getPropertySources() { - return Collections.emptyList(); - } - - @Override - public PropertySource getPropertySource(String name) { - return null; - } - - @Override - public <T> void addPropertyConverter(TypeLiteral<T> type, PropertyConverter<T> propertyConverter) { - } - - @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_POLICY; - } - - @Override - public ConfigurationContextBuilder toBuilder() { - return EmptyConfigurationContextBuilder.instance(); - } - - public static ConfigurationContext instance() { - return INSTANCE; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContextBuilder.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContextBuilder.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContextBuilder.java index 5ea6bfa..837445d 100644 --- a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContextBuilder.java +++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContextBuilder.java @@ -43,6 +43,16 @@ public class EmptyConfigurationContextBuilder implements ConfigurationContextBui } @Override + public ConfigurationContextBuilder addMetaData(Map<String, String> metaData) { + return this; + } + + @Override + public ConfigurationContextBuilder addMetaData(String key, String value) { + return this; + } + + @Override public ConfigurationContextBuilder addPropertySources(PropertySource... propertySources) { return this; } @@ -179,7 +189,7 @@ public class EmptyConfigurationContextBuilder implements ConfigurationContextBui @Override public ConfigurationContext build() { - return EmptyConfigurationContext.instance(); + return ConfigurationContext.EMPTY; } public static ConfigurationContextBuilder instance() { http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/test/java/org/apache/tamaya/spisupport/MockedConfigurationContext.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/MockedConfigurationContext.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/MockedConfigurationContext.java index 23226b0..5c09039 100644 --- a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/MockedConfigurationContext.java +++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/MockedConfigurationContext.java @@ -18,10 +18,8 @@ */ package org.apache.tamaya.spisupport; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; + import org.apache.tamaya.TypeLiteral; import org.apache.tamaya.spi.*; @@ -34,6 +32,7 @@ public class MockedConfigurationContext implements ConfigurationContext { ServiceContext serviceContext = ServiceContextManager.getServiceContext(getClass().getClassLoader()); PropertyConverterManager pcm = new PropertyConverterManager(serviceContext,false); List<PropertySource> pss = new ArrayList<>(); + Map<String,String> metaData = new HashMap<>(); public MockedConfigurationContext() { pcm.register(TypeLiteral.of(Integer.class), new IntegerTestConverter()); @@ -41,6 +40,11 @@ public class MockedConfigurationContext implements ConfigurationContext { } @Override + public Map<String, String> getMetadata() { + return metaData; + } + + @Override public ServiceContext getServiceContext() { return serviceContext; } http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/test/java/org/apache/tamaya/spisupport/RegexPropertyFilterTest.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/RegexPropertyFilterTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/RegexPropertyFilterTest.java index aa0fe85..7e7d64e 100644 --- a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/RegexPropertyFilterTest.java +++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/RegexPropertyFilterTest.java @@ -34,7 +34,7 @@ public class RegexPropertyFilterTest { private static PropertyValue prop1 = PropertyValue.of("test1", "test1", "test"); private static PropertyValue prop2 = PropertyValue.of("test2", "test2", "test"); private static PropertyValue prop3 = PropertyValue.of("test1.test3", "test.test3", "test"); - private static ConfigurationContext configContext = EmptyConfigurationContext.instance(); + private static ConfigurationContext configContext = ConfigurationContext.EMPTY; @org.junit.Test public void testFilterProperty() throws Exception { http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySourceTest.java ---------------------------------------------------------------------- diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySourceTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySourceTest.java index 2b7928e..bff46d7 100644 --- a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySourceTest.java +++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySourceTest.java @@ -115,7 +115,7 @@ public class EnvironmentPropertySourceTest { System.out.println(localEnvironmentPropertySource); assertThat(localEnvironmentPropertySource.getPrefix()).isEqualTo("fancyprefix"); localEnvironmentPropertySource.setPropertiesProvider(new MockedSystemPropertiesProvider()); - assertThat(localEnvironmentPropertySource.get("somekey").getValue()).isEqualTo("somekey.value"); + assertThat(localEnvironmentPropertySource.get("somekey").getValue()).isEqualTo("somekey.createValue"); } @Test @@ -149,7 +149,7 @@ public class EnvironmentPropertySourceTest { private class MockedSystemPropertiesProvider extends EnvironmentPropertySource.SystemPropertiesProvider { @Override String getenv(String key) { - return key + ".value"; + return key + ".createValue"; } } } http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/code/spi-support/src/test/java/org/apache/tamaya/spisupport/services/DefaultServiceContext.java ---------------------------------------------------------------------- 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 963bfbb..c0e4a23 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 @@ -19,6 +19,7 @@ package org.apache.tamaya.spisupport.services; import org.apache.tamaya.ConfigException; +import org.apache.tamaya.spi.ClassloaderAware; import org.apache.tamaya.spi.ServiceContext; import org.apache.tamaya.spisupport.PriorityServiceComparator; @@ -28,6 +29,7 @@ import java.net.URL; import java.text.MessageFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; @@ -63,11 +65,12 @@ public final class DefaultServiceContext implements ServiceContext { @SuppressWarnings("rawtypes") private Map<Class, Class> factoryTypes = new ConcurrentHashMap<>(); + @Override - public <T> T getService(Class<T> serviceType) { + public <T> T getService(Class<T> serviceType, Supplier<T> supplier) { Object cached = singletons.get(serviceType); if (cached == null) { - cached = create(serviceType); + cached = create(serviceType, supplier); if(cached!=null) { singletons.put(serviceType, cached); } @@ -76,12 +79,19 @@ public final class DefaultServiceContext implements ServiceContext { } @Override - public <T> T create(Class<T> serviceType) { + public <T> T create(Class<T> serviceType, Supplier<T> supplier) { @SuppressWarnings("unchecked") - Class<? extends T> implType = factoryTypes.get(serviceType); + Class<? extends T> implType = factoryTypes.get(serviceType); if(implType==null) { - Collection<T> services = getServices(serviceType); + Collection<T> services = loadServices(serviceType, null); if (services.isEmpty()) { + if(supplier!=null){ + T instance = supplier.get(); + if(instance instanceof ClassloaderAware){ + ((ClassloaderAware)instance).init(this.classLoader); + } + return instance; + } return null; } else { return getServiceWithHighestPriority(services, serviceType); @@ -90,51 +100,51 @@ public final class DefaultServiceContext implements ServiceContext { try { return implType.newInstance(); } catch (Exception e) { - LOG.log(Level.SEVERE, "Failed to create instance of " + implType.getName(), e); + LOG.log(Level.SEVERE, "Failed to createObject instance of " + implType.getName(), e); + if(supplier!=null){ + return supplier.get(); + } return null; } } - /** - * Loads and registers services. - * - * @param <T> the concrete type. - * @param serviceType The service type. - * @return the items found, never {@code null}. - */ + @Override - public <T> List<T> getServices(final Class<T> serviceType) { + public <T> List<T> getServices(Class<T> serviceType, Supplier<List<T>> supplier) { @SuppressWarnings("unchecked") - List<T> found = (List<T>) servicesLoaded.get(serviceType); + List<T> found = (List<T>) servicesLoaded.get(serviceType); if (found != null) { return found; } + List<T> services = loadServices(serviceType, supplier); + @SuppressWarnings("unchecked") + final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>) services)); + return previousServices != null ? previousServices : services; + } + + private <T> List<T> loadServices(Class<T> serviceType, Supplier<List<T>> supplier) { List<T> services = new ArrayList<>(); try { - for (T t : ServiceLoader.load(serviceType)) { + for (T t : ServiceLoader.load(serviceType, classLoader)) { services.add(t); } - if(services.isEmpty()) { - for (T t : ServiceLoader.load(serviceType, serviceType.getClassLoader())) { - services.add(t); - } - } Collections.sort(services, PriorityServiceComparator.getInstance()); services = Collections.unmodifiableList(services); } catch (ServiceConfigurationError e) { LOG.log(Level.WARNING, "Error loading services current type " + serviceType, e); + if(supplier!=null){ + services = supplier.get(); + } if(services==null){ services = Collections.emptyList(); } } - @SuppressWarnings("unchecked") - final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>) services)); - return previousServices != null ? previousServices : services; + return services; } /** - * Checks the given instance for a @Priority annotation. If present the annotation's value is evaluated. If no such + * Checks the given instance for a @Priority annotation. If present the annotation's createValue is evaluated. If no such * annotation is present, a default priority of {@code 1} is returned. * @param o the instance, not {@code null}. * @return a priority, by default 1. @@ -158,7 +168,7 @@ public final class DefaultServiceContext implements ServiceContext { */ private <T> T getServiceWithHighestPriority(Collection<T> services, Class<T> serviceType) { T highestService = null; - // we do not need the priority stuff if the list contains only one element + // we do not need the priority stuff if the createList contains only one element if (services.size() == 1) { highestService = services.iterator().next(); this.factoryTypes.put(serviceType, highestService.getClass()); @@ -186,7 +196,9 @@ public final class DefaultServiceContext implements ServiceContext { highestPriority, services)); } - this.factoryTypes.put(serviceType, highestService.getClass()); + if(highestService!=null) { + this.factoryTypes.put(serviceType, highestService.getClass()); + } return highestService; } @@ -210,4 +222,24 @@ public final class DefaultServiceContext implements ServiceContext { return classLoader.getResource(resource); } + @Override + public <T> T register(Class<T> type, T instance, boolean force) { + if(force){ + singletons.put(type, instance); + }else{ + singletons.putIfAbsent(type, instance); + } + return (T)singletons.get(type); + } + + @Override + public <T> List<T> register(Class<T> type, List<T> instances, boolean force) { + if(force){ + singletons.put(type, Collections.unmodifiableList(instances)); + }else { + servicesLoaded.putIfAbsent(type, Collections.unmodifiableList(instances)); + } + return (List<T>)servicesLoaded.get(type); + } + } http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/Main.java ---------------------------------------------------------------------- diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/Main.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/Main.java index dc254e8..a56d18c 100644 --- a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/Main.java +++ b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/Main.java @@ -19,7 +19,6 @@ package org.apache.tamaya.examples.custompropertysource; import org.apache.tamaya.Configuration; -import org.apache.tamaya.ConfigurationProvider; import java.io.PrintStream; import java.util.Map; @@ -64,7 +63,7 @@ public class Main { } public static void main(String[] args) { - Configuration cfg = ConfigurationProvider.getConfiguration(); + Configuration cfg = Configuration.current(); System.out.println("*****************************************************"); System.out.println("Simple Example (with a PropertySource and a Provider)"); http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/67ffcbf2/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySource.java ---------------------------------------------------------------------- diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySource.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySource.java index d21230e..7510090 100644 --- a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySource.java +++ b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySource.java @@ -43,8 +43,8 @@ public class SimplePropertySource extends BasePropertySource { for(Map.Entry en: properties.entrySet()){ props.put(en.getKey().toString(), - PropertyValue.of(en.getKey().toString(), en.getValue().toString(), - getName())); + PropertyValue.createValue(en.getKey().toString(), en.getValue().toString()) + .setMeta("source", getName())); } } finally{
