TAMAYA-318 Moved spi-support as API base implementation package to remove code duplicates.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/7917a9f3 Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/7917a9f3 Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/7917a9f3 Branch: refs/heads/master Commit: 7917a9f38e4087814ea1987395cb48edff7dfe2c Parents: 353817c Author: Anatole Tresch <anat...@apache.org> Authored: Mon Nov 13 16:40:43 2017 +0100 Committer: Anatole Tresch <anat...@apache.org> Committed: Mon Nov 13 16:40:45 2017 +0100 ---------------------------------------------------------------------- code/core/pom.xml | 5 + .../org/apache/tamaya/core/OSGIActivator.java | 4 + .../internal/DefaultConfigValueEvaluator.java | 72 --- .../core/internal/DefaultConfiguration.java | 245 ---------- .../internal/DefaultConfigurationContext.java | 73 ++- .../DefaultConfigurationContextBuilder.java | 101 ++-- .../internal/DefaultConfigurationProvider.java | 1 + .../core/internal/DefaultServiceContext.java | 1 + .../tamaya/core/internal/OSGIServiceLoader.java | 1 + .../internal/PriorityServiceComparator.java | 81 ---- .../core/internal/PropertyConverterManager.java | 464 ------------------ .../core/internal/PropertyFilterComparator.java | 73 --- .../tamaya/core/internal/PropertyFiltering.java | 125 ----- .../core/internal/PropertySourceComparator.java | 86 ---- .../tamaya/core/internal/ReflectionUtil.java | 42 -- .../core/internal/WrappedPropertySource.java | 125 ----- .../core/internal/converters/ConvertQuery.java | 68 +++ .../core/internal/converters/EnumConverter.java | 83 ---- .../core/internal/converters/FileConverter.java | 1 - .../converters/OffsetDateTimeConverter.java | 1 - .../converters/OffsetTimeConverter.java | 1 - .../internal/converters/OptionalConverter.java | 42 -- .../core/internal/converters/PathConverter.java | 3 - .../internal/converters/SupplierConverter.java | 71 +++ .../core/propertysource/BasePropertySource.java | 162 ------- .../core/propertysource/CLIPropertySource.java | 131 ------ .../EnvironmentPropertySource.java | 293 ------------ .../JavaConfigurationPropertySource.java | 136 ------ .../propertysource/SimplePropertySource.java | 140 ------ .../propertysource/SystemPropertySource.java | 190 -------- .../core/propertysource/package-info.java | 23 - .../org.apache.tamaya.spi.PropertyConverter | 1 + .../org.apache.tamaya.spi.PropertySource | 8 +- .../core/ConfigurationContextBuilderTest.java | 2 +- .../DefaultConfigurationContextTest.java | 1 - .../core/internal/DefaultConfigurationTest.java | 201 -------- .../internal/PriorityServiceComparatorTest.java | 45 -- .../internal/PropertyConverterManagerTest.java | 182 ------- .../internal/PropertyFilterComparatorTest.java | 75 --- .../propertysource/BasePropertySourceTest.java | 136 ------ .../propertysource/CLIPropertySourceTest.java | 58 --- .../EnvironmentPropertySourceTest.java | 180 ------- .../PropertiesFilePropertySourceTest.java | 59 --- .../SimplePropertySourceTest.java | 89 ---- .../SystemPropertySourceTest.java | 91 ---- .../testdata/TestPropertyDefaultSource.java | 2 +- .../testdata/TestPropertySourceProvider.java | 2 +- .../org.apache.tamaya.spi.PropertySource | 4 +- code/pom.xml | 1 + code/spi-support/pom.xml | 81 ++++ .../tamaya/spisupport/ConfigValueEvaluator.java | 48 ++ .../tamaya/spisupport/ConfigurationBuilder.java | 334 +++++++++++++ .../spisupport/DefaultConfigValueEvaluator.java | 70 +++ .../tamaya/spisupport/DefaultConfiguration.java | 268 +++++++++++ .../spisupport/DefaultConfigurationBuilder.java | 229 +++++++++ .../spisupport/DefaultServiceContext.java | 204 ++++++++ .../apache/tamaya/spisupport/EnumConverter.java | 83 ++++ .../spisupport/PriorityServiceComparator.java | 84 ++++ .../spisupport/PropertyConverterManager.java | 471 +++++++++++++++++++ .../spisupport/PropertyFilterComparator.java | 72 +++ .../tamaya/spisupport/PropertyFiltering.java | 124 +++++ .../spisupport/PropertySourceComparator.java | 122 +++++ .../tamaya/spisupport/ReflectionUtil.java | 42 ++ .../tamaya/spisupport/RegexPropertyFilter.java | 84 ++++ .../propertysource/BasePropertySource.java | 173 +++++++ .../propertysource/BuildablePropertySource.java | 231 +++++++++ .../BuildablePropertySourceProvider.java | 114 +++++ .../propertysource/CLIPropertySource.java | 137 ++++++ .../EnvironmentPropertySource.java | 287 +++++++++++ .../JavaConfigurationPropertySource.java | 134 ++++++ .../propertysource/MapPropertySource.java | 102 ++++ .../PropertiesResourcePropertySource.java | 109 +++++ .../propertysource/SimplePropertySource.java | 284 +++++++++++ .../propertysource/SystemPropertySource.java | 199 ++++++++ .../propertysource/WrappedPropertySource.java | 126 +++++ .../spisupport/propertysource/package-info.java | 23 + .../java/org/apache/tamaya/spisupport/A.java | 29 ++ .../java/org/apache/tamaya/spisupport/B.java | 29 ++ .../BuildablePropertySourceProviderTest.java | 78 +++ .../spisupport/BuildablePropertySourceTest.java | 89 ++++ .../java/org/apache/tamaya/spisupport/C.java | 56 +++ .../tamaya/spisupport/CTestConverter.java | 32 ++ .../spisupport/DefaultConfigurationTest.java | 201 ++++++++ .../spisupport/EmptyConfigurationContext.java | 78 +++ .../EmptyConfigurationContextBuilder.java | 174 +++++++ .../PriorityServiceComparatorTest.java | 44 ++ .../PropertyConverterManagerTest.java | 180 +++++++ .../PropertyFilterComparatorTest.java | 76 +++ .../spisupport/RegexPropertyFilterTest.java | 70 +++ .../propertysource/BasePropertySourceTest.java | 136 ++++++ .../propertysource/CLIPropertySourceTest.java | 59 +++ .../propertysource/EnumConverterTest.java | 60 +++ .../EnvironmentPropertySourceTest.java | 68 +++ .../propertysource/MapPropertySourceTest.java | 76 +++ .../PropertiesFilePropertySourceTest.java | 60 +++ .../SimplePropertySourceTest.java | 89 ++++ .../SystemPropertySourceTest.java | 91 ++++ .../TestPropertyDefaultSource.java | 57 +++ .../services/DefaultServiceContext.java | 205 ++++++++ .../org.apache.tamaya.spi.PropertyConverter | 19 + .../org.apache.tamaya.spi.ServiceContext | 19 + .../src/test/resources/invalid-properties.xml | 25 + .../src/test/resources/non-xml-properties.xml | 18 + .../test/resources/overrideOrdinal.properties | 25 + .../src/test/resources/testfile.properties | 22 + .../src/test/resources/valid-properties.xml | 25 + .../apache/tamaya/examples/minimal/Main.java | 4 +- .../examples/minimal/TestConfigProvider.java | 2 +- .../SimplePropertySource.java | 2 +- .../SimplePropertySourceProvider.java | 2 +- .../tamaya/examples/distributed/Display.java | 4 +- .../examples/distributed/DisplayManager.java | 4 +- 112 files changed, 6703 insertions(+), 3721 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/pom.xml ---------------------------------------------------------------------- diff --git a/code/core/pom.xml b/code/core/pom.xml index 0c57c6d..2d98631 100644 --- a/code/core/pom.xml +++ b/code/core/pom.xml @@ -40,6 +40,11 @@ under the License. <version>${project.version}</version> </dependency> <dependency> + <groupId>org.apache.tamaya</groupId> + <artifactId>tamaya-spisupport</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/OSGIActivator.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/OSGIActivator.java b/code/core/src/main/java/org/apache/tamaya/core/OSGIActivator.java index 46355f3..09bf384 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/OSGIActivator.java +++ b/code/core/src/main/java/org/apache/tamaya/core/OSGIActivator.java @@ -23,6 +23,10 @@ package org.apache.tamaya.core; import org.apache.tamaya.ConfigurationProvider; import org.apache.tamaya.core.internal.*; import org.apache.tamaya.spi.ServiceContextManager; +import org.apache.tamaya.spisupport.DefaultConfiguration; +import org.apache.tamaya.core.internal.DefaultConfigurationContextBuilder; +import org.apache.tamaya.spisupport.PropertyFilterComparator; +import org.apache.tamaya.spisupport.PropertySourceComparator; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigValueEvaluator.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigValueEvaluator.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigValueEvaluator.java deleted file mode 100644 index 4d8a7f3..0000000 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigValueEvaluator.java +++ /dev/null @@ -1,72 +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.core.internal; - -import org.apache.tamaya.spi.ConfigurationContext; -import org.apache.tamaya.spi.PropertyFilter; -import org.apache.tamaya.spi.PropertySource; -import org.apache.tamaya.spi.PropertyValue; -import org.osgi.service.component.annotations.Component; - -import java.util.HashMap; -import java.util.Map; - - -/** - * Implementation of the Configuration API. This class uses the current {@link ConfigurationContext} to evaluate the - * chain of {@link PropertySource} and {@link PropertyFilter} - * instance to evaluate the current Configuration. - */ -@Component(service = ConfigValueEvaluator.class) -public class DefaultConfigValueEvaluator implements ConfigValueEvaluator{ - - @Override - public PropertyValue evaluteRawValue(String key, ConfigurationContext context) { - PropertyValue unfilteredValue = null; - for (PropertySource propertySource : context.getPropertySources()) { - unfilteredValue = context.getPropertyValueCombinationPolicy(). - collect(unfilteredValue, key, propertySource); - } - if(unfilteredValue==null || unfilteredValue.getValue()==null){ - return null; - } - return unfilteredValue; - } - - @Override - public Map<String, PropertyValue> evaluateRawValues(ConfigurationContext context) { - Map<String, PropertyValue> result = new HashMap<>(); - for (PropertySource propertySource : context.getPropertySources()) { - for (Map.Entry<String,PropertyValue> propEntry: propertySource.getProperties().entrySet()) { - PropertyValue unfilteredValue = result.get(propEntry.getKey()); - unfilteredValue = context.getPropertyValueCombinationPolicy(). - collect(unfilteredValue, propEntry.getKey(), propertySource); - if(unfilteredValue!=null){ - result.put(unfilteredValue.getKey(), unfilteredValue); - } - } - } - return result; - } - - @Override - public String toString() { - return "DefaultConfigEvaluator{}"; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java deleted file mode 100644 index 1c22e44..0000000 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java +++ /dev/null @@ -1,245 +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.core.internal; - -import org.apache.tamaya.ConfigException; -import org.apache.tamaya.ConfigOperator; -import org.apache.tamaya.ConfigQuery; -import org.apache.tamaya.Configuration; -import org.apache.tamaya.TypeLiteral; -import org.apache.tamaya.spi.*; -import org.osgi.service.component.annotations.Component; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Implementation of the Configuration API. This class uses the current {@link ConfigurationContext} to evaluate the - * chain of {@link PropertySource} and {@link PropertyFilter} - * instance to evaluate the current Configuration. - */ -@Component(service = Configuration.class) -public class DefaultConfiguration implements Configuration { - /** - * The logger. - */ - private static final Logger LOG = Logger.getLogger(DefaultConfiguration.class.getName()); - - /** - * The current {@link ConfigurationContext} of the current instance. - */ - private final ConfigurationContext configurationContext; - - /** - * EvaluationStrategy - */ - private ConfigValueEvaluator configEvaluator = loadConfigValueEvaluator(); - - private ConfigValueEvaluator loadConfigValueEvaluator() { - ConfigValueEvaluator eval = null; - try{ - eval = ServiceContextManager.getServiceContext() - .getService(ConfigValueEvaluator.class); - }catch(Exception e){ - LOG.log(Level.WARNING, "Failed to load ConfigValueEvaluator from ServiceContext, using default.", e); - } - if(eval==null){ - eval = new DefaultConfigValueEvaluator(); - } - return eval; - } - - - /** - * Constructor. - * @param configurationContext The configuration Context to be used. - */ - public DefaultConfiguration(ConfigurationContext configurationContext){ - this.configurationContext = Objects.requireNonNull(configurationContext); - } - - @Override - public String get(String key) { - Objects.requireNonNull(key, "Key must not be null."); - - PropertyValue value = configEvaluator.evaluteRawValue(key, configurationContext); - if(value==null){ - return null; - } - value = PropertyFiltering.applyFilter(value, configurationContext); - if(value!=null){ - return value.getValue(); - } - return null; - } - - - @Override - public String getOrDefault(String key, String defaultValue) { - Objects.requireNonNull(key, "Key must not be null."); - Objects.requireNonNull(defaultValue, "Default value must not be null"); - - String val = get(key); - if(val==null){ - return defaultValue; - } - return val; - } - - @Override - public <T> T getOrDefault(String key, Class<T> type, T defaultValue) { - Objects.requireNonNull(key, "Key must not be null."); - Objects.requireNonNull(type, "Target type must not be null"); - Objects.requireNonNull(defaultValue, "Default value must not be null"); - - T val = get(key, type); - if(val==null){ - return defaultValue; - } - return val; - } - - /** - * Get the current properties, composed by the loaded {@link PropertySource} and filtered - * by registered {@link PropertyFilter}. - * - * @return the final properties. - */ - @Override - public Map<String, String> getProperties() { - Map<String, PropertyValue> filtered = PropertyFiltering.applyFilters( - configEvaluator.evaluateRawValues(configurationContext), - configurationContext); - Map<String,String> result = new HashMap<>(); - for(PropertyValue val:filtered.values()){ - if(val.getValue()!=null) { - result.put(val.getKey(), val.getValue()); - // TODO: Discuss metadata handling... - result.putAll(val.getMetaEntries()); - } - } - return result; - } - - - /** - * Accesses the current String value for the given key and tries to convert it - * using the {@link PropertyConverter} instances provided by the current - * {@link ConfigurationContext}. - * - * @param key the property's absolute, or relative path, e.g. @code - * a/b/c/d.myProperty}, never {@code null}. - * @param type The target type required, not {@code null}. - * @param <T> the value type - * @return the converted value, never {@code null}. - */ - @SuppressWarnings("unchecked") - @Override - public <T> T get(String key, Class<T> type) { - Objects.requireNonNull(key, "Key must not be null."); - Objects.requireNonNull(type, "Target type must not be null"); - - return get(key, (TypeLiteral<T>)TypeLiteral.of(type)); - } - - /** - * Accesses the current String value for the given key and tries to convert it - * using the {@link PropertyConverter} instances provided by the current - * {@link ConfigurationContext}. - * - * @param key the property's absolute, or relative path, e.g. @code - * a/b/c/d.myProperty}. - * @param type The target type required, not {@code null}. - * @param <T> the value type - * @return the converted value, never {@code null}. - */ - @Override - public <T> T get(String key, TypeLiteral<T> type) { - Objects.requireNonNull(key, "Key must not be null."); - Objects.requireNonNull(type, "Target type must not be null"); - - return convertValue(key, get(key), type); - } - - @SuppressWarnings("unchecked") - protected <T> T convertValue(String key, String value, TypeLiteral<T> type) { - if (value != null) { - List<PropertyConverter<T>> converters = configurationContext.getPropertyConverters(type); - ConversionContext context = new ConversionContext.Builder(this, this.configurationContext, key, type) - .build(); - for (PropertyConverter<T> converter : converters) { - try { - T t = converter.convert(value, context); - if (t != null) { - return t; - } - } catch (Exception e) { - LOG.log(Level.INFO, "PropertyConverter: " + converter + " failed to convert value: " + value, e); - } - } - // if the target type is a String, we can return the value, no conversion required. - if(type.equals(TypeLiteral.of(String.class))){ - return (T)value; - } - // unsupported type, throw an exception - throw new ConfigException("Unparseable config value for type: " + type.getRawType().getName() + ": " + key + - ", supported formats: " + context.getSupportedFormats()); - } - return null; - } - - @Override - public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) { - Objects.requireNonNull(key); - Objects.requireNonNull(type); - Objects.requireNonNull(defaultValue); - - T val = get(key, type); - if(val==null){ - return defaultValue; - } - return val; - } - - @Override - public Configuration with(ConfigOperator operator) { - return operator.operate(this); - } - - @Override - public <T> T query(ConfigQuery<T> query) { - return query.query(this); - } - - @Override - public ConfigurationContext getContext() { - return this.configurationContext; - } - - @Override - public String toString() { - return "Configuration{\n " + - configurationContext + - '}'; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java index 9645681..95ebbca 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java +++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java @@ -1,24 +1,23 @@ /* * 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 + * 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 + * 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. + * 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.core.internal; -import org.apache.tamaya.ConfigurationProvider; import org.apache.tamaya.TypeLiteral; import org.apache.tamaya.spi.ConfigurationContext; import org.apache.tamaya.spi.ConfigurationContextBuilder; @@ -28,8 +27,15 @@ import org.apache.tamaya.spi.PropertySource; import org.apache.tamaya.spi.PropertyValue; import org.apache.tamaya.spi.PropertyValueCombinationPolicy; import org.apache.tamaya.spi.ServiceContextManager; - -import java.util.*; +import org.apache.tamaya.spisupport.PropertyConverterManager; +import org.apache.tamaya.spisupport.PropertySourceComparator; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.logging.Logger; @@ -86,13 +92,17 @@ public class DefaultConfigurationContext implements ConfigurationContext { this.propertyConverterManager.register(en.getKey(), converter); } } + LOG.info("Registered " + propertyConverterManager.getPropertyConverters().size() + " property converters: " + + propertyConverterManager.getPropertyConverters()); + propertyValueCombinationPolicy = builder.combinationPolicy; if(propertyValueCombinationPolicy==null){ propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().getService(PropertyValueCombinationPolicy.class); } if(propertyValueCombinationPolicy==null){ - propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_POLICY; + propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR; } + LOG.info("Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy); } @@ -114,14 +124,24 @@ public class DefaultConfigurationContext implements ConfigurationContext { @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof DefaultConfigurationContext)) return false; + if (this == o) { + return true; + } + if (!(o instanceof DefaultConfigurationContext)){ + return false; + } DefaultConfigurationContext that = (DefaultConfigurationContext) o; - if (!propertyConverterManager.equals(that.propertyConverterManager)) return false; - if (!immutablePropertySources.equals(that.immutablePropertySources)) return false; - if (!immutablePropertyFilters.equals(that.immutablePropertyFilters)) return false; + if (!propertyConverterManager.equals(that.propertyConverterManager)) { + return false; + } + if (!immutablePropertySources.equals(that.immutablePropertySources)) { + return false; + } + if (!immutablePropertyFilters.equals(that.immutablePropertyFilters)) { + return false; + } return getPropertyValueCombinationPolicy().equals(that.getPropertyValueCombinationPolicy()); } @@ -143,11 +163,12 @@ public class DefaultConfigurationContext implements ConfigurationContext { if(immutablePropertySources.isEmpty()){ b.append(" No property sources loaded.\n\n"); }else { - b.append(" CLASS NAME SCANNABLE SIZE STATE ERROR\n\n"); + b.append(" CLASS NAME ORDINAL SCANNABLE SIZE STATE ERROR\n\n"); for (PropertySource ps : immutablePropertySources) { b.append(" "); appendFormatted(b, ps.getClass().getSimpleName(), 30); appendFormatted(b, ps.getName(), 70); + appendFormatted(b, String.valueOf(PropertySourceComparator.getOrdinal(ps)), 8); appendFormatted(b, String.valueOf(ps.isScannable()), 10); if (ps.isScannable()) { appendFormatted(b, String.valueOf(ps.getProperties().size()), 8); @@ -188,7 +209,7 @@ public class DefaultConfigurationContext implements ConfigurationContext { b.append(" -------------------\n"); b.append(" CLASS TYPE INFO\n\n"); for(Map.Entry<TypeLiteral<?>, List<PropertyConverter<?>>> converterEntry:getPropertyConverters().entrySet()){ - for(PropertyConverter<?> converter: converterEntry.getValue()){ + for(PropertyConverter converter: converterEntry.getValue()){ b.append(" "); appendFormatted(b, converter.getClass().getSimpleName(), 30); appendFormatted(b, converterEntry.getKey().getRawType().getSimpleName(), 30); @@ -197,7 +218,7 @@ public class DefaultConfigurationContext implements ConfigurationContext { } } b.append("\n\n"); - b.append(" PropertyValueCombinationPolicy: ").append(getPropertyValueCombinationPolicy().getClass().getName()).append('\n'); + b.append(" PropertyValueCombinationPolicy: " + getPropertyValueCombinationPolicy().getClass().getName()).append('\n'); b.append('}'); return b.toString(); } @@ -264,7 +285,7 @@ public class DefaultConfigurationContext implements ConfigurationContext { @Override public ConfigurationContextBuilder toBuilder() { - return ConfigurationProvider.getConfigurationContextBuilder().setContext(this); + return new DefaultConfigurationContextBuilder(this); } } http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java index 2ddade6..4cad87d 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java +++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java @@ -1,30 +1,24 @@ /* * 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 + * 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 + * 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. + * 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.core.internal; -import org.apache.tamaya.Configuration; import org.apache.tamaya.TypeLiteral; -import org.apache.tamaya.core.internal.converters.*; -import org.apache.tamaya.core.propertysource.CLIPropertySource; -import org.apache.tamaya.core.propertysource.EnvironmentPropertySource; -import org.apache.tamaya.core.propertysource.SystemPropertySource; -import org.apache.tamaya.core.propertysource.JavaConfigurationPropertySource; import org.apache.tamaya.spi.ConfigurationContext; import org.apache.tamaya.spi.ConfigurationContextBuilder; import org.apache.tamaya.spi.PropertyConverter; @@ -33,10 +27,14 @@ import org.apache.tamaya.spi.PropertySource; import org.apache.tamaya.spi.PropertySourceProvider; import org.apache.tamaya.spi.PropertyValueCombinationPolicy; import org.apache.tamaya.spi.ServiceContextManager; -import org.osgi.service.component.annotations.Component; +import org.apache.tamaya.core.internal.converters.*; +import org.apache.tamaya.spisupport.PropertySourceComparator; +import org.apache.tamaya.spisupport.propertysource.CLIPropertySource; +import org.apache.tamaya.spisupport.propertysource.EnvironmentPropertySource; +import org.apache.tamaya.spisupport.propertysource.JavaConfigurationPropertySource; +import org.apache.tamaya.spisupport.propertysource.SystemPropertySource; import java.io.File; -import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URI; @@ -46,9 +44,8 @@ import java.util.*; import java.util.logging.Logger; /** - * Default implementation of {@link org.apache.tamaya.spi.ConfigurationContextBuilder}. + * Default implementation of {@link ConfigurationContextBuilder}. */ -@Component(service = ConfigurationContextBuilder.class) public class DefaultConfigurationContextBuilder implements ConfigurationContextBuilder { private static final Logger LOG = Logger.getLogger(DefaultConfigurationContextBuilder.class.getName()); @@ -64,6 +61,8 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB */ private boolean built; + + /** * Creates a new builder instance. */ @@ -71,7 +70,7 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB } /** - * Creates a new builder instance. + * Creates a new builder instance initializing it with the given context. * @param context the context to be used, not null. */ public DefaultConfigurationContextBuilder(ConfigurationContext context) { @@ -101,6 +100,7 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB return this; } + @Override public ConfigurationContextBuilder setContext(ConfigurationContext context) { checkBuilderState(); @@ -134,7 +134,11 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB checkBuilderState(); List<PropertySource> propertySources = new ArrayList<>(); addCorePropertyResources(propertySources); - propertySources.addAll(ServiceContextManager.getServiceContext().getServices(PropertySource.class)); + for(PropertySource ps: ServiceContextManager.getServiceContext().getServices(PropertySource.class)) { + if(!propertySources.contains(ps)){ + propertySources.add(ps); + } + } for(PropertySourceProvider provider: ServiceContextManager.getServiceContext().getServices(PropertySourceProvider.class)){ propertySources.addAll(provider.getPropertySources()); @@ -144,10 +148,16 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB } private void addCorePropertyResources(List<PropertySource> propertySources) { - propertySources.add(new EnvironmentPropertySource()); - propertySources.add(new JavaConfigurationPropertySource()); - propertySources.add(new CLIPropertySource()); - propertySources.add(new SystemPropertySource()); + for(PropertySource ps: new PropertySource[]{ + new EnvironmentPropertySource(), + new JavaConfigurationPropertySource(), + new CLIPropertySource(), + new SystemPropertySource() + }){ + if(!propertySources.contains(ps)){ + propertySources.add(ps); + } + } } @Override @@ -159,8 +169,6 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB return this; } - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override public DefaultConfigurationContextBuilder addDefaultPropertyConverters() { checkBuilderState(); addCorePropertyConverters(); @@ -173,7 +181,7 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB } @SuppressWarnings("unchecked") - private void addCorePropertyConverters() { + protected void addCorePropertyConverters() { addPropertyConverters(TypeLiteral.<BigDecimal>of(BigDecimal.class), new BigDecimalConverter()); addPropertyConverters(TypeLiteral.<BigInteger>of(BigInteger.class), new BigIntegerConverter()); addPropertyConverters(TypeLiteral.<Boolean>of(Boolean.class), new BooleanConverter()); @@ -205,6 +213,15 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB return this; } + private PropertySource getPropertySource(String name) { + for(PropertySource ps:propertySources){ + if(ps.getName().equals(name)){ + return ps; + } + } + throw new IllegalArgumentException("No such PropertySource: "+name); + } + @Override public List<PropertySource> getPropertySources() { return this.propertySources; @@ -317,6 +334,7 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB return this; } + @Override public ConfigurationContextBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy combinationPolicy){ checkBuilderState(); @@ -324,8 +342,9 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB return this; } + @Override - public <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> type, @SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters){ + public <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> type, PropertyConverter<T>... propertyConverters){ checkBuilderState(); Objects.requireNonNull(type); Objects.requireNonNull(propertyConverters); @@ -338,7 +357,7 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB if (!converters.contains(propertyConverter)) { converters.add(propertyConverter); } else { - LOG.finer("Converter ignored, already registered: " + propertyConverter); + LOG.warning("Converter ignored, already registered: " + propertyConverter); } } return this; @@ -358,7 +377,7 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB if (!converters.contains(propertyConverter)) { converters.add(propertyConverter); } else { - LOG.finer("Converter ignored, already registered: " + propertyConverter); + LOG.warning("Converter ignored, already registered: " + propertyConverter); } } return this; @@ -366,20 +385,19 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB protected ConfigurationContextBuilder loadDefaults() { checkBuilderState(); - this.combinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_POLICY; + this.combinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR; addDefaultPropertySources(); addDefaultPropertyFilters(); addDefaultPropertyConverters(); return this; } - @SuppressWarnings("rawtypes") - private Map<TypeLiteral, Collection<PropertyConverter>> getDefaultPropertyConverters() { + + private Map<TypeLiteral, Collection<PropertyConverter>> getDefaultPropertyConverters() { Map<TypeLiteral, Collection<PropertyConverter>> result = new HashMap<>(); for (PropertyConverter conv : ServiceContextManager.getServiceContext().getServices( PropertyConverter.class)) { - Type type = TypeLiteral.getGenericInterfaceTypeParameters(conv.getClass(), PropertyConverter.class)[0]; - TypeLiteral target = TypeLiteral.of(type); + TypeLiteral target = TypeLiteral.of(TypeLiteral.of(conv.getClass()).getType()); Collection<PropertyConverter> convList = result.get(target); if (convList == null) { convList = new ArrayList<>(); @@ -390,10 +408,11 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB return result; } + /** * Builds a new configuration based on the configuration of this builder instance. * - * @return a new {@link Configuration configuration instance}, + * @return a new {@link org.apache.tamaya.Configuration configuration instance}, * never {@code null}. */ @Override http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationProvider.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationProvider.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationProvider.java index d7abf8b..dd73889 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationProvider.java +++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationProvider.java @@ -22,6 +22,7 @@ import org.apache.tamaya.Configuration; import org.apache.tamaya.spi.ConfigurationContext; import org.apache.tamaya.spi.ConfigurationContextBuilder; import org.apache.tamaya.spi.ConfigurationProviderSpi; +import org.apache.tamaya.spisupport.DefaultConfiguration; import org.osgi.service.component.annotations.Component; import java.util.Objects; http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java index 04377e2..372ae2a 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java +++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java @@ -20,6 +20,7 @@ package org.apache.tamaya.core.internal; import org.apache.tamaya.ConfigException; import org.apache.tamaya.spi.ServiceContext; +import org.apache.tamaya.spisupport.PriorityServiceComparator; import javax.annotation.Priority; import java.io.IOException; http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceLoader.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceLoader.java b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceLoader.java index 3bf0291..b973d5f 100644 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceLoader.java +++ b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceLoader.java @@ -26,6 +26,7 @@ import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; +import org.apache.tamaya.spisupport.PriorityServiceComparator; import org.osgi.framework.*; /** http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/internal/PriorityServiceComparator.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/PriorityServiceComparator.java b/code/core/src/main/java/org/apache/tamaya/core/internal/PriorityServiceComparator.java deleted file mode 100644 index 3b2ff5a..0000000 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/PriorityServiceComparator.java +++ /dev/null @@ -1,81 +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.core.internal; - -import javax.annotation.Priority; -import java.util.Comparator; - -/** - * Comparator implementation for ordering services loaded based on their increasing priority values. - */ -public class PriorityServiceComparator implements Comparator<Object> { - - private static final PriorityServiceComparator INSTANCE = new PriorityServiceComparator(); - - /** Singleton constructor. */ - private PriorityServiceComparator(){} - - /** - * Get the shared instance of the comparator. - * @return the shared instance, never null. - */ - public static PriorityServiceComparator getInstance(){ - return INSTANCE; - } - - @Override - public int compare(Object o1, Object o2) { - int prio = getPriority(o1) - getPriority(o2); - if (prio < 0) { - return 1; - } else if (prio > 0) { - return -1; - } else { - return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName()); - } - } - - /** - * Checks the given instance for a @Priority annotation. If present the annotation's value is evaluated. If no such - * annotation is present, a default priority {@code 1} is returned. - * - * @param o the instance, not {@code null}. - * @return a priority, by default 1. - */ - public static int getPriority(Object o) { - return getPriority(o.getClass()); - } - - /** - * Checks the given type optionally annotated with a @Priority. If present the annotation's value is evaluated. - * If no such annotation is present, a default priority {@code 1} is returned. - * - * @param type the type, not {@code null}. - * @return a priority, by default 1. - */ - @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(); - } - return prio; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java deleted file mode 100644 index eb5fa92..0000000 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java +++ /dev/null @@ -1,464 +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.core.internal; - -import org.apache.tamaya.ConfigException; -import org.apache.tamaya.TypeLiteral; -import org.apache.tamaya.core.internal.converters.EnumConverter; -import org.apache.tamaya.spi.ConversionContext; -import org.apache.tamaya.spi.PropertyConverter; -import org.apache.tamaya.spi.ServiceContextManager; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.Type; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Manager that deals with {@link org.apache.tamaya.spi.PropertyConverter} instances. - * This class is thread-safe. - */ -public class PropertyConverterManager { - /** - * The logger used. - */ - private static final Logger LOG = Logger.getLogger(PropertyConverterManager.class.getName()); - /** - * The registered converters. - */ - private final Map<TypeLiteral<?>, List<PropertyConverter<?>>> converters = new ConcurrentHashMap<>(); - /** - * The transitive converters. - */ - private final Map<TypeLiteral<?>, List<PropertyConverter<?>>> transitiveConverters = new ConcurrentHashMap<>(); - /** - * The lock used. - */ - private final ReadWriteLock lock = new ReentrantReadWriteLock(); - - private static final Comparator<Object> PRIORITY_COMPARATOR = new Comparator<Object>() { - - @Override - public int compare(Object o1, Object o2) { - int prio = DefaultServiceContext.getPriority(o1) - DefaultServiceContext.getPriority(o2); - if (prio < 0) { - return 1; - } else if (prio > 0) { - return -1; - } else { - return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName()); - } - } - }; - - /** - * Constructor. - */ - public PropertyConverterManager() { - this(false); - } - - public PropertyConverterManager(boolean init) { - if (init) { - initConverters(); - } - } - - /** - * Registers the default converters provided out of the box. - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected void initConverters() { - for ( PropertyConverter conv : ServiceContextManager.getServiceContext().getServices(PropertyConverter.class)) { - Type type = TypeLiteral.getGenericInterfaceTypeParameters(conv.getClass(), PropertyConverter.class)[0]; - register(TypeLiteral.of(type), conv); - } - } - - /** - * Registers a new converter instance. - * - * @param targetType the target type, not {@code null}. - * @param converter the converter, not {@code null}. - * @param <T> the type. - */ - @SuppressWarnings("unchecked") - public <T> void register(TypeLiteral<T> targetType, PropertyConverter<T> converter) { - Objects.requireNonNull(converter); - Lock writeLock = lock.writeLock(); - try { - writeLock.lock(); - List<PropertyConverter<?>> converters = List.class.cast(this.converters.get(targetType)); - if(converters!=null && converters.contains(converter)){ - return; - } - List<PropertyConverter<?>> newConverters = new ArrayList<>(); - if (converters != null) { - newConverters.addAll(converters); - } - if(!newConverters.contains(converter)) { - newConverters.add(converter); - } - Collections.sort(newConverters, PRIORITY_COMPARATOR); - this.converters.put(targetType, Collections.unmodifiableList(newConverters)); - // evaluate transitive closure for all inherited supertypes and implemented interfaces - // direct implemented interfaces - for (Class<?> ifaceType : targetType.getRawType().getInterfaces()) { - converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(ifaceType))); - newConverters = new ArrayList<>(); - if (converters != null) { - newConverters.addAll(converters); - } - newConverters.add(converter); - Collections.sort(newConverters, PRIORITY_COMPARATOR); - this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters)); - } - Class<?> superClass = targetType.getRawType().getSuperclass(); - while (superClass != null && !superClass.equals(Object.class)) { - converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(superClass))); - newConverters = new ArrayList<>(); - if (converters != null) { - newConverters.addAll(converters); - } - newConverters.add(converter); - Collections.sort(newConverters, PRIORITY_COMPARATOR); - this.transitiveConverters.put(TypeLiteral.of(superClass), Collections.unmodifiableList(newConverters)); - for (Class<?> ifaceType : superClass.getInterfaces()) { - converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(ifaceType))); - newConverters = new ArrayList<>(); - if (converters != null) { - newConverters.addAll(converters); - } - newConverters.add(converter); - Collections.sort(newConverters, PRIORITY_COMPARATOR); - this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters)); - } - superClass = superClass.getSuperclass(); - } - } finally { - writeLock.unlock(); - } - } - - /** - * Allows to evaluate if a given target type is supported. - * - * @param targetType the target type, not {@code null}. - * @return true, if a converter for the given type is registered, or a default one can be created. - */ - public boolean isTargetTypeSupported(TypeLiteral<?> targetType) { - return converters.containsKey(targetType) || transitiveConverters.containsKey(targetType) || createDefaultPropertyConverter(targetType) != null; - } - - /** - * Get a map of all property converters currently registered. This will not contain the converters that - * may be created, when an instance is adapted, which provides a String constructor or compatible - * factory methods taking a single String instance. - * - * @return the current map of instantiated and registered converters. - * @see #createDefaultPropertyConverter(org.apache.tamaya.TypeLiteral) - */ - public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() { - Lock readLock = lock.readLock(); - try { - readLock.lock(); - return new HashMap<>(this.converters); - } finally { - readLock.unlock(); - } - } - - /** - * Get the list of all current registered converters for the given target type. - * If not converters are registered, they component tries to create and register a dynamic - * converter 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> - * <li>The target type of each explicitly registered converter also can be transitively mapped to - * 1) all directly implemented interfaces, 2) all its superclasses (except Object), 3) all the interfaces - * implemented by its superclasses. These groups of transitive converters is returned similarly in the - * order as mentioned, whereas also here a priority based decreasing ordering is applied.</li> - * <li>java.lang wrapper classes and native types are automatically mapped.</li> - * <li>If no explicit converters are registered, for Enum types a default implementation is provided that - * compares the configuration values with the different enum members defined (cases sensitive mapping).</li> - * </ul> - * <p> - * So given that list above directly registered mappings always are 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). - * @see #createDefaultPropertyConverter(org.apache.tamaya.TypeLiteral) - */ - @SuppressWarnings("unchecked") - public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) { - Lock readLock = lock.readLock(); - List<PropertyConverter<T>> converterList = new ArrayList<>(); - // direct mapped converters - try { - readLock.lock(); - addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList); - addConvertersToList(List.class.cast(this.transitiveConverters.get(targetType)), converterList); - } finally { - readLock.unlock(); - } - // handling of java.lang wrapper classes - TypeLiteral<T> boxedType = mapBoxedType(targetType); - if (boxedType != null) { - try { - readLock.lock(); - addConvertersToList(List.class.cast(this.converters.get(boxedType)), 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); - if (defaultConverter != null) { - register(targetType, defaultConverter); - try { - readLock.lock(); - addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList); - } finally { - readLock.unlock(); - } - } - } - // check for parametrized types, ignoring param type - // direct mapped converters - if(targetType.getType()!=null) { - try { - readLock.lock(); - addConvertersToList(List.class.cast(this.converters.get( - TypeLiteral.of(targetType.getRawType()))), converterList); - } finally { - readLock.unlock(); - } - } - return converterList; - } - - private <T> void addConvertersToList(Collection<PropertyConverter<T>> converters, List<PropertyConverter<T>> converterList) { - if (converters != null) { - for(PropertyConverter<T> conv:converters) { - if(!converterList.contains(conv)) { - converterList.add(conv); - } - } - } - } - - /** - * Maps native types to the corresponding boxed types. - * - * @param targetType the native type. - * @param <T> the type - * @return the boxed type, or null. - */ - @SuppressWarnings("unchecked") - private <T> TypeLiteral<T> mapBoxedType(TypeLiteral<T> targetType) { - Type parameterType = targetType.getType(); - if (parameterType == int.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Integer.class)); - } - if (parameterType == short.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Short.class)); - } - if (parameterType == byte.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Byte.class)); - } - if (parameterType == long.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Long.class)); - } - if (parameterType == boolean.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Boolean.class)); - } - if (parameterType == char.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Character.class)); - } - if (parameterType == float.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Float.class)); - } - if (parameterType == double.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Double.class)); - } - if (parameterType == int[].class) { - return TypeLiteral.class.cast(TypeLiteral.of(Integer[].class)); - } - if (parameterType == short[].class) { - return TypeLiteral.class.cast(TypeLiteral.of(Short[].class)); - } - if (parameterType == byte[].class) { - return TypeLiteral.class.cast(TypeLiteral.of(Byte[].class)); - } - if (parameterType == long[].class) { - return TypeLiteral.class.cast(TypeLiteral.of(Long[].class)); - } - if (parameterType == boolean.class) { - return TypeLiteral.class.cast(TypeLiteral.of(Boolean.class)); - } - if (parameterType == char[].class) { - return TypeLiteral.class.cast(TypeLiteral.of(Character[].class)); - } - if (parameterType == float[].class) { - return TypeLiteral.class.cast(TypeLiteral.of(Float[].class)); - } - if (parameterType == double[].class) { - return TypeLiteral.class.cast(TypeLiteral.of(Double[].class)); - } - return null; - } - - /** - * Creates a dynamic PropertyConverter for the given target type. - * - * @param targetType the target type - * @param <T> the type class - * @return a new converter, or null. - */ - protected <T> PropertyConverter<T> createDefaultPropertyConverter(final TypeLiteral<T> targetType) { - if (Enum.class.isAssignableFrom(targetType.getRawType())) { - return new EnumConverter<>(targetType.getRawType()); - } - PropertyConverter<T> converter = null; - final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "valueOf", "instanceOf", "getInstance", "from", "fromString", "parse"); - if (factoryMethod != null) { - converter = new DefaultPropertyConverter<>(factoryMethod, targetType.getRawType()); - } - if (converter == null) { - final 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; - } - 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; - } - }); - return null; - } - }); - try { - return constr.newInstance(value); - } catch (Exception e) { - LOG.log(Level.SEVERE, "Error creating new PropertyConverter instance " + targetType, e); - } - return null; - } - }; - } - return converter; - } - - /** - * Tries to evaluate a factory method that can be used to create an instance based on a String. - * - * @param type the target type - * @param methodNames the possible static method names - * @return the first method found, or null. - */ - private Method getFactoryMethod(Class<?> type, String... methodNames) { - Method m; - for (String name : methodNames) { - try { - m = type.getDeclaredMethod(name, String.class); - return m; - } catch (NoSuchMethodException | RuntimeException e) { - LOG.finest("No such factory method found on type: " + type.getName() + ", methodName: " + name); - } - } - return null; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof PropertyConverterManager)) return false; - - PropertyConverterManager that = (PropertyConverterManager) o; - - return converters.equals(that.converters); - } - - @Override - public int hashCode() { - return converters.hashCode(); - } - - private static class DefaultPropertyConverter<T> implements PropertyConverter<T> { - - private final Method factoryMethod; - private final Class<T> targetType; - - DefaultPropertyConverter(Method factoryMethod, Class<T> targetType){ - this.factoryMethod = Objects.requireNonNull(factoryMethod); - this.targetType = Objects.requireNonNull(targetType); - } - - @Override - public T convert(String value, ConversionContext context) { - context.addSupportedFormats(getClass(), "<String -> "+factoryMethod.toGenericString()); - - if (!Modifier.isStatic(factoryMethod.getModifiers())) { - throw new ConfigException(factoryMethod.toGenericString() + - " is not a static method. Only static methods can be used as factory methods."); - } - try { - AccessController.doPrivileged(new PrivilegedAction<Object>() { - @Override - public Object run() { - factoryMethod.setAccessible(true); - return null; - } - }); - Object invoke = factoryMethod.invoke(null, value); - return targetType.cast(invoke); - } catch (Exception e) { - throw new ConfigException("Failed to decode '" + value + "'", e); - } - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFilterComparator.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFilterComparator.java b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFilterComparator.java deleted file mode 100644 index 96779df..0000000 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFilterComparator.java +++ /dev/null @@ -1,73 +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.core.internal; - -import org.apache.tamaya.spi.PropertyFilter; - -import javax.annotation.Priority; -import java.io.Serializable; -import java.util.Comparator; - -/** - * Comparator for PropertyFilters based on their priority annotations. - */ -public class PropertyFilterComparator implements Comparator<PropertyFilter>, Serializable { - - private static final long serialVersionUID = 1L; - - private static final PropertyFilterComparator INSTANCE = new PropertyFilterComparator(); - - /** Singleton constructor. */ - private PropertyFilterComparator(){} - - /** - * Get the shared instance of the comparator. - * @return the shared instance, never null. - */ - public static PropertyFilterComparator getInstance(){ - return INSTANCE; - } - - /** - * Compare 2 filters for ordering the filter chain. - * - * @param filter1 the first filter - * @param filter2 the second filter - * @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; - - if (ord1 < ord2) { - return -1; - } else if (ord1 > ord2) { - return 1; - } else { - return filter1.getClass().getName().compareTo(filter2.getClass().getName()); - } - } - - @Override - public int compare(PropertyFilter filter1, PropertyFilter filter2) { - return comparePropertyFilters(filter1, filter2); - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java deleted file mode 100644 index 16ff457..0000000 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java +++ /dev/null @@ -1,125 +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.core.internal; - -import org.apache.tamaya.spi.ConfigurationContext; -import org.apache.tamaya.spi.FilterContext; -import org.apache.tamaya.spi.PropertyFilter; -import org.apache.tamaya.spi.PropertySource; -import org.apache.tamaya.spi.PropertyValue; - -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Implementation of the Configuration API. This class uses the current {@link ConfigurationContext} to evaluate the - * chain of {@link PropertySource} and {@link PropertyFilter} - * instance to evaluate the current Configuration. - */ -public final class PropertyFiltering{ - /** - * The logger. - */ - private static final Logger LOG = Logger.getLogger(PropertyFiltering.class.getName()); - - /** - * The maximal number of filter cycles performed before aborting. - */ - private static final int MAX_FILTER_LOOPS = 10; - - /** - * Private singleton constructor. - */ - private PropertyFiltering(){} - - /** - * Filters a single value. - * @param value the raw value, not {@code null}. - * @param context the context - * @return the filtered value, including {@code null}. - */ - public static PropertyValue applyFilter(PropertyValue value, ConfigurationContext context) { - FilterContext filterContext = new FilterContext(value, context); - return filterValue(filterContext); - } - - /** - * Filters all properties. - * @param rawProperties the unfiltered properties, not {@code null}. - * @param context the context - * @return the filtered value, inclusing null. - */ - public static Map<String, PropertyValue> applyFilters(Map<String, PropertyValue> rawProperties, ConfigurationContext context) { - Map<String, PropertyValue> result = new HashMap<>(); - // Apply filters to values, prevent values filtered to null! - for (Map.Entry<String, PropertyValue> entry : rawProperties.entrySet()) { - FilterContext filterContext = new FilterContext(entry.getValue(), rawProperties, context); - PropertyValue filtered = filterValue(filterContext); - if(filtered!=null){ - result.put(filtered.getKey(), filtered); - } - } - return result; - } - - /** - * Basic filter logic. - * @param context the filter context, not {@code null}. - * @return the filtered value. - */ - private static PropertyValue filterValue(FilterContext context) { - PropertyValue inputValue = context.getProperty(); - PropertyValue filteredValue = inputValue; - - for (int i = 0; i < MAX_FILTER_LOOPS; i++) { - int changes = 0; - for (PropertyFilter filter : context.getContext().getPropertyFilters()) { - filteredValue = filter.filterProperty(inputValue, context); - if (filteredValue != null && !filteredValue.equals(inputValue)) { - changes++; - LOG.finest("Filter - " + inputValue + " -> " + filteredValue + " by " + filter); - } - if(filteredValue==null){ - LOG.finest("Filter removed entry - " + inputValue + ": " + filter); - break; - }else{ - inputValue = filteredValue; - } - } - if (changes == 0) { - LOG.finest("Finishing filter loop, no changes detected."); - break; - } else if (filteredValue == null) { - break; - } else { - if (i == (MAX_FILTER_LOOPS - 1)) { - if (LOG.isLoggable(Level.WARNING)) { - LOG.warning("Maximal filter loop count reached, aborting filter evaluation after cycles: " + i); - } - } else { - LOG.finest("Repeating filter loop, changes detected: " + changes); - } - } - } - return filteredValue; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java deleted file mode 100644 index 20ca097..0000000 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java +++ /dev/null @@ -1,86 +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.core.internal; - -import org.apache.tamaya.spi.PropertySource; - -import javax.annotation.Priority; -import java.io.Serializable; -import java.util.Comparator; - -/** - * Comparator for ordering of PropertySources based on their ordinal method and class name. - */ -public class PropertySourceComparator implements Comparator<PropertySource>, Serializable { - - private static final long serialVersionUID = 1L; - - private static final PropertySourceComparator INSTANCE = new PropertySourceComparator(); - - /** Singleton constructor. */ - private PropertySourceComparator(){} - - /** - * Get the shared instance of the comparator. - * @return the shared instance, never null. - */ - public static PropertySourceComparator getInstance(){ - return INSTANCE; - } - - /** - * Order property source reversely, the most important comes first. - * - * @param source1 the first PropertySource - * @param source2 the second PropertySource - * @return the comparison result. - */ - private int comparePropertySources(PropertySource source1, PropertySource source2) { - if (getOrdinal(source1) < getOrdinal(source2)) { - return -1; - } else if (getOrdinal(source1) > getOrdinal(source2)) { - return 1; - } else { - return source1.getClass().getName().compareTo(source2.getClass().getName()); - } - } - - /** - * Evaluates an ordinal value from a {@link PropertySource}, Hereby 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 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. - */ - public static int getOrdinal(PropertySource propertySource) { - return propertySource.getOrdinal(); - } - - @Override - public int compare(PropertySource source1, PropertySource source2) { - return comparePropertySources(source1, source2); - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/internal/ReflectionUtil.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/ReflectionUtil.java b/code/core/src/main/java/org/apache/tamaya/core/internal/ReflectionUtil.java deleted file mode 100644 index 6c7a1d2..0000000 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/ReflectionUtil.java +++ /dev/null @@ -1,42 +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.core.internal; - -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; - - -/** - * Small utility class used by other parts. - */ -public final class ReflectionUtil { - - private ReflectionUtil(){} - - public static ParameterizedType getParametrizedType(Class<?> clazz) { - Type[] genericTypes = clazz.getGenericInterfaces(); - for (Type type : genericTypes) { - if (type instanceof ParameterizedType) { - return (ParameterizedType) type; - } - - } - return null; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/main/java/org/apache/tamaya/core/internal/WrappedPropertySource.java ---------------------------------------------------------------------- diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/WrappedPropertySource.java b/code/core/src/main/java/org/apache/tamaya/core/internal/WrappedPropertySource.java deleted file mode 100644 index 34f4361..0000000 --- a/code/core/src/main/java/org/apache/tamaya/core/internal/WrappedPropertySource.java +++ /dev/null @@ -1,125 +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.core.internal; - -import org.apache.tamaya.spi.PropertySource; -import org.apache.tamaya.spi.PropertyValue; - -import java.util.Map; -import java.util.Objects; - -/** - * Property source effectively managed by the configuration context, allowing resetting of ordinal and its - * delegate (e.g. in case of refresh). - */ -class WrappedPropertySource implements PropertySource{ - - private Integer ordinal; - private PropertySource delegate; - private long loaded = System.currentTimeMillis(); - - private WrappedPropertySource(PropertySource delegate) { - this(delegate, null); - } - - private WrappedPropertySource(PropertySource delegate, Integer ordinal) { - this.delegate = Objects.requireNonNull(delegate); - this.ordinal = ordinal; - } - - public static WrappedPropertySource of(PropertySource ps) { - if(ps instanceof WrappedPropertySource){ - return (WrappedPropertySource)ps; - } - return new WrappedPropertySource(ps); - } - - public static WrappedPropertySource of(PropertySource ps, Integer ordinal) { - if(ps instanceof WrappedPropertySource){ - return new WrappedPropertySource(((WrappedPropertySource)ps).getDelegate(), ordinal); - } - return new WrappedPropertySource(ps, ordinal); - } - - public int getOrdinal() { - if(this.ordinal!=null){ - return this.ordinal; - } - return PropertySourceComparator.getOrdinal(delegate); - } - - public void setOrdinal(Integer ordinal) { - this.ordinal = ordinal; - } - - public void setDelegate(PropertySource delegate) { - this.delegate = Objects.requireNonNull(delegate); - this.loaded = System.currentTimeMillis(); - } - - @Override - public String getName() { - return delegate.getName(); - } - - @Override - public PropertyValue get(String key) { - return delegate.get(key); - } - - @Override - public Map<String, PropertyValue> getProperties() { - return delegate.getProperties(); - } - - @Override - public boolean isScannable() { - return delegate.isScannable(); - } - - public PropertySource getDelegate() { - return delegate; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof WrappedPropertySource)) return false; - - WrappedPropertySource that = (WrappedPropertySource) o; - - return getDelegate().getName().equals(that.getDelegate().getName()); - } - - @Override - public int hashCode() { - return getDelegate().getName().hashCode(); - } - - @Override - public String toString() { - return "WrappedPropertySource{" + - "name=" + getName() + - ", ordinal=" + getOrdinal() + - ", scannable=" + isScannable() + - ", loadedAt=" + loaded + - ", delegate-class=" + delegate.getClass().getName() + - '}'; - } -}