Reimplemented (also simjplified) Tamaya core completely based on latest JSR API. Moved prior Tamaya API into compat module.
Signed-off-by: Anatole Tresch <anat...@apache.org> Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/d0e14ed7 Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/d0e14ed7 Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/d0e14ed7 Branch: refs/heads/configjsr Commit: d0e14ed705b464f3d15f3bae5979cc90df275dc9 Parents: 9bc56a3 Author: Anatole Tresch <anat...@apache.org> Authored: Sun Dec 10 23:06:52 2017 +0100 Committer: Anatole Tresch <anat...@apache.org> Committed: Sun Dec 10 23:06:53 2017 +0100 ---------------------------------------------------------------------- code/base/bnd.bnd | 31 ++ code/base/pom.xml | 91 ++++ code/compat/bnd.bnd | 34 ++ code/compat/pom.xml | 70 +++ .../java/org/apache/tamaya/ConfigException.java | 44 ++ .../java/org/apache/tamaya/ConfigOperator.java | 38 ++ .../java/org/apache/tamaya/ConfigQuery.java | 37 ++ .../java/org/apache/tamaya/Configuration.java | 180 +++++++ .../apache/tamaya/ConfigurationProvider.java | 138 ++++++ .../java/org/apache/tamaya/package-info.java | 23 + .../apache/tamaya/spi/ConfigurationBuilder.java | 347 ++++++++++++++ .../apache/tamaya/spi/ConfigurationContext.java | 172 +++++++ .../tamaya/spi/ConfigurationContextBuilder.java | 334 +++++++++++++ .../tamaya/spi/ConfigurationProviderSpi.java | 128 +++++ .../apache/tamaya/spi/ConversionContext.java | 266 +++++++++++ .../org/apache/tamaya/spi/FilterContext.java | 140 ++++++ .../apache/tamaya/spi/PropertyConverter.java | 44 ++ .../org/apache/tamaya/spi/PropertyFilter.java | 51 ++ .../org/apache/tamaya/spi/PropertySource.java | 174 +++++++ .../tamaya/spi/PropertySourceProvider.java | 61 +++ .../org/apache/tamaya/spi/PropertyValue.java | 232 +++++++++ .../apache/tamaya/spi/PropertyValueBuilder.java | 196 ++++++++ .../spi/PropertyValueCombinationPolicy.java | 71 +++ .../org/apache/tamaya/spi/package-info.java | 24 + .../tamaya/spisupport/ConfigValueEvaluator.java | 48 ++ .../spisupport/DefaultConfigValueEvaluator.java | 70 +++ .../tamaya/spisupport/DefaultConfiguration.java | 281 +++++++++++ .../spisupport/DefaultConfigurationBuilder.java | 239 ++++++++++ .../spisupport/DefaultConfigurationContext.java | 277 +++++++++++ .../DefaultConfigurationContextBuilder.java | 431 +++++++++++++++++ .../apache/tamaya/spisupport/EnumConverter.java | 39 ++ .../spisupport/PriorityServiceComparator.java | 84 ++++ .../spisupport/PropertyConverterManager.java | 472 +++++++++++++++++++ .../spisupport/PropertyFilterComparator.java | 72 +++ .../tamaya/spisupport/PropertyFiltering.java | 123 +++++ .../spisupport/PropertySourceComparator.java | 120 +++++ .../tamaya/spisupport/RegexPropertyFilter.java | 84 ++++ .../propertysource/BasePropertySource.java | 172 +++++++ .../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 + .../compat/src/main/resources/tamaya-banner.txt | 11 + .../org/apache/tamaya/ConfigExceptionTest.java | 45 ++ .../org/apache/tamaya/ConfigurationTest.java | 63 +++ .../org/apache/tamaya/TestConfiguration.java | 138 ++++++ .../tamaya/TestConfigurationProvider.java | 76 +++ .../java/org/apache/tamaya/TypeLiteralTest.java | 91 ++++ .../tamaya/spi/ConversionContextTest.java | 193 ++++++++ .../apache/tamaya/spi/FilterContextTest.java | 157 ++++++ .../tamaya/spi/ServiceContextManagerTest.java | 105 +++++ .../apache/tamaya/spi/ServiceContextTest.java | 128 +++++ .../apache/tamaya/spi/TestServiceContext.java | 120 +++++ .../tamaya/spisupport/RegexFilterTest.java | 75 +++ ...g.apache.tamaya.spi.ConfigurationProviderSpi | 19 + .../org.apache.tamaya.spi.ServiceContext | 19 + .../org/apache/tamaya/core/BannerManager.java | 163 +++++++ .../tamaya/core/OSGIServiceComparator.java | 70 +++ .../apache/tamaya/core/OSGIServiceContext.java | 187 ++++++++ .../apache/tamaya/core/OSGIServiceLoader.java | 254 ++++++++++ .../core/TamayaConfigProviderResolver.java | 92 ++++ .../core/converters/BigDecimalConverter.java | 78 +++ .../core/converters/BigIntegerConverter.java | 107 +++++ .../core/converters/BooleanConverter.java | 74 +++ .../tamaya/core/converters/ByteConverter.java | 84 ++++ .../tamaya/core/converters/CharConverter.java | 81 ++++ .../tamaya/core/converters/ClassConverter.java | 79 ++++ .../tamaya/core/converters/ConvertQuery.java | 81 ++++ .../core/converters/CurrencyConverter.java | 103 ++++ .../tamaya/core/converters/DoubleConverter.java | 94 ++++ .../core/converters/DurationConverter.java | 60 +++ .../tamaya/core/converters/FileConverter.java | 63 +++ .../tamaya/core/converters/FloatConverter.java | 94 ++++ .../core/converters/InstantConverter.java | 58 +++ .../core/converters/IntegerConverter.java | 87 ++++ .../core/converters/LocalDateConverter.java | 58 +++ .../core/converters/LocalDateTimeConverter.java | 58 +++ .../core/converters/LocalTimeConverter.java | 58 +++ .../tamaya/core/converters/LongConverter.java | 84 ++++ .../tamaya/core/converters/NumberConverter.java | 85 ++++ .../converters/OffsetDateTimeConverter.java | 58 +++ .../core/converters/OffsetTimeConverter.java | 58 +++ .../core/converters/OptionalConverter.java | 78 +++ .../tamaya/core/converters/PathConverter.java | 64 +++ .../tamaya/core/converters/ShortConverter.java | 85 ++++ .../core/converters/SupplierConverter.java | 70 +++ .../tamaya/core/converters/URIConverter.java | 63 +++ .../tamaya/core/converters/URLConverter.java | 63 +++ .../tamaya/core/converters/package-info.java | 23 + .../javax.config.spi.ConfigProviderResolver | 19 + .../services/javax.config.spi.ConfigSource | 22 + .../services/javax.config.spi.Converter | 44 ++ .../org.apache.tamaya.spi.ConfigValueEvaluator | 19 + code/core/src/main/resources/tamaya-banner.txt | 11 + .../apache/tamaya/core/BannerManagerTest.java | 89 ++++ .../apache/tamaya/core/ConfigBuilderTest.java | 94 ++++ .../tamaya/core/ConfigContextBuilderTest.java | 424 +++++++++++++++++ .../tamaya/core/ExtConfigBuilderTest.java | 447 ++++++++++++++++++ .../core/TamayaConfigProviderResolverTest.java | 69 +++ .../apache/tamaya/core/TestConfigSource.java | 67 +++ .../core/testdata/TestConfigNamesSource.java | 51 ++ .../apache/tamaya/core/testdata/TestFilter.java | 42 ++ .../core/testdata/TestRemovingFilter.java | 47 ++ .../resources/META-INF/javaconfig.properties | 22 + .../src/test/resources/META-INF/javaconfig.xml | 25 + .../services/javax.config.spi.ConfigSource | 21 + .../javax.config.spi.ConfigSourceProvider | 19 + .../services/javax.config.spi.Converter | 19 + .../services/org.apache.tamaya.spi.Filter | 20 + 116 files changed, 12809 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/base/bnd.bnd ---------------------------------------------------------------------- diff --git a/code/base/bnd.bnd b/code/base/bnd.bnd new file mode 100644 index 0000000..cc6472d --- /dev/null +++ b/code/base/bnd.bnd @@ -0,0 +1,31 @@ +-buildpath: \ + osgi.annotation; version=6.0.0,\ + osgi.core; version=6.0,\ + osgi.cmpn; version=6.0 + +-testpath: \ + ${junit} + +javac.source: 1.8 +javac.target: 1.8 + +Bundle-Version: ${version}.${tstamp} +Bundle-Name: Apache Tamaya - SPI Support +Bundle-SymbolicName: org.apache.tamaya.spisupport +Bundle-Description: Apacha Tamaya Config - SPI Support +Bundle-Category: Implementation +Bundle-Copyright: (C) Apache Foundation +Bundle-License: Apache Licence version 2 +Bundle-Vendor: Apache Software Foundation +Bundle-ContactAddress: dev-tam...@incubator.apache.org +Bundle-DocURL: http://tamaya.apache.org +Export-Package: \ + org.apache.tamaya.base,\ + org.apache.tamaya.base.configsource,\ + org.apache.tamaya.base.convert,\ + org.apache.tamaya.base.filter,\ + org.apache.tamaya.spi +Import-Package: \ + javax.config,\ + javax.config.spi,\ + javax.annotation http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/base/pom.xml ---------------------------------------------------------------------- diff --git a/code/base/pom.xml b/code/base/pom.xml new file mode 100644 index 0000000..dc16016 --- /dev/null +++ b/code/base/pom.xml @@ -0,0 +1,91 @@ +<!-- +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 current 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.tamaya</groupId> + <artifactId>tamaya-code</artifactId> + <version>0.4-incubating-SNAPSHOT</version> + </parent> + + <artifactId>tamaya-base</artifactId> + <name>Apache Tamaya JavaConfig SPI Base Support</name> + <description>Apache Tamaya Base Classes useful when implementing the JavaConfig SPI.</description> + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.apache.tamaya</groupId> + <artifactId>tamaya-spisupport</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-annotation_1.2_spec</artifactId> + <version>1.0-alpha-1</version> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + <scope>provided</scope> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.annotation</artifactId> + <scope>provided</scope> + <optional>true</optional> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>java-hamcrest</artifactId> + </dependency> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <!-- + ! See https://issues.apache.org/jira/browse/TAMAYA-318 + !--> + <groupId>org.pitest</groupId> + <artifactId>pitest-maven</artifactId> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + </plugins> + </build> + +</project> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/bnd.bnd ---------------------------------------------------------------------- diff --git a/code/compat/bnd.bnd b/code/compat/bnd.bnd new file mode 100644 index 0000000..0409b56 --- /dev/null +++ b/code/compat/bnd.bnd @@ -0,0 +1,34 @@ +-buildpath: \ + osgi.annotation; version=6.0.0,\ + osgi.core; version=6.0,\ + osgi.cmpn; version=6.0 + +-testpath: \ + ${junit} + +javac.source: 1.8 +javac.target: 1.8 + +Bundle-Version: ${version}.${tstamp} +Bundle-SymbolicName: org.apache.tamaya.compat +Bundle-Name: Apache Tamaya - API +Bundle-Description: Apacha Tamaya Configuration Java API +Bundle-Category: API +Bundle-Copyright: (C) Apache Foundation +Bundle-License: Apache Licence version 2 +Bundle-Vendor: Apache Software Foundation +Bundle-ContactAddress: dev-tam...@incubator.apache.org +Bundle-DocURL: http://tamaya.apache.org +Export-Package: \ + org.apache.tamaya,\ + org.apache.tamaya.spisupport,\ + org.apache.tamaya.spi,\ + org.apache.tamaya.spisupport.propertysource +Import-Package: \ + javax.config,\ + javax.config.spi,\ + org.apache.tamaya.base,\ + org.apache.tamaya.base.configsource,\ + org.apache.tamaya.base.convert,\ + org.apache.tamaya.base.filter,\ + org.apache.tamaya.spi http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/pom.xml ---------------------------------------------------------------------- diff --git a/code/compat/pom.xml b/code/compat/pom.xml new file mode 100644 index 0000000..c48131b --- /dev/null +++ b/code/compat/pom.xml @@ -0,0 +1,70 @@ +<!-- +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 current 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.tamaya</groupId> + <artifactId>tamaya-code</artifactId> + <version>0.4-incubating-SNAPSHOT</version> + </parent> + + <artifactId>tamaya-compat</artifactId> + <name>Apache Tamaya Compatibility API</name> + <packaging>jar</packaging> + + <description> + The compatibility API from former Tamaya versions. + </description> + + + <url>http://tamaya.incubator.apache.org</url> + + <dependencies> + <dependency> + <groupId>org.apache.tamaya</groupId> + <artifactId>tamaya-base</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>java-hamcrest</artifactId> + </dependency> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.annotation</artifactId> + <scope>provided</scope> + <optional>true</optional> + </dependency> + </dependencies> + +</project> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/ConfigException.java ---------------------------------------------------------------------- diff --git a/code/compat/src/main/java/org/apache/tamaya/ConfigException.java b/code/compat/src/main/java/org/apache/tamaya/ConfigException.java new file mode 100644 index 0000000..38b0801 --- /dev/null +++ b/code/compat/src/main/java/org/apache/tamaya/ConfigException.java @@ -0,0 +1,44 @@ +/* + * 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; + +/** + * Exception class (runtime exception) for configuration issues. + */ +public class ConfigException extends RuntimeException{ + + private static final long serialVersionUID = -5886094818057522680L; + + /** + * Creates a new configuration exception. + * @param message the exception message, not {@code null}. + */ + public ConfigException(String message){ + super(message); + } + + /** + * Creates a new configuration exception. + * @param message the exception message, not {@code null}. + * @param t the throwable. + */ + public ConfigException(String message, Throwable t){ + super(message, t); + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/ConfigOperator.java ---------------------------------------------------------------------- diff --git a/code/compat/src/main/java/org/apache/tamaya/ConfigOperator.java b/code/compat/src/main/java/org/apache/tamaya/ConfigOperator.java new file mode 100644 index 0000000..b14c155 --- /dev/null +++ b/code/compat/src/main/java/org/apache/tamaya/ConfigOperator.java @@ -0,0 +1,38 @@ +/* + * 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; + +/** + * Models a function that maps a given {@link org.apache.tamaya.Configuration} to another {@link org.apache.tamaya.Configuration}. This can be used + * to modell additional functionality and applying it to a given {@link org.apache.tamaya.Configuration} instance by calling + * the {@link org.apache.tamaya.Configuration#with(org.apache.tamaya.ConfigOperator)} method. + */ +@FunctionalInterface +public interface ConfigOperator { + + /** + * Creates a new {@link org.apache.tamaya.Configuration} based on the given Configuration. Operators basically acts similar to + * decorators, whereas operated instances may have non compatible behaviour, e.g. by applying security constraints + * or view restrictions. + * + * @param config the input configuration, not {@code null}. + * @return the operated configuration, never {@code null}. + */ + Configuration operate(Configuration config); +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/ConfigQuery.java ---------------------------------------------------------------------- diff --git a/code/compat/src/main/java/org/apache/tamaya/ConfigQuery.java b/code/compat/src/main/java/org/apache/tamaya/ConfigQuery.java new file mode 100644 index 0000000..28b8b93 --- /dev/null +++ b/code/compat/src/main/java/org/apache/tamaya/ConfigQuery.java @@ -0,0 +1,37 @@ +/* + * 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; + +/** + * Models a function that maps a given {@link Configuration} to something else. This can be used + * to model additional functionality and applying it to a given {@link Configuration} instance by + * calling the {@link Configuration#query(ConfigQuery)} method. + */ +@FunctionalInterface +public interface ConfigQuery<T> { + + /** + * Creates a result based on the given Configuration. Queries basically acts similar to + * operators, whereas they returns any kind of result. + * + * @param config the input configuration, not {@code null}. + * @return the query result. + */ + T query(Configuration config); +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/Configuration.java ---------------------------------------------------------------------- diff --git a/code/compat/src/main/java/org/apache/tamaya/Configuration.java b/code/compat/src/main/java/org/apache/tamaya/Configuration.java new file mode 100644 index 0000000..3cf57f7 --- /dev/null +++ b/code/compat/src/main/java/org/apache/tamaya/Configuration.java @@ -0,0 +1,180 @@ +/* + * 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; + +import org.apache.tamaya.spi.ConfigurationBuilder; +import org.apache.tamaya.spi.ConfigurationContext; +import org.apache.tamaya.spi.TypeLiteral; + +import java.util.Map; + + +/** + * <p>A configuration models a aggregated set current properties, identified by + * a unique key, but adds higher level access functions to + * a {@link org.apache.tamaya.spi.PropertySource}. Hereby in most + * cases a configuration is a wrapper around a composite + * {@link org.apache.tamaya.spi.PropertySource} instance, which may combine + * multiple child config in well defined tree like structure, + * where nodes define logically the rules current priority, filtering, + * combination and overriding. + * </p> + * <h3>Implementation Requirements</h3> + * Implementations current this interface must be + * <ul> + * <li>Thread safe</li> + * <li>Immutable</li> + * </ul> + * + * <p>It is not recommended that implementations also are serializable, since the any configuration can be <i>frozen</i> + * by reading out its complete configuration map into a serializable and remotable structure. This helps significantly + * simplifying the development current this interface, e.g. for being backed up by systems and stores that are not part current + * this library at all.</p> + */ +public interface Configuration { + + /** + * Access a property. + * + * @param key the property's key, not {@code null}. + * @return the property's value. + */ + default String get(String key){ + return get(key, org.apache.tamaya.spi.TypeLiteral.of(String.class)); + } + + /** + * Access a property. + * + * @param key the property's key, not {@code null}. + * @param defaultValue value to be returned, if no value is present, not {@code null} + * @return the property's keys. + */ + default String getOrDefault(String key, String defaultValue){ + return getOrDefault(key, org.apache.tamaya.spi.TypeLiteral.of(String.class), defaultValue); + } + + /** + * Get the property keys as type T. This will implicitly require a corresponding {@link + * org.apache.tamaya.spi.PropertyConverter} to be available that is capable current providing type T + * fromMap the given String keys. + * + * @param <T> the type of the class modeled by the type parameter + * @param key the property's absolute, or relative path, e.g. @code + * a/b/c/d.myProperty}, not {@code null}. + * @param type The target type required, not {@code null}. + * @param defaultValue value to be used, if no value is present, not {@code null} + * @return the property value, never {@code null}. + * @throws ConfigException if the keys could not be converted to the required target type. + */ + default <T> T getOrDefault(String key, Class<T> type, T defaultValue){ + return getOrDefault(key, org.apache.tamaya.spi.TypeLiteral.of(type), defaultValue); + } + + /** + * Get the property keys as type T. This will implicitly require a corresponding {@link + * org.apache.tamaya.spi.PropertyConverter} to be available that is capable current providing type T + * fromMap the given String keys. + * + * @param <T> the type of the class modeled by the type parameter + * @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}. + * @return the property value, never {@code null}. + * @throws ConfigException if the keys could not be converted to the required target type. + */ + default <T> T get(String key, Class<T> type){ + return get(key, org.apache.tamaya.spi.TypeLiteral.of(type)); + } + + /** + * Get the property keys as type T. This will implicitly require a corresponding {@link + * org.apache.tamaya.spi.PropertyConverter} to be available that is capable current providing type T + * fromMap the given String keys. + * + * @param <T> the type of the type literal + * @param key the property's absolute, or relative path, e.g. @code + * a/b/c/d.myProperty}, not {@code null}. + * @param type The target type required, not {@code null}. + * @return the property value, never {@code null}. + * @throws ConfigException if the keys could not be converted to the required target type. + */ + <T> T get(String key, org.apache.tamaya.spi.TypeLiteral<T> type); + + /** + * Get the property keys as type T. This will implicitly require a corresponding {@link + * org.apache.tamaya.spi.PropertyConverter} to be available that is capable current providing type T + * fromMap the given String keys. + * + * @param <T> the type of the type literal + * @param key the property's absolute, or relative path, e.g. + * {@code a/b/c/d.myProperty}, not {@code null}. + * @param type The target type required, not {@code null}. + * @param defaultValue default value to be used, if no value is present. + * @return the property value, never null. + * @throws ConfigException if the keys could not be converted to the required target type. + */ + <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue); + + /** + * Access all currently known configuration properties as a full {@code Map<String,String>}. + * Be aware that entries from non scannable parts of the registered {@link org.apache.tamaya.spi.PropertySource} + * instances may not be contained in the result, but nevertheless be accessible calling one of the + * {@code get(...)} methods. + * @return all currently known configuration properties. + */ + Map<String,String> getProperties(); + + /** + * Extension point for adjusting configuration. + * + * @param operator A configuration operator, e.g. a filter, or an adjuster + * combining configurations, never {@code null}. + * @return the new adjusted configuration returned by the {@code operator}, never {@code null}. + */ + default Configuration with(ConfigOperator operator){ + return operator.operate(this); + } + + /** + * Query a configuration. + * + * @param <T> the type of the configuration. + * @param query the query, not {@code null}. + * @return the result returned by the {@code query}. + */ + default <T> T query(ConfigQuery<T> query){ + return query.query(this); + } + + /** + * Access a configuration's context. + * @return the configuration context, never null. + */ + ConfigurationContext getContext(); + + /** + * Create a new builder using this instance as it's base. + * @return a new builder, never null. + */ + default ConfigurationBuilder toBuilder() { + return ConfigurationProvider.getConfigurationBuilder().setConfiguration(this); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/ConfigurationProvider.java ---------------------------------------------------------------------- diff --git a/code/compat/src/main/java/org/apache/tamaya/ConfigurationProvider.java b/code/compat/src/main/java/org/apache/tamaya/ConfigurationProvider.java new file mode 100644 index 0000000..bacb944 --- /dev/null +++ b/code/compat/src/main/java/org/apache/tamaya/ConfigurationProvider.java @@ -0,0 +1,138 @@ +/* + * 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; + +import org.apache.tamaya.spi.*; + +import java.util.logging.Logger; + +/** + * Static access to the {@link Configuration} for the very application. + */ +public final class ConfigurationProvider { + + private static final Logger LOG = Logger.getLogger(ConfigurationProvider.class.getName()); + + private static ConfigurationProviderSpi spi() { + ConfigurationProviderSpi spi = ServiceContextManager.getServiceContext() + .getService(ConfigurationProviderSpi.class); + if(spi==null){ + throw new IllegalStateException("ConfigurationProviderSpi not available."); + } + return spi; + } + + private ConfigurationProvider() { + // just to prevent initialisation + } + + /** + * Access the current configuration. + * + * @return the corresponding Configuration instance, never {@code null}. + */ + public static Configuration getConfiguration() { + return spi().getConfiguration(); + } + + /** + * Creates a new configuration instance based on the given context. + * + * @param context the configuration context, not {@code null}. + * @return a new Configuration instance, never {@code null}. + */ + public static Configuration createConfiguration(ConfigurationContext context) { + return spi().createConfiguration(context); + } + + /** + * Get access to the current ConfigurationContext. + * + * @return the current ConfigurationContext, never null. + * @deprecated Use {@link Configuration#getContext()} instead of. + */ + @Deprecated + public static ConfigurationContext getConfigurationContext() { + return spi().getConfigurationContext(); + } + + /** + * This method allows to replace the current {@link org.apache.tamaya.spi.ConfigurationContext} with a new + * instance. This can be used to update the context with a new one, e.g. because some of the configuration + * data has changed and should be updated. It is the responsibility of the ConfigurationProvider to trigger + * corresponding update events for the current {@link org.apache.tamaya.Configuration}, so observing + * listeners can do whatever is appropriate to react to any given configuration changes. + * + * @param context the new ConfigurationContext to be applied. + * @throws java.lang.UnsupportedOperationException if the current provider is read-only and does not support + * applying a new ConfigurationContext. + * @deprecated Use #setConfiguration(Configuration) instead of. + */ + @Deprecated + public static void setConfigurationContext(ConfigurationContext context) { + spi().setConfigurationContext(context); + } + + /** + * This method allows to replace the current default {@link org.apache.tamaya.Configuration} with a new + * instance. It is the responsibility of the ConfigurationProvider to trigger + * corresponding update events for the current {@link org.apache.tamaya.Configuration}, so observing + * listeners can do whatever is appropriate to react to any given configuration change. + * + * @param config the new Configuration to be applied, not {@code null} + * @throws java.lang.UnsupportedOperationException if the current provider is read-only and + * does not support + * applying a new Configuration. + */ + public static void setConfiguration(Configuration config) { + LOG.info("TAMAYA Applying new Configuration: " + config); + spi().setConfiguration(config); + } + + /** + * Create a new {@link ConfigurationBuilder} instance. This method creates + * a new builder instance that is not related to any concrete {@link org.apache.tamaya.spi.ConfigurationContext}. + * You can use {@link #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)} to change the + * current configuration context. + * + * @return a new, empty {@link ConfigurationBuilder}, never null. + * @see #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext) + * @see org.apache.tamaya.spi.ConfigurationContext + * @deprecated Will be removed. + */ + @Deprecated + public static ConfigurationContextBuilder getConfigurationContextBuilder() { + return spi().getConfigurationContextBuilder(); + } + + /** + * Create a new {@link ConfigurationBuilder} instance. This method creates + * a new builder instance that is not related to any concrete {@link org.apache.tamaya.spi.ConfigurationContext}. + * You can use {@link #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)} to change the + * current configuration context. + * + * @return a new, empty {@link ConfigurationBuilder}, never null. + * @see #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext) + * @see org.apache.tamaya.spi.ConfigurationContext + */ + public static ConfigurationBuilder getConfigurationBuilder() { + return spi().getConfigurationBuilder(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/package-info.java ---------------------------------------------------------------------- diff --git a/code/compat/src/main/java/org/apache/tamaya/package-info.java b/code/compat/src/main/java/org/apache/tamaya/package-info.java new file mode 100644 index 0000000..486116a --- /dev/null +++ b/code/compat/src/main/java/org/apache/tamaya/package-info.java @@ -0,0 +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 + * + * 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. + */ + +/** + * This package contains the Apache Tamaya API. + */ +package org.apache.tamaya; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java ---------------------------------------------------------------------- diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java new file mode 100644 index 0000000..ac3e3b9 --- /dev/null +++ b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java @@ -0,0 +1,347 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tamaya.spi; + +import org.apache.tamaya.Configuration; + +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +/** + * A builder for creating new instance of {@link Configuration}. + * Builders can be obtained in exactly two ways: + * <ol> + * <li>By accessing a preinitialized builder from an existing {@link Configuration}, + * by calling {@link org.apache.tamaya.Configuration#toBuilder()}.</li> + * <li>By accessing an empty builder instance from + * {@link org.apache.tamaya.ConfigurationProvider#getConfigurationBuilder()}.</li> + * </ol> + * After all changes are applied to a builder a new {@link Configuration} instance can + * be created and can be applied by calling + * {@link #build()}}. + * + */ +public interface ConfigurationBuilder { + + /** + * Init this builder instance with the given {@link Configuration} instance. This + * method will use any existing property sources, filters, converters and the combination + * policy of the given {@link Configuration} and initialize the current builder + * with them. All previous property sources, filters, converters and the combination + * policy of this instance will be replaced. + * + * @param config the {@link Configuration} instance to be used, not {@code null}. + * @return this builder, for chaining, never null. + */ + ConfigurationBuilder setConfiguration(Configuration config); + + /** + * Init this builder instance with the given {@link ConfigurationContext} instance. This + * method will use any existing property sources, filters, converters and the combination + * policy of the given {@link ConfigurationContext} and initialize the current builder + * with them. All previous property sources, filters, converters and the combination + * policy of this instance will be replaced. + * + * @param context the {@link ConfigurationContext} instance to be used, not {@code null}. + * @return this builder, for chaining, never null. + */ + ConfigurationBuilder setContext(ConfigurationContext context); + + /** + * This method can be used for adding {@link PropertySource}s. + * Hereby the property source is added to the tail of property sources with + * lowest priority regardless of its current ordinal value. To sort the property + * sources based on their ordinals call {@link #sortPropertySources}. + * + * @param propertySources the PropertySources to add + * @return this builder, for chaining, never null. + * @throws IllegalArgumentException If a property source with a given name already + * exists. + */ + ConfigurationBuilder addPropertySources(PropertySource... propertySources); + + /** + * This method can be used for programmatically adding {@link PropertySource}s. + * Hereby the property source is added to the tail of property sources with + * lowest priority regardless of its current ordinal value. To sort the property + * sources based on their ordinals call {@link #sortPropertySources}. + * + * @param propertySources the PropertySources to add + * @return this builder, for chaining, never null. + * @throws IllegalArgumentException If a property source with a given name already + * exists. + */ + ConfigurationBuilder addPropertySources(Collection<PropertySource> propertySources); + + /** + * Add all registered (default) property sources to the context built. The sources are ordered + * based on their ordinal values and added to the chain of property sources with + * higher priority. + * @return this builder, for chaining, never null. + */ + ConfigurationBuilder addDefaultPropertySources(); + + /** + * Removes the given property sources, if existing. The existing order of property + * sources is preserved. + * + * @param propertySources the property sources to remove, not {@code null}. + * @return the builder for chaining. + */ + ConfigurationBuilder removePropertySources(PropertySource... propertySources); + + /** + * Removes the given property sources, if existing. The existing order of property + * sources is preserved. + * + * @param propertySources the property sources to remove, not {@code null}. + * @return the builder for chaining. + */ + ConfigurationBuilder removePropertySources(Collection<PropertySource> propertySources); + + /** + * Access the current chain of property sources. Items at the end of the list have + * precedence/more significance. + * + * @return the property source chain, never {@code null}. + */ + List<PropertySource> getPropertySources(); + + /** + * Access the current chain of property filters. Items at the end of the list have + * precedence/more significance. + * + * @return the property filter chain, never {@code null}. + */ + List<PropertyFilter> getPropertyFilters(); + + /** + * Access the current registered property converters. + * + * @return the current registered property converters. + */ + Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> getPropertyConverter(); + + /** + * Increases the priority of the given property source, by moving it towards the end + * of the chain of property sources. If the property source given is already at the end + * this method has no effect. This operation does not change any ordinal values. + * + * @param propertySource the property source to be incresed regarding its significance. + * @return the builder for chaining. + * @throws IllegalArgumentException If no such property source exists in the current + * chain. + */ + ConfigurationBuilder increasePriority(PropertySource propertySource); + + /** + * Decreases the priority of the given property source, by moving it towards the start + * of the chain of property sources. If the property source given is already the first + * this method has no effect. This operation does not change any ordinal values. + * + * @param propertySource the property source to be decresed regarding its significance. + * @return the builder for chaining. + * @throws IllegalArgumentException If no such property source exists in the current + * chain. + */ + ConfigurationBuilder decreasePriority(PropertySource propertySource); + + /** + * Increases the priority of the given property source to be maximal, by moving it to + * the tail of the of property source chain. If the property source given is + * already the last item this method has no effect. This operation does not change + * any ordinal values. + * + * @param propertySource the property source to be maximized regarding its significance. + * @return the builder for chaining. + * @throws IllegalArgumentException If no such property source exists in the current + * chain. + */ + ConfigurationBuilder highestPriority(PropertySource propertySource); + + /** + * Decreases the priority of the given property source to be minimal, by moving it to + * the start of the chain of property source chain. If the property source given is + * already the first item this method has no effect. This operation does not change + * any ordinal values. + * + * @param propertySource the property source to be minimized regarding its significance. + * @return the builder for chaining. + * @throws IllegalArgumentException If no such property source exists in the current + * chain. + */ + ConfigurationBuilder lowestPriority(PropertySource propertySource); + + /** + * Adds the given PropertyFilter instances, hereby the instances are added + * to the end of the list with highest priority. The ordering of existing + * property filters remains unchanged. To sort the property + * filters call {@link #sortPropertyFilter}. + * + * @param filters the filters to add + * @return this builder, for chaining, never null. + */ + ConfigurationBuilder addPropertyFilters(PropertyFilter... filters); + + /** + * Adds the given PropertyFilter instances, hereby the instances are added + * to the end of the list with highest priority. The ordering of existing + * property filters remains unchanged. To sort the property + * filters call {@link #sortPropertyFilter}. + * + * @param filters the filters to add + * @return this builder, for chaining, never null. + */ + ConfigurationBuilder addPropertyFilters(Collection<PropertyFilter> filters); + + /** + * Add all auto-discoverable property filters to the context built. + * @return this builder, for chaining, never null. + */ + ConfigurationBuilder addDefaultPropertyFilters(); + + + /** + * Removes the given PropertyFilter instances, if existing. The order of the remaining + * filters is preserved. + * + * @param filters the filter to remove + * @return this builder, for chaining, never null. + */ + ConfigurationBuilder removePropertyFilters(PropertyFilter... filters); + + /** + * Removes the given PropertyFilter instances, if existing. The order of the remaining + * filters is preserved. + * + * @param filters the filter to remove + * @return this builder, for chaining, never null. + */ + ConfigurationBuilder removePropertyFilters(Collection<PropertyFilter> filters); + + /** + * This method can be used for adding {@link PropertyConverter}s. + * Converters are added at the end after any existing converters. + * For converters already registered for the current target type the + * method has no effect. + * + * @param typeToConvert the type for which the converter is for + * @param propertyConverters the PropertyConverters to add for this type + * @param <T> the target type. + * @return this builder, for chaining, never null. + */ + <T> ConfigurationBuilder addPropertyConverters(TypeLiteral<T> typeToConvert, + @SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters); + + /** + * This method can be used for adding {@link PropertyConverter}s. + * Converters are added at the end after any existing converters. + * For converters already registered for the current target type the + * method has no effect. + * + * @param typeToConvert the type for which the converter is for + * @param propertyConverters the PropertyConverters to add for this type + * @param <T> the target type. + * @return this builder, for chaining, never null. + */ + <T> ConfigurationBuilder addPropertyConverters(TypeLiteral<T> typeToConvert, + Collection<PropertyConverter<T>> propertyConverters); + + /** + * Add all auto-discoverable property converters to the context built. + * @return this builder, for chaining, never null. + */ + ConfigurationBuilder addDefaultPropertyConverters(); + + /** + * Removes the given PropertyConverter instances for the given type, + * if existing. + * + * @param typeToConvert the type which the converter is for + * @param propertyConverters the converter to remove + * @param <T> the target type. + * @return this builder, for chaining, never null. + */ + <T> ConfigurationBuilder removePropertyConverters(TypeLiteral<T> typeToConvert, + @SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters); + + /** + * Removes the given PropertyConverter instances for the given type, + * if existing. + * + * @param typeToConvert the type which the converter is for + * @param propertyConverters the converter to remove + * @param <T> the target type. + * @return this builder, for chaining, never null. + */ + <T> ConfigurationBuilder removePropertyConverters(TypeLiteral<T> typeToConvert, + Collection<PropertyConverter<T>> propertyConverters); + + /** + * Removes all converters for the given type, which actually renders a given type + * unsupported for type conversion. + * + * @param typeToConvert the type which the converter is for + * @return this builder, for chaining, never null. + */ + ConfigurationBuilder removePropertyConverters(TypeLiteral<?> typeToConvert); + + /** + * Sorts the current registered property sources using the given comparator. + * + * NOTE: property sources at the beginning have minimal significance. + * + * @param comparator the comparator to be used, not {@code null}. + * @return this instance for chaining. + */ + ConfigurationBuilder sortPropertySources(Comparator<PropertySource> comparator); + + /** + * Sorts the current registered property filters using the given comparator. + * + * NOTE: property filters at the beginning have minimal significance. + * + * @param comparator the comparator to be used, not {@code null}. + * @return this instance for chaining. + */ + ConfigurationBuilder sortPropertyFilter(Comparator<PropertyFilter> comparator); + + /** + * Sets the {@link PropertyValueCombinationPolicy} used to evaluate the final + * property values. + * + * @param policy the {@link PropertyValueCombinationPolicy} used, not {@code null}. + * @return this builder, for chaining, never null. + */ + ConfigurationBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy); + + /** + * Builds a new {@link Configuration} based on the data in this builder. The ordering of property + * sources and property filters is not changed, regardless of their ordinals. For ensure a certain + * ordering/significance use {@link #sortPropertyFilter(Comparator)} and/or {@link #sortPropertySources(Comparator)} + * before building the context. + * + * @return the final configuration, never null. + */ + Configuration build(); + +} + http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java ---------------------------------------------------------------------- diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java new file mode 100644 index 0000000..43f7ea0 --- /dev/null +++ b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java @@ -0,0 +1,172 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tamaya.spi; + + +import java.util.List; +import java.util.Map; + +/** + * Central SPI for programmatically dealing with the setup of the configuration system. + * This includes adding and enlisting {@link org.apache.tamaya.spi.PropertySource}s, + * managing {@link PropertyConverter}s, ConfigFilters, etc. + */ +public interface ConfigurationContext { + + /** + * This method can be used for programmatically adding {@link PropertySource}s. + * It is not needed for normal 'usage' by end users, but only for Extension Developers! + * + * @param propertySources the PropertySources to add + * @deprecated Use {@link ConfigurationContextBuilder} to create a new {@link ConfigurationContext}. + * @see #toBuilder() + */ + @Deprecated + void addPropertySources(PropertySource... propertySources); + + /** + * This method returns the current list of registered PropertySources ordered via their ordinal. + * PropertySources with a lower ordinal come last. The PropertySource with the + * highest ordinal comes first. + * If two PropertySources have the same ordinal number they will get sorted + * using their class name just to ensure the user at least gets the same ordering + * after a JVM restart, hereby names before are added last. + * PropertySources are loaded when this method is called the first time, which basically is + * when the first time configuration is accessed. + * + * @return a sorted list of registered PropertySources. The returned list need not be modifiable + */ + List<PropertySource> getPropertySources(); + + /** + * Access a {@link PropertySource} using its (unique) name. + * @param name the propoerty source's name, not {@code null}. + * @return the propoerty source found, or {@code null}. + */ + PropertySource getPropertySource(String name); + + /** + * This method can be used for programmatically adding {@link PropertyConverter}s. + * It is not needed for normal 'usage' by end users, but only for Extension Developers! + * + * @param <T> the type of the type literal + * @param type the type which the converters is for + * @param propertyConverter the PropertyConverters to add for this type + * @deprecated Use {@link ConfigurationContextBuilder} to create a new {@link ConfigurationContext}. + * @see #toBuilder() + */ + @Deprecated + <T> void addPropertyConverter(TypeLiteral<T> type, PropertyConverter<T> propertyConverter); + + + /** + * <p> + * This method returns the Map of registered PropertyConverters + * per type. + * The List for each type is ordered via their {@link javax.annotation.Priority} and + * cladd name. + * </p> + * + * <p>A simplified scenario could be like:</p> + * <pre> + * { + * Date.class -> {StandardDateConverter, TimezoneDateConverter, MyCustomDateConverter } + * Boolean.class -> {StandardBooleanConverter, FrenchBooleanConverter} + * Integer.class -> {DynamicDefaultConverter} + * } + * </pre> + * + * @return map with sorted list of registered PropertySources per type. + */ + Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters(); + + /** + * <p> + * This method returns the registered PropertyConverters for a given type. + * The List for each type is ordered via their {@link javax.annotation.Priority}. + * </p> + * + * <p> + * PropertyConverters with a higher Priority come first. The PropertyConverter with the + * lowest Priority comes last. + * If two PropertyConverter have the same ordinal number they will get sorted + * using their class name just to ensure the user at least gets the same ordering + * after a JVM restart. + * </p> + * + * <p> + * Additionally if a PropertyProvider is accessed, which is not registered the implementation + * should try to figure out, if there could be a default implementation as follows:</p> + * <ol> + * <li>Look for static factory methods: {@code of(String), valueOf(String), getInstance(String), + * instanceOf(String), fomr(String)}</li> + * <li>Look for a matching constructor: {@code T(String)}.</li> + * </ol> + * + * <p> + * If a correspoding factory method or constructor could be found, a corresponding + * PropertyConverter should be created and registered automatically for the given + * type. + * </p> + * + * <p> The scenario could be like:</p> + * + * <pre> + * { + * Date.class -> {MyCustomDateConverter,StandardDateConverter, TimezoneDateConverter} + * Boolean.class -> {StandardBooleanConverter, FrenchBooleanConverter} + * Integer.class -> {DynamicDefaultConverter} + * } + * </pre> + * + * <p> + * The converters returned for a type should be used as a chain, whereas the result of the + * first converters that is able to convert the configured value, is taken as the chain's result. + * No more converters are called after a converters has successfully converted the input into + * the required target type. + * </p> + * + * @param <T> the type of the type literal + * @param type type of the desired converters + * @return a sorted list of registered PropertySources per type. + */ + <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> type); + + /** + * Access the current PropertyFilter instances. + * @return the list of registered PropertyFilters, never null. + */ + List<PropertyFilter> getPropertyFilters(); + + /** + * Access the {@link org.apache.tamaya.spi.PropertyValueCombinationPolicy} used to evaluate the final + * property values. + * @return the {@link org.apache.tamaya.spi.PropertyValueCombinationPolicy} used, never null. + */ + PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(); + + /** + * Creates a {@link ConfigurationContextBuilder} preinitialized with the data from this instance. + * @return a new builder instance, never null. + * @deprecated Will be removed. + */ + @Deprecated + ConfigurationContextBuilder toBuilder(); + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java ---------------------------------------------------------------------- diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java new file mode 100644 index 0000000..8e3f307 --- /dev/null +++ b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java @@ -0,0 +1,334 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tamaya.spi; + +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +/** + * A builder for creating new or adapting instances of {@link ConfigurationContext}. + * Builders can be obtained in exactly two ways: + * <ol> + * <li>By accessing a preinitialized builder from an existing {@link ConfigurationContext}, + * by calling {@link org.apache.tamaya.spi.ConfigurationContext#toBuilder()}.</li> + * <li>By accessing an empty builder instance from + * {@link org.apache.tamaya.ConfigurationProvider#getConfigurationContextBuilder()}.</li> + * </ol> + * After all changes are applied to a builder a new {@link ConfigurationContext} instance can + * be created and can be applied by calling + * {@link org.apache.tamaya.ConfigurationProvider#setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)}. + * @deprecated Use {@link ConfigurationBuilder} instead. + */ +@Deprecated +public interface ConfigurationContextBuilder { + + /** + * Init this builder instance with the given {@link ConfigurationContext} instance. This + * method will use any existing property sources, filters, converters and the combination + * policy of the given {@link ConfigurationContext} and initialize the current builder + * with them. + * + * @param context the {@link ConfigurationContext} instance to be used, not {@code null}. + * @return this builder, for chaining, never null. + */ + ConfigurationContextBuilder setContext(ConfigurationContext context); + + /** + * This method can be used for adding {@link PropertySource}s. + * Hereby the property source is added to the tail of property sources with + * lowest priority regardless of its current ordinal value. To sort the property + * sources based on their ordinals call {@link #sortPropertySources}. + * + * @param propertySources the PropertySources to add + * @return this builder, for chaining, never null. + * @throws IllegalArgumentException If a property source with a given name already + * exists. + */ + ConfigurationContextBuilder addPropertySources(PropertySource... propertySources); + + /** + * This method can be used for programmatically adding {@link PropertySource}s. + * Hereby the property source is added to the tail of property sources with + * lowest priority regardless of its current ordinal value. To sort the property + * sources based on their ordinals call {@link #sortPropertySources}. + * + * @param propertySources the PropertySources to add + * @return this builder, for chaining, never null. + * @throws IllegalArgumentException If a property source with a given name already + * exists. + */ + ConfigurationContextBuilder addPropertySources(Collection<PropertySource> propertySources); + + /** + * Add all registered (default) property sources to the context built. The sources are ordered + * based on their ordinal values and added to the chain of property sources with + * higher priority. + * @return this builder, for chaining, never null. + */ + ConfigurationContextBuilder addDefaultPropertySources(); + + /** + * Removes the given property sources, if existing. The existing order of property + * sources is preserved. + * + * @param propertySources the property sources to remove, not {@code null}. + * @return the builder for chaining. + */ + ConfigurationContextBuilder removePropertySources(PropertySource... propertySources); + + /** + * Removes the given property sources, if existing. The existing order of property + * sources is preserved. + * + * @param propertySources the property sources to remove, not {@code null}. + * @return the builder for chaining. + */ + ConfigurationContextBuilder removePropertySources(Collection<PropertySource> propertySources); + + /** + * Access the current chain of property sources. Items at the end of the list have + * precedence/more significance. + * + * @return the property source chain, never {@code null}. + */ + List<PropertySource> getPropertySources(); + + /** + * Access the current chain of property filters. Items at the end of the list have + * precedence/more significance. + * + * @return the property source chain, never {@code null}. + */ + List<PropertyFilter> getPropertyFilters(); + + /** + * Access the current registered property converters. + * + * @return the current registered property converters. + */ + Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> getPropertyConverter(); + + /** + * Increases the priority of the given property source, by moving it towards the end + * of the chain of property sources. If the property source given is already at the end + * this method has no effect. This operation does not change any ordinal values. + * + * @param propertySource the property source to be incresed regarding its significance. + * @return the builder for chaining. + * @throws IllegalArgumentException If no such property source exists in the current + * chain. + */ + ConfigurationContextBuilder increasePriority(PropertySource propertySource); + + /** + * Decreases the priority of the given property source, by moving it towards the start + * of the chain of property sources. If the property source given is already the first + * this method has no effect. This operation does not change any ordinal values. + * + * @param propertySource the property source to be decresed regarding its significance. + * @return the builder for chaining. + * @throws IllegalArgumentException If no such property source exists in the current + * chain. + */ + ConfigurationContextBuilder decreasePriority(PropertySource propertySource); + + /** + * Increases the priority of the given property source to be maximal, by moving it to + * the tail of the of property source chain. If the property source given is + * already the last item this method has no effect. This operation does not change + * any ordinal values. + * + * @param propertySource the property source to be maximized regarding its significance. + * @return the builder for chaining. + * @throws IllegalArgumentException If no such property source exists in the current + * chain. + */ + ConfigurationContextBuilder highestPriority(PropertySource propertySource); + + /** + * Decreases the priority of the given property source to be minimal, by moving it to + * the start of the chain of property source chain. If the property source given is + * already the first item this method has no effect. This operation does not change + * any ordinal values. + * + * @param propertySource the property source to be minimized regarding its significance. + * @return the builder for chaining. + * @throws IllegalArgumentException If no such property source exists in the current + * chain. + */ + ConfigurationContextBuilder lowestPriority(PropertySource propertySource); + + /** + * Adds the given PropertyFilter instances, hereby the instances are added + * to the end of the list with highest priority. The ordering of existing + * property filters remains unchanged. To sort the property + * filters call {@link #sortPropertyFilter}. + * + * @param filters the filters to add + * @return this builder, for chaining, never null. + */ + ConfigurationContextBuilder addPropertyFilters(PropertyFilter... filters); + + /** + * Adds the given PropertyFilter instances, hereby the instances are added + * to the end of the list with highest priority. The ordering of existing + * property filters remains unchanged. To sort the property + * filters call {@link #sortPropertyFilter}. + * + * @param filters the filters to add + * @return this builder, for chaining, never null. + */ + ConfigurationContextBuilder addPropertyFilters(Collection<PropertyFilter> filters); + + /** + * Add all registered (default) property filters to the context built. + * @return this builder, for chaining, never null. + */ + ConfigurationContextBuilder addDefaultPropertyFilters(); + + + /** + * Removes the given PropertyFilter instances, if existing. The order of the remaining + * filters is preserved. + * + * @param filters the filter to remove + * @return this builder, for chaining, never null. + */ + ConfigurationContextBuilder removePropertyFilters(PropertyFilter... filters); + + /** + * Removes the given PropertyFilter instances, if existing. The order of the remaining + * filters is preserved. + * + * @param filters the filter to remove + * @return this builder, for chaining, never null. + */ + ConfigurationContextBuilder removePropertyFilters(Collection<PropertyFilter> filters); + + /** + * This method can be used for adding {@link PropertyConverter}s. + * Converters are added at the end after any existing converters. + * For converters already registered for the current target type the + * method has no effect. + * + * @param typeToConvert the type for which the converters is for + * @param propertyConverters the PropertyConverters to add for this type + * @param <T> the target type. + * @return this builder, for chaining, never null. + */ + <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> typeToConvert, + @SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters); + + /** + * This method can be used for adding {@link PropertyConverter}s. + * Converters are added at the end after any existing converters. + * For converters already registered for the current target type the + * method has no effect. + * + * @param typeToConvert the type for which the converters is for + * @param propertyConverters the PropertyConverters to add for this type + * @param <T> the target type. + * @return this builder, for chaining, never null. + */ + <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> typeToConvert, + Collection<PropertyConverter<T>> propertyConverters); + + /** + * Add all registered (default) property converters to the context built. + * @return this builder, for chaining, never null. + */ + ConfigurationContextBuilder addDefaultPropertyConverters(); + + /** + * Removes the given PropertyConverter instances for the given type, + * if existing. + * + * @param typeToConvert the type which the converters is for + * @param propertyConverters the converters to remove + * @param <T> the target type. + * @return this builder, for chaining, never null. + */ + <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert, + @SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters); + + /** + * Removes the given PropertyConverter instances for the given type, + * if existing. + * + * @param typeToConvert the type which the converters is for + * @param propertyConverters the converters to remove + * @param <T> the target type. + * @return this builder, for chaining, never null. + */ + <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert, + Collection<PropertyConverter<T>> propertyConverters); + + /** + * Removes all converters for the given type, which actually renders a given type + * unsupported for type conversion. + * + * @param typeToConvert the type which the converters is for + * @return this builder, for chaining, never null. + */ + ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert); + + /** + * Sorts the current registered property sources using the given comparator. + * + * NOTE: property sources at the beginning have minimal significance. + * + * @param comparator the comparator to be used, not {@code null}. + * @return this instance for chaining. + */ + ConfigurationContextBuilder sortPropertySources(Comparator<PropertySource> comparator); + + /** + * Sorts the current registered property filters using the given comparator. + * + * NOTE: property filters at the beginning have minimal significance. + * + * @param comparator the comparator to be used, not {@code null}. + * @return this instance for chaining. + */ + ConfigurationContextBuilder sortPropertyFilter(Comparator<PropertyFilter> comparator); + + /** + * Sets the {@link PropertyValueCombinationPolicy} used to evaluate the final + * property values. + * + * @param policy the {@link PropertyValueCombinationPolicy} used, not {@code null}. + * @return this builder, for chaining, never null. + */ + ConfigurationContextBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy); + + /** + * Builds a new {@link ConfigurationContext} based on the data in this builder. The ordering of property + * sources and property filters is not changed, regardless of their ordinals. For ensure a certain + * ordering/significance call {@link #sortPropertyFilter(Comparator)} and/or {@link #sortPropertySources(Comparator)} + * before building the context. + * + * @return the final context to be used to create a configuration. + * @see org.apache.tamaya.ConfigurationProvider#createConfiguration(ConfigurationContext) + */ + ConfigurationContext build(); + +} + http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java ---------------------------------------------------------------------- diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java new file mode 100644 index 0000000..fb93ab4 --- /dev/null +++ b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tamaya.spi; + +import org.apache.tamaya.Configuration; + +/** + * SPI that must be implemented to provide the component that manages all {@link org.apache.tamaya.Configuration} + * instances in a system. In SE this may be a true singleton containing exact one {@link org.apache.tamaya.Configuration} + * instance, whereas in Java EE and other more complex environments instances may be returned depending the current + * runtime context. + */ +public interface ConfigurationProviderSpi { + + /** + * Access the current {@link org.apache.tamaya.Configuration}. + * + * @return the current {@link org.apache.tamaya.Configuration} instance, never null. + */ + Configuration getConfiguration(); + + /** + * Create a {@link Configuration} instance using the given context. The configuration + * created hereby must respect the artifacts provided by its context (property sources, + * filters, converters, policies etc), including their ordering and significance. + * @param context the context to be used, not {@code null}. + * @return the corresponding configuration instance. + */ + Configuration createConfiguration(ConfigurationContext context); + + /** + * Creates a new {@link org.apache.tamaya.spi.ConfigurationContextBuilder} instance. + * + * @return a new {@link org.apache.tamaya.spi.ConfigurationContextBuilder}, never null. + * @deprecated Will be removed + */ + @Deprecated + ConfigurationContextBuilder getConfigurationContextBuilder(); + + /** + * Creates a new {@link org.apache.tamaya.spi.ConfigurationBuilder} instance. + * + * @return a new {@link org.apache.tamaya.spi.ConfigurationBuilder}, never null. + */ + ConfigurationBuilder getConfigurationBuilder(); + + /** + * This method allows to replace the current {@link org.apache.tamaya.Configuration} with a new + * instance. This can be used to update the configuration with a new one, e.g. because some of the + * data has changed and must be updated. It is the responsibility of the ConfigurationProvider to trigger + * corresponding update events for the current {@link org.apache.tamaya.Configuration}. + * + * @param config the new Configuration to be applied. + * @throws java.lang.UnsupportedOperationException if the current provider is read-only. + */ + void setConfiguration(Configuration config); + + /** + * Method that allows to determine if a new {@link org.apache.tamaya.Configuration} can be applied + * programmatically. + * + * @return true, if {@link #setConfiguration(org.apache.tamaya.Configuration)} is supported + * by the current implementation. + * @see #setConfiguration(org.apache.tamaya.Configuration) + */ + default boolean isConfigurationSettable(){ + return true; + } + + /** + * Get access to the current {@link ConfigurationContext}. + * + * @return the current {@link ConfigurationContext}, never null. + * @deprecated Will be removed in favour of {@link Configuration#getContext()}. + */ + @Deprecated + default ConfigurationContext getConfigurationContext(){ + return getConfiguration().getContext(); + } + + /** + * This method allows to replace the current {@link org.apache.tamaya.spi.ConfigurationContext} with a new + * instance. This can be used to update the context with a new one, e.g. because some of the configuration + * data has changed and must be updated. It is the responsibility of the ConfigurationProvider to trigger + * corresponding update event for the current {@link org.apache.tamaya.spi.ConfigurationContext} or + * {@link org.apache.tamaya.Configuration}. + * + * @param context the new ConfigurationContext to be applied. + * @throws java.lang.UnsupportedOperationException if the current provider is read-only. + * @deprecated use {@link #setConfiguration(Configuration)} + */ + @Deprecated + default void setConfigurationContext(ConfigurationContext context){ + setConfiguration(createConfiguration(context)); + } + + /** + * Method that allows to determine if a new {@link org.apache.tamaya.spi.ConfigurationContext} can be applied + * programmatically. + * + * @return true, if {@link #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)} is supported + * by the current implementation. + * @see #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext) + * @deprecated use {@link #isConfigurationSettable()} + */ + @Deprecated + default boolean isConfigurationContextSettable(){ + return isConfigurationSettable(); + } + + +}