TAMAYA-320 Initial commit.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/67245331 Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/67245331 Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/67245331 Branch: refs/heads/master Commit: 67245331e77d25af9628d90fdd97fa96b00af1e3 Parents: 31bdbd2 Author: Anatole Tresch <[email protected]> Authored: Wed Nov 22 13:48:38 2017 +0100 Committer: Anatole Tresch <[email protected]> Committed: Wed Nov 22 13:48:38 2017 +0100 ---------------------------------------------------------------------- configjsr/bnd.bnd | 34 +++ configjsr/pom.xml | 167 +++++++++++++ .../org/apache/tamaya/jsr382/JavaConfig.java | 100 ++++++++ .../apache/tamaya/jsr382/JavaConfigAdapter.java | 182 ++++++++++++++ .../apache/tamaya/jsr382/JavaConfigBuilder.java | 136 ++++++++++ .../tamaya/jsr382/JavaConfigConverter.java | 49 ++++ .../jsr382/JavaConfigDefaultProperties.java | 33 +++ .../jsr382/JavaConfigProviderResolver.java | 82 +++++++ .../apache/tamaya/jsr382/JavaConfigSource.java | 78 ++++++ .../tamaya/jsr382/JavaConfigSourceProvider.java | 64 +++++ .../tamaya/jsr382/TamayaConfiguration.java | 93 +++++++ .../tamaya/jsr382/TamayaPropertyConverter.java | 47 ++++ .../tamaya/jsr382/TamayaPropertySource.java | 78 ++++++ .../jsr382/TamayaPropertySourceProvider.java | 55 +++++ .../tamaya/jsr382/cdi/BridgingConfigBean.java | 95 +++++++ .../tamaya/jsr382/cdi/ConfiguredField.java | 65 +++++ .../tamaya/jsr382/cdi/ConfiguredMethod.java | 65 +++++ .../tamaya/jsr382/cdi/ConfiguredType.java | 86 +++++++ .../jsr382/cdi/JavaConfigCDIExtension.java | 126 ++++++++++ .../cdi/JavaConfigConfigurationProducer.java | 153 ++++++++++++ .../converter/BooleanAsIntegerConverterFix.java | 61 +++++ .../jsr382/converter/ProviderConverter.java | 98 ++++++++ .../javax.config.spi.ConfigProviderResolver | 19 ++ .../javax.enterprise.inject.spi.Extension | 19 ++ .../org.apache.tamaya.spi.PropertyConverter | 20 ++ .../org.apache.tamaya.spi.PropertySource | 19 ++ configjsr/src/main/resources/beans.xml | 25 ++ .../tamaya/jsr382/BuildableConfigSource.java | 177 +++++++++++++ .../apache/tamaya/jsr382/ConfigSourceParis.java | 44 ++++ .../jsr382/ConfigSourceProviderMinsk.java | 31 +++ .../tamaya/jsr382/JavaConfigAdapterTest.java | 246 +++++++++++++++++++ .../jsr382/JavaConfigConfigBuilderTest.java | 126 ++++++++++ .../JavaConfigConfigProviderResolverTest.java | 72 ++++++ .../jsr382/JavaConfigConfigProviderTest.java | 62 +++++ .../JavaConfigConfigSourceProviderTest.java | 45 ++++ .../tamaya/jsr382/JavaConfigConfigTest.java | 95 +++++++ .../tamaya/jsr382/JavaConfigConverterTest.java | 41 ++++ .../jsr382/JavaConfigDefaultPropertiesTest.java | 31 +++ .../tamaya/jsr382/TamayaPropertySourceTest.java | 51 ++++ .../tamaya/jsr382/UppercaseConverter.java | 33 +++ .../jsr382/UppercasePropertyConverter.java | 35 +++ .../tck/TamayaConfigArchiveProcessor.java | 79 ++++++ .../jsr382/tck/TamayaConfigExtension.java | 36 +++ configjsr/src/test/resources/META-INF/beans.xml | 24 ++ .../META-INF/microprofile-config.properties | 105 ++++++++ ...eclipse.microprofile.config.spi.ConfigSource | 19 ++ ...microprofile.config.spi.ConfigSourceProvider | 19 ++ ....jboss.arquillian.core.spi.LoadableExtension | 19 ++ configjsr/src/test/resources/sampleconfig.yaml | 18 ++ configjsr/src/test/tck-suite.xml | 27 ++ 50 files changed, 3484 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/bnd.bnd ---------------------------------------------------------------------- diff --git a/configjsr/bnd.bnd b/configjsr/bnd.bnd new file mode 100644 index 0000000..6a9a25f --- /dev/null +++ b/configjsr/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-Name: Apache Tamaya - JSR 382 +Bundle-SymbolicName: org.apache.tamaya.jsr382 +Bundle-Description: Apacha Tamaya Config - JSR 382 Implementation +Bundle-Category: Implementation +Bundle-Copyright: (C) Apache Foundation +Bundle-License: Apache Licence version 2 +Bundle-Vendor: Apache Software Foundation +Bundle-ContactAddress: [email protected] +Bundle-DocURL: http://tamaya.apache.org +Export-Package: \ + org.apache.tamaya.jsr382,\ + org.apache.tamaya.jsr382.cdi,\ + org.apache.tamaya.jsr382.converter +Import-Package: \ + org.apache.tamaya,\ + org.apache.tamaya.spi,\ + javax.config +Export-Service: \ + org.apache.tamaya.spi.PropertyConverter,\ + org.apache.tamaya.spi.ProperySource,\ + javax.config.spi.ConfigProviderResolver,\ + javax.enterprise.inject.spi.Extension http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/pom.xml ---------------------------------------------------------------------- diff --git a/configjsr/pom.xml b/configjsr/pom.xml new file mode 100644 index 0000000..28e5619 --- /dev/null +++ b/configjsr/pom.xml @@ -0,0 +1,167 @@ +<!-- +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.ext</groupId> + <artifactId>tamaya-sandbox</artifactId> + <version>0.4-incubating-SNAPSHOT</version> + </parent> + + <artifactId>tamaya-jsr382</artifactId> + <name>Apache Tamaya Modules - JSR 382 Implementation</name> + <packaging>jar</packaging> + + <properties> + <jsr.version>1.0-SNAPSHOT</jsr.version> + <maven.compile.sourceLevel>1.8</maven.compile.sourceLevel> + <maven.compile.targetLevel>1.8</maven.compile.targetLevel> + <JavaConfig.config.version>1.1</JavaConfig.config.version> + <geronimo-atinject-1.0-spec.version>1.0</geronimo-atinject-1.0-spec.version> + <geronimo-jcdi-1.1-spec.version>1.0</geronimo-jcdi-1.1-spec.version> + <version.shrinkwrap.resolvers>2.2.6</version.shrinkwrap.resolvers> + <tamaya-version>0.4-incubating-SNAPSHOT</tamaya-version> + <arquillian.version>1.1.13.Final</arquillian.version> + <arquillian-weld-embedded.version>2.0.0.Beta5</arquillian-weld-embedded.version> + <cdi-api.version>2.0</cdi-api.version> + <weld.version>3.0.1.Final</weld.version> + <deltaspike.version>1.1.0</deltaspike.version> + <openejb.version>4.7.1</openejb.version> + </properties> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>java-hamcrest</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.tamaya</groupId> + <artifactId>tamaya-core</artifactId> + <version>${tamaya-version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.tamaya</groupId> + <artifactId>tamaya-api</artifactId> + <version>${tamaya-version}</version> + </dependency> + <dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-functions</artifactId> + <version>${tamaya-version}</version> + </dependency> + <dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-events</artifactId> + <version>${tamaya-version}</version> + </dependency> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + </dependency> + <dependency> + <groupId>javax.config</groupId> + <artifactId>javaconfig-api</artifactId> + <version>${jsr.version}</version> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + </dependency> + <dependency> + <groupId>javax.enterprise</groupId> + <artifactId>cdi-api</artifactId> + <version>${cdi-api.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.jboss.weld.se</groupId> + <artifactId>weld-se-shaded</artifactId> + <version>${weld.version}</version> + <scope>test</scope> + </dependency> + <!-- JavaConfig TCK support only --> + <dependency> + <groupId>org.jboss.arquillian.testng</groupId> + <artifactId>arquillian-testng-container</artifactId> + <version>${arquillian.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + <version>6.9.9</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.jboss.shrinkwrap.resolver</groupId> + <artifactId>shrinkwrap-resolver-depchain</artifactId> + <version>${version.shrinkwrap.resolvers}</version> + <scope>test</scope> + <type>pom</type> + </dependency> + </dependencies> + + <profiles> + <profile> + <id>TCK</id> + <activation> + <activeByDefault>false</activeByDefault> + </activation> + <dependencies> + <dependency> + <groupId>javax.config</groupId> + <artifactId>javaconfig-tck</artifactId> + <version>${jsr.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.jboss.arquillian.container</groupId> + <artifactId>arquillian-weld-embedded</artifactId> + <version>${arquillian-weld-embedded.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.20.1</version> + <configuration> + <suiteXmlFiles> + <suiteXmlFile>src/test/tck-suite.xml</suiteXmlFile> + </suiteXmlFiles> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfig.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfig.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfig.java new file mode 100644 index 0000000..a53dfc2 --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfig.java @@ -0,0 +1,100 @@ +/* + * 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.jsr382; + +import org.apache.tamaya.ConfigException; +import org.apache.tamaya.Configuration; +import org.apache.tamaya.events.FrozenConfiguration; +import org.apache.tamaya.spi.PropertySource; + +import javax.config.Config; +import javax.config.spi.ConfigSource; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.*; + +/** + * JavaConfig {@link javax.config.spi.ConfigSource} implementation that wraps a {@link PropertySource} instance. + */ +public class JavaConfig implements Config, Serializable { + + private Configuration delegate; + + public JavaConfig(Configuration delegate){ + this.delegate = Objects.requireNonNull(delegate); + } + + public Configuration getConfiguration(){ + return this.delegate; + } + + + @Override + public <T> T getValue(String propertyName, Class<T> propertyType) { + T value = null; + try{ + value = delegate.get(propertyName, propertyType); + }catch(ConfigException e){ + if(e.toString().contains("Unparseable")){ + throw new IllegalArgumentException("Invalid type: " + propertyType.getName()); + } + } + if(value == null){ + throw new NoSuchElementException("No such config property: " + propertyName); + } + return value; + } + + @Override + public <T> Optional<T> getOptionalValue(String propertyName, Class<T> propertyType) { + return Optional.ofNullable(delegate.get(propertyName, propertyType)); + } + + @Override + public Iterable<String> getPropertyNames() { + return delegate.getProperties().keySet(); + } + + @Override + public Iterable<ConfigSource> getConfigSources() { + return JavaConfigAdapter.toConfigSources(delegate.getContext().getPropertySources()); + } + + @Override + public String toString() { + return "JavaConfigConfig{" + + "delegate=" + delegate + + '}'; + } + + private void writeObject(ObjectOutputStream out) throws IOException{ + if(!(this.delegate instanceof Serializable)){ + out.writeObject(FrozenConfiguration.of(this.delegate)); + }else { + out.writeObject(this.delegate); + } + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{ + this.delegate = (Configuration)in.readObject(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigAdapter.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigAdapter.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigAdapter.java new file mode 100644 index 0000000..6641dc0 --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigAdapter.java @@ -0,0 +1,182 @@ +/* + * 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.jsr382; + + +import org.apache.tamaya.*; +import org.apache.tamaya.spi.*; + +import javax.config.Config; +import javax.config.spi.ConfigBuilder; +import javax.config.spi.ConfigSource; +import javax.config.spi.Converter; +import java.util.*; + +/** + * Utility class for adapting JavaConfig artifacts into Tamaya artifacts and vice versa. + */ +public final class JavaConfigAdapter{ + + /** + * Singleton constructor. + */ + private JavaConfigAdapter(){} + + /** + * Converts a Tamaya {@link Configuration} into a JavaConfig.io {@link javax.config.Config}. + * @param config the Tamaya {@link Configuration} instance, not null. + * @return the corresponding JavaConfig.io {@link Config} instance, never null. + */ + public static Config toConfig(Configuration config){ + if(config instanceof TamayaConfiguration){ + return ((TamayaConfiguration)config).getConfig(); + } + return new JavaConfig(config); + } + + /** + * Converts a JavaConfig {@link Config}s into Tamaya {@link Configuration}s. + * @param config the JavaConfig {@link Config} instance, not null. + * @return the corresponding Tamaya {@link Configuration} instance, never null. + */ + public static Configuration toConfiguration(Config config){ + if(config instanceof JavaConfig){ + return ((JavaConfig)config).getConfiguration(); + } + return new TamayaConfiguration(config); + } + + /** + * Converts a Tamaya {@link PropertySource}s into a JavaConfig.io {@link ConfigSource}. + * @param propertySources the Tamaya {@link PropertySource} instances, not null. + * @return the corresponding JavaConfig.io {@link ConfigSource} instance, never null. + */ + public static List<ConfigSource> toConfigSources(Iterable<PropertySource> propertySources) { + List<ConfigSource> configSources = new ArrayList<>(); + for(PropertySource ps:propertySources){ + configSources.add(toConfigSource(ps)); + } + Collections.reverse(configSources); + return configSources; + } + + /** + * Converts a JavaConfig {@link ConfigSource}s into Tamaya {@link PropertySource}s. + * @param configSources the JavaConfig {@link ConfigSource} instances, not null. + * @return the corresponding Tamaya {@link PropertySource} instances, never null. + */ + public static List<PropertySource> toPropertySources(Iterable<ConfigSource> configSources) { + List<PropertySource> propertySources = new ArrayList<>(); + for(ConfigSource cs:configSources){ + propertySources.add(toPropertySource(cs)); + } + return propertySources; + } + + /** + * Converts a Tamaya {@link PropertySource} into a JavaConfig.io {@link ConfigSource}. + * @param propertySource the Tamaya {@link PropertySource} instance, not null. + * @return the corresponding JavaConfig.io {@link ConfigSource} instance, never null. + */ + public static ConfigSource toConfigSource(PropertySource propertySource) { + if(propertySource instanceof TamayaPropertySource){ + return ((TamayaPropertySource)propertySource).getConfigSource(); + } + return new JavaConfigSource(propertySource); + } + + /** + * Converts a JavaConfig {@link ConfigSource} into a Tamaya {@link PropertySource}. + * @param configSource the JavaConfig {@link ConfigSource} instance, not null. + * @return the corresponding Tamaya {@link PropertySource} instance, never null. + */ + public static PropertySource toPropertySource(ConfigSource configSource) { + if(configSource instanceof JavaConfigSource){ + return ((JavaConfigSource)configSource).getPropertySource(); + } + return new TamayaPropertySource(configSource); + } + + /** + * Converts a JavaConfig {@link Converter} into a Tamaya {@link PropertyConverter}. + * @param converter the JavaConfig {@link Converter} instance, not null. + * @param <T> the target type + * @return the corresponding Tamaya {@link PropertyConverter} instance, never null. + */ + public static <T> PropertyConverter<T> toPropertyConverter(Converter<T> converter) { + if(converter instanceof JavaConfigConverter){ + return ((JavaConfigConverter)converter).getPropertyConverter(); + } + return new TamayaPropertyConverter(converter); + } + + /** + * Converts a Tamaya {@link PropertyConverter} into a JavaConfig.io {@link Converter}. + * @param converter the Tamaya {@link PropertyConverter} instance, not null. + * @param <T> the target type + * @return the corresponding JavaConfig.io {@link Converter} instance, never null. + */ + public static <T> Converter<T> toConverter(PropertyConverter<T> converter) { + if(converter instanceof TamayaPropertyConverter){ + return ((TamayaPropertyConverter)converter).getConverter(); + } + return new JavaConfigConverter(converter); + } + + /** + * Converts a Tamaya {@link ConfigurationContextBuilder} into a JavaConfig.io {@link ConfigBuilder}. + * @param builder the Tamaya {@link ConfigurationContextBuilder} instance, not null. + * @return the corresponding JavaConfig.io {@link ConfigBuilder} instance, never null. + */ + public static ConfigBuilder toConfigBuilder(ConfigurationBuilder builder) { + return new JavaConfigBuilder(builder); + } + + /** + * Converts the given Tamaya key, value map into a corresponding String based map, hereby + * omitting all meta-entries. + * @param properties the Tamaya key, value map, not null. + * @return the corresponding String based map, never null. + */ + public static Map<String, String> toStringMap(Map<String, PropertyValue> properties) { + Map<String, String> valueMap = new HashMap<>(properties.size()); + for(Map.Entry<String,PropertyValue> en:properties.entrySet()){ + if(en.getValue().getValue()!=null) { + valueMap.put(en.getKey(), en.getValue().getValue()); + } + } + return valueMap; + } + + /** + * Converts the given String based key, value map into a corresponding String,PropertyValue + * based map. + * @param properties the String based key, value map, not null. + * @param source the source of the entries, not null. + * @return the corresponding String,PropertyValue based map, never null. + */ + public static Map<String, PropertyValue> toPropertyValueMap(Map<String, String> properties, String source) { + Map<String, PropertyValue> valueMap = new HashMap<>(properties.size()); + for(Map.Entry<String,String> en:properties.entrySet()){ + valueMap.put(en.getKey(), PropertyValue.of(en.getKey(), en.getValue(), source)); + } + return valueMap; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigBuilder.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigBuilder.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigBuilder.java new file mode 100644 index 0000000..f623d01 --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigBuilder.java @@ -0,0 +1,136 @@ +/* + * 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.jsr382; + +import org.apache.tamaya.TypeLiteral; +import org.apache.tamaya.spi.*; +import org.apache.tamaya.spisupport.PropertySourceComparator; +import org.apache.tamaya.spisupport.propertysource.EnvironmentPropertySource; +import org.apache.tamaya.spisupport.propertysource.SystemPropertySource; + +import javax.config.Config; +import javax.config.spi.ConfigBuilder; +import javax.config.spi.ConfigSource; +import javax.config.spi.ConfigSourceProvider; +import javax.config.spi.Converter; +import java.util.Objects; + +/** + * Created by atsticks on 23.03.17. + */ +final class JavaConfigBuilder implements ConfigBuilder{ + + private ConfigurationBuilder configBuilder; + private ClassLoader classLoader; + + JavaConfigBuilder(ConfigurationBuilder contextBuilder){ + this.configBuilder = Objects.requireNonNull(contextBuilder); + contextBuilder.addDefaultPropertyConverters(); + } + + public ConfigurationBuilder getConfigurationBuilder(){ + return configBuilder; + } + + /** + * Add the default config sources appearing on the builder's classpath + * including: + * <ol> + * <li>System properties</li> + * <li>Environment properties</li> + * <li>/META-INF/JavaConfig-config.properties</li> + * </ol> + * + * @return the ConfigBuilder with the default config sources + */ + @Override + public ConfigBuilder addDefaultSources() { + configBuilder.addPropertySources( + new SystemPropertySource(400), + new EnvironmentPropertySource(300), + new JavaConfigDefaultProperties()); + configBuilder.sortPropertySources(PropertySourceComparator.getInstance()); + return this; + } + + /** + * Add ConfigSources registered using the ServiceLoader. + * @return the ConfigBuilder with the added config sources + */ + @Override + public ConfigBuilder addDiscoveredSources() { + for(ConfigSource configSource: ServiceContextManager.getServiceContext().getServices(ConfigSource.class)){ + configBuilder.addPropertySources(JavaConfigAdapter.toPropertySource(configSource)); + } + for(ConfigSourceProvider configSourceProvider: ServiceContextManager.getServiceContext().getServices(ConfigSourceProvider.class)){ + configBuilder.addPropertySources(JavaConfigAdapter.toPropertySources(configSourceProvider.getConfigSources( + Thread.currentThread().getContextClassLoader() + ))); + } + configBuilder.sortPropertySources(PropertySourceComparator.getInstance()); + return this; + } + + /** + * Add Converters registered using the ServiceLoader. + * @return the ConfigBuilder with the added config converters + */ + @Override + public ConfigBuilder addDiscoveredConverters() { + for(Converter<?> converter: ServiceContextManager.getServiceContext().getServices(Converter.class)){ + TypeLiteral targetType = TypeLiteral.of( + TypeLiteral.getGenericInterfaceTypeParameters(converter.getClass(),Converter.class)[0]); + configBuilder.addPropertyConverters(targetType, + JavaConfigAdapter.toPropertyConverter(converter)); + } + return this; + } + + @Override + public ConfigBuilder forClassLoader(ClassLoader loader) { + this.classLoader = loader; + return this; + } + + @Override + public ConfigBuilder withSources(ConfigSource... sources) { + for(ConfigSource source:sources){ + configBuilder.addPropertySources(JavaConfigAdapter.toPropertySource(source)); + } + return this; + } + + @Override + public ConfigBuilder withConverters(Converter<?>... converters) { + for(Converter<?> converter:converters){ + TypeLiteral lit = TypeLiteral.of(converter.getClass()); + TypeLiteral target = TypeLiteral.of(lit.getType()); + configBuilder.removePropertyConverters(target); + configBuilder.addPropertyConverters( + target, + JavaConfigAdapter.toPropertyConverter(converter)); + } + return this; + } + + @Override + public Config build() { + return JavaConfigAdapter.toConfig(configBuilder.build()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigConverter.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigConverter.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigConverter.java new file mode 100644 index 0000000..0d33710 --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigConverter.java @@ -0,0 +1,49 @@ +/* + * 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.jsr382; + + +import org.apache.tamaya.TypeLiteral; +import org.apache.tamaya.spi.ConversionContext; +import org.apache.tamaya.spi.PropertyConverter; + +import javax.config.spi.Converter; +import java.util.Objects; + +/** + * Property source implementation that wraps a Java config {@link javax.config.spi.ConfigSource} instance. + */ +public class JavaConfigConverter<T> implements Converter<T> { + + private PropertyConverter<T> delegate; + + public JavaConfigConverter(PropertyConverter<T> delegate){ + this.delegate = Objects.requireNonNull(delegate); + } + + public PropertyConverter<T> getPropertyConverter(){ + return this.delegate; + } + + @Override + public T convert(String value) { + return delegate.convert(value, new ConversionContext.Builder("JavaConfig:no-key", TypeLiteral.of( + TypeLiteral.of(getClass()).getType())).build()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigDefaultProperties.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigDefaultProperties.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigDefaultProperties.java new file mode 100644 index 0000000..314911d --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigDefaultProperties.java @@ -0,0 +1,33 @@ +/* + * 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.jsr382; + +import org.apache.tamaya.spisupport.propertysource.PropertiesResourcePropertySource; + + +/** + * Default property source for config properties in the classpath. + */ +public class JavaConfigDefaultProperties extends PropertiesResourcePropertySource { + + public JavaConfigDefaultProperties() { + super("META-INF/javaconfig.properties", null); + setDefaultOrdinal(100); + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigProviderResolver.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigProviderResolver.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigProviderResolver.java new file mode 100644 index 0000000..88b1e0d --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigProviderResolver.java @@ -0,0 +1,82 @@ +/* + * 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.jsr382; + +import org.apache.tamaya.ConfigurationProvider; +import org.apache.tamaya.spi.ConfigurationBuilder; + +import javax.config.Config; +import javax.config.spi.ConfigBuilder; +import javax.config.spi.ConfigProviderResolver; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; + +/** + * Created by atsticks on 23.03.17. + */ +public class JavaConfigProviderResolver extends ConfigProviderResolver { + + private Map<ClassLoader, Config> configs = new ConcurrentHashMap<>(); + + @Override + public Config getConfig() { + return getConfig(Thread.currentThread().getContextClassLoader()); + } + + @Override + public Config getConfig(ClassLoader loader) { + Config config = this.configs.get(loader); + if(config==null){ + ConfigurationBuilder builder = ConfigurationProvider.getConfigurationBuilder(); + builder.addDefaultPropertyConverters(); + JavaConfigBuilder microConfigBuilder = new JavaConfigBuilder(builder); + microConfigBuilder.addDefaultSources(); + microConfigBuilder.addDiscoveredSources(); + config = microConfigBuilder.build(); + this.configs.put(loader, config); + } + return config; + } + + @Override + public ConfigBuilder getBuilder() { + return new JavaConfigBuilder(ConfigurationProvider.getConfigurationBuilder()); + } + + @Override + public void registerConfig(Config config, ClassLoader classLoader) { + if(configs.containsKey(classLoader)){ + Logger.getLogger(getClass().getName()) + .warning("Replacing existing config for classloader: " + classLoader); +// throw new IllegalArgumentException("Already a config registered with classloader: " + classLoader); + } + this.configs.put(classLoader, config); + } + + @Override + public void releaseConfig(Config config) { + for(Map.Entry<ClassLoader, Config> en: this.configs.entrySet()){ + if(en.getValue().equals(config)){ + this.configs.remove(en.getKey()); + return; + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigSource.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigSource.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigSource.java new file mode 100644 index 0000000..16bf7a9 --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigSource.java @@ -0,0 +1,78 @@ +/* + * 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.jsr382; + +import org.apache.tamaya.spi.PropertySource; +import org.apache.tamaya.spi.PropertyValue; + +import javax.config.spi.ConfigSource; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * Javaconfig {@link ConfigSource} implementation that wraps a {@link PropertySource} instance. + */ +public class JavaConfigSource implements ConfigSource{ + + private PropertySource delegate; + + public JavaConfigSource(PropertySource propertySource){ + this.delegate = Objects.requireNonNull(propertySource); + } + + public PropertySource getPropertySource(){ + return this.delegate; + } + + @Override + public int getOrdinal() { + return delegate.getOrdinal(); + } + + @Override + public String getName() { + return delegate.getName(); + } + + @Override + public String getValue(String key) { + PropertyValue value = delegate.get(key); + if(value!=null){ + return value.getValue(); + } + return null; + } + + @Override + public Map<String, String> getProperties() { + return toMap(delegate.getProperties()); + } + + private Map<String, String> toMap(Map<String, PropertyValue> properties) { + Map<String, String> valueMap = new HashMap<>(properties.size()); + for(Map.Entry<String,PropertyValue> en:properties.entrySet()){ + if(en.getValue().getValue()!=null) { + valueMap.put(en.getKey(), en.getValue().getValue()); + } + } + return valueMap; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigSourceProvider.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigSourceProvider.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigSourceProvider.java new file mode 100644 index 0000000..2b34eac --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/JavaConfigSourceProvider.java @@ -0,0 +1,64 @@ +/* + * 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.jsr382; + +import org.apache.tamaya.spi.PropertySource; +import org.apache.tamaya.spi.PropertySourceProvider; +import org.apache.tamaya.spi.PropertyValue; + +import javax.config.spi.ConfigSource; +import javax.config.spi.ConfigSourceProvider; +import java.util.*; + +/** + * JavaConfig {@link javax.config.spi.ConfigSource} implementation that wraps a {@link PropertySource} instance. + */ +public class JavaConfigSourceProvider implements ConfigSourceProvider{ + + private PropertySourceProvider delegate; + + public JavaConfigSourceProvider(PropertySourceProvider propertySourceProvider){ + this.delegate = Objects.requireNonNull(propertySourceProvider); + } + + public PropertySourceProvider getPropertySourceProvider(){ + return this.delegate; + } + + + private Map<String, String> toMap(Map<String, PropertyValue> properties) { + Map<String, String> valueMap = new HashMap<>(properties.size()); + for(Map.Entry<String,PropertyValue> en:properties.entrySet()){ + if(en.getValue().getValue()!=null) { + valueMap.put(en.getKey(), en.getValue().getValue()); + } + } + return valueMap; + } + + @Override + public Iterable<ConfigSource> getConfigSources(ClassLoader forClassLoader) { + if(delegate instanceof TamayaPropertySourceProvider){ + return ((TamayaPropertySourceProvider)delegate).getConfigSourceProvider() + .getConfigSources(forClassLoader); + }else { + return JavaConfigAdapter.toConfigSources(delegate.getPropertySources()); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaConfiguration.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaConfiguration.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaConfiguration.java new file mode 100644 index 0000000..c381366 --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaConfiguration.java @@ -0,0 +1,93 @@ +/* + * 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.jsr382; + +import org.apache.tamaya.*; +import org.apache.tamaya.spi.ConfigurationContext; + +import javax.config.Config; +import java.util.*; + +/** + * Configuration implementation that wraps a Javaconfig {@link Config} instance. + */ +public class TamayaConfiguration implements Configuration{ + + private Config delegate; + + public TamayaConfiguration(Config config){ + this.delegate = Objects.requireNonNull(config); + } + + public Config getConfig(){ + return delegate; + } + + @Override + public String get(String key) { + return this.delegate.getOptionalValue(key, String.class).orElse(null); + } + + @Override + public String getOrDefault(String key, String defaultValue) { + return this.delegate.getOptionalValue(key, String.class).orElse(defaultValue); + } + + @Override + public <T> T getOrDefault(String key, Class<T> type, T defaultValue) { + return this.delegate.getOptionalValue(key, type).orElse(defaultValue); + } + + @Override + public <T> T get(String key, Class<T> type) { + return this.delegate.getOptionalValue(key, type).orElseThrow( + () -> new NoSuchElementException("Missing key: " + key)); + } + + @Override + public <T> T get(String key, TypeLiteral<T> type) { + return this.delegate.getOptionalValue(key, type.getRawType()).orElseThrow( + () -> new NoSuchElementException("Missing key: " + key)); + } + + @Override + public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) { + return null; + } + + @Override + public Map<String, String> getProperties() { + return null; + } + + @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 null; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaPropertyConverter.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaPropertyConverter.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaPropertyConverter.java new file mode 100644 index 0000000..e220eab --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaPropertyConverter.java @@ -0,0 +1,47 @@ +/* + * 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.jsr382; + + +import org.apache.tamaya.spi.ConversionContext; +import org.apache.tamaya.spi.PropertyConverter; + +import javax.config.spi.Converter; +import java.util.Objects; + +/** + * Converter implementation that wraps a Javaconfig {@link Converter} instance. + */ +public class TamayaPropertyConverter<T> implements PropertyConverter<T> { + + private Converter<T> delegate; + + public TamayaPropertyConverter(Converter<T> delegate){ + this.delegate = Objects.requireNonNull(delegate); + } + + public Converter<T> getConverter(){ + return this.delegate; + } + + @Override + public T convert(String value, ConversionContext context) { + return delegate.convert(value); + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaPropertySource.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaPropertySource.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaPropertySource.java new file mode 100644 index 0000000..a551b59 --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaPropertySource.java @@ -0,0 +1,78 @@ +/* + * 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.jsr382; + +import org.apache.tamaya.spi.PropertySource; +import org.apache.tamaya.spi.PropertyValue; + +import javax.config.spi.ConfigSource; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +/** + * Property source implementation that wraps a Javaconfig {@link ConfigSource} instance. + */ +public class TamayaPropertySource implements PropertySource { + + private ConfigSource delegate; + + public TamayaPropertySource(ConfigSource configSource){ + this.delegate = Objects.requireNonNull(configSource); + } + + public ConfigSource getConfigSource(){ + return this.delegate; + } + + @Override + public int getOrdinal() { + return delegate.getOrdinal(); + } + + @Override + public String getName() { + return Optional.ofNullable(delegate.getName()) + .orElse(delegate.toString()); + } + + @Override + public PropertyValue get(String key) { + return PropertyValue.of(key, delegate.getValue(key),getName()); + } + + @Override + public Map<String, PropertyValue> getProperties() { + return toValueMap(delegate.getProperties()); + } + + private Map<String, PropertyValue> toValueMap(Map<String, String> properties) { + Map<String, PropertyValue> valueMap = new HashMap<>(properties.size()); + for(Map.Entry<String,String> en:properties.entrySet()){ + valueMap.put(en.getKey(), PropertyValue.of(en.getKey(), en.getValue(), getName())); + } + return valueMap; + } + + @Override + public boolean isScannable() { + return true; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaPropertySourceProvider.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaPropertySourceProvider.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaPropertySourceProvider.java new file mode 100644 index 0000000..f5b48cd --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/TamayaPropertySourceProvider.java @@ -0,0 +1,55 @@ +/* + * 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.jsr382; + + +import org.apache.tamaya.spi.PropertySource; +import org.apache.tamaya.spi.PropertySourceProvider; + +import javax.config.spi.ConfigSourceProvider; +import java.util.*; + +/** + * Tamaya {@link PropertySourceProvider} implementation that wraps a {@link ConfigSourceProvider} instance. + */ +public class TamayaPropertySourceProvider implements PropertySourceProvider{ + + private ConfigSourceProvider delegate; + + public TamayaPropertySourceProvider(ConfigSourceProvider configSourceProvider){ + this.delegate = Objects.requireNonNull(configSourceProvider); + } + + public ConfigSourceProvider getConfigSourceProvider(){ + return this.delegate; + } + + + @Override + public Collection<PropertySource> getPropertySources() { + if(delegate instanceof JavaConfigSourceProvider){ + return ((JavaConfigSourceProvider)delegate).getPropertySourceProvider() + .getPropertySources(); + }else { + return JavaConfigAdapter.toPropertySources( + delegate.getConfigSources(Thread.currentThread().getContextClassLoader())); + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/BridgingConfigBean.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/BridgingConfigBean.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/BridgingConfigBean.java new file mode 100644 index 0000000..4a9fac0 --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/BridgingConfigBean.java @@ -0,0 +1,95 @@ +/* + * 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.jsr382.cdi; + +import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.InjectionPoint; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.Objects; +import java.util.Set; + +/** + * Internally used conversion bean. + */ +final class BridgingConfigBean implements Bean<Object> { + + private final Bean<Object> delegate; + private final Set<Type> types; + + public BridgingConfigBean(final Bean delegate, final Set<Type> types) { + this.types = types; + this.delegate = Objects.requireNonNull(delegate); + } + + @Override + public Set<Type> getTypes() { + return types; + } + + @Override + public Class<?> getBeanClass() { + return delegate.getBeanClass(); + } + + @Override + public Set<InjectionPoint> getInjectionPoints() { + return delegate.getInjectionPoints(); + } + + @Override + public String getName() { + return delegate.getName(); + } + + @Override + public Set<Annotation> getQualifiers() { + return delegate.getQualifiers(); + } + + @Override + public Class<? extends Annotation> getScope() { + return delegate.getScope(); + } + + @Override + public Set<Class<? extends Annotation>> getStereotypes() { + return delegate.getStereotypes(); + } + + @Override + public boolean isAlternative() { + return delegate.isAlternative(); + } + + @Override + public boolean isNullable() { + return false; + // delegate.isNullable(); + } + + @Override + public Object create(CreationalContext<Object> creationalContext) { + return this.delegate.create(creationalContext); + } + + @Override + public void destroy(Object instance, CreationalContext<Object> creationalContext) { + delegate.destroy(instance, creationalContext); + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/ConfiguredField.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/ConfiguredField.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/ConfiguredField.java new file mode 100644 index 0000000..cc06415 --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/ConfiguredField.java @@ -0,0 +1,65 @@ +/* + * 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.jsr382.cdi; + +import org.apache.tamaya.Configuration; + +import javax.enterprise.inject.spi.InjectionPoint; +import java.lang.reflect.Field; + +/** + * CDI implementation for event publishing of configured instances. + */ +public final class ConfiguredField { + + private final Field field; + private String key; + + ConfiguredField(InjectionPoint injectionPoint, String key){ + this.field = (Field)injectionPoint.getMember(); + this.key = key; + } + + public Class<?> getType() { + return field.getType(); + } + + public String getKey() { + return key; + } + + public Field getAnnotatedField() { + return field; + } + + public String getName() { + return field.getName(); + } + + public String getSignature() { + return getName()+':'+field.getType().getName(); + } + + public void configure(Object instance, Configuration config) { + throw new UnsupportedOperationException("Use CDI annotations for configuration injection."); + } + + @Override + public String toString() { + return "CDIConfiguredField["+getSignature()+']'; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/ConfiguredMethod.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/ConfiguredMethod.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/ConfiguredMethod.java new file mode 100644 index 0000000..d859d88 --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/ConfiguredMethod.java @@ -0,0 +1,65 @@ +/* + * 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.jsr382.cdi; + +import org.apache.tamaya.Configuration; + +import javax.enterprise.inject.spi.InjectionPoint; +import java.lang.reflect.Method; + +/** + * Implementation of a configured methods for CDI module. + */ +public final class ConfiguredMethod { + + private final Method method; + private String key; + + ConfiguredMethod(InjectionPoint injectionPoint, String key){ + this.method = (Method)injectionPoint.getMember(); + this.key = key; + } + + public String getKey() { + return key; + } + + public Class<?>[] getParameterTypes() { + return method.getParameterTypes(); + } + + public Method getAnnotatedMethod() { + return method; + } + + public String getName() { + return method.getName(); + } + + public String getSignature() { + return null; + } + + public void configure(Object instance, Configuration config) { + throw new UnsupportedOperationException("Use CDI annotations for configuration injection."); + } + + @Override + public String toString() { + return "CDIConfiguredMethod["+getSignature()+']'; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/ConfiguredType.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/ConfiguredType.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/ConfiguredType.java new file mode 100644 index 0000000..2730aaf --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/ConfiguredType.java @@ -0,0 +1,86 @@ +/* + * 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.jsr382.cdi; + +import org.apache.tamaya.Configuration; + +import javax.enterprise.inject.spi.InjectionPoint; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; + +/** + * Event published for items configured by CDI extensions. This is for example used by the documentation module + * to automatically track the configuration endpoints for documentation. + */ +public final class ConfiguredType { + + private final Class<?> type; + private final List<ConfiguredMethod> methods = new ArrayList<>(); + private final List<ConfiguredField> fields = new ArrayList<>(); + + public ConfiguredType(Class<?> type){ + this.type = Objects.requireNonNull(type); + } + + public Class getType() { + return type; + } + + public String getName() { + return type.getName(); + } + + public Collection<ConfiguredField> getConfiguredFields() { + return null; + } + + public Collection<ConfiguredMethod> getConfiguredMethods() { + return null; + } + + public void configure(Object instance, Configuration config) { + throw new UnsupportedOperationException("Use CDI annotations for configuration injection."); + } + + /** + * Used to build up during injection point processing. + * @param injectionPoint the CDI injection point, not null. + * @param key the possible config key, not null. + */ + void addConfiguredMember(InjectionPoint injectionPoint, String key) { + Member member = injectionPoint.getMember(); + if(member instanceof Field){ + this.fields.add(new ConfiguredField(injectionPoint, key)); + } else if(member instanceof Method){ + this.methods.add(new ConfiguredMethod(injectionPoint, key)); + } + } + + @Override + public String toString() { + return "CDIConfiguredType{" + + "type=" + type + + ", methods=" + methods + + ", fields=" + fields + + '}'; + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/JavaConfigCDIExtension.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/JavaConfigCDIExtension.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/JavaConfigCDIExtension.java new file mode 100644 index 0000000..12f93b3 --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/JavaConfigCDIExtension.java @@ -0,0 +1,126 @@ +/* + * 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.jsr382.cdi; + +import javax.config.inject.ConfigProperty; + +import javax.enterprise.event.Observes; +import javax.enterprise.inject.Instance; +import javax.enterprise.inject.spi.AfterBeanDiscovery; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.Extension; +import javax.enterprise.inject.spi.InjectionPoint; +import javax.enterprise.inject.spi.ProcessBean; +import javax.enterprise.inject.spi.ProcessProducerMethod; +import javax.inject.Provider; +import java.lang.reflect.AnnotatedType; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.HashSet; +import java.util.Set; +import java.util.logging.Logger; + + +/** + * CDI Extension module that adds injection mechanism for configuration. + * + * @see javax.config.Config + */ +public class JavaConfigCDIExtension implements Extension { + + private static final Logger LOG = Logger.getLogger(JavaConfigCDIExtension.class.getName()); + + private final Set<Type> types = new HashSet<>(); + private Bean<?> convBean; + + /** + * Constructor for loading logging its load. + */ + public JavaConfigCDIExtension(){ + LOG.finest("Loading Tamaya JavaConfig Support..."); + } + + /** + * Method that checks the configuration injection points during deployment for available configuration. + * @param pb the bean to process. + * @param beanManager the bean manager to notify about new injections. + */ + public void retrieveTypes(@Observes final ProcessBean<?> pb, BeanManager beanManager) { + + final Set<InjectionPoint> ips = pb.getBean().getInjectionPoints(); + ConfiguredType configuredType = new ConfiguredType(pb.getBean().getBeanClass()); + + boolean configured = false; + for (InjectionPoint injectionPoint : ips) { + if (injectionPoint.getAnnotated().isAnnotationPresent(ConfigProperty.class)) { + LOG.fine("Configuring: " + injectionPoint); + final ConfigProperty annotation = injectionPoint.getAnnotated().getAnnotation(ConfigProperty.class); + String key = !annotation.name().isEmpty()?annotation.name():JavaConfigConfigurationProducer.getDefaultKey(injectionPoint); + configuredType.addConfiguredMember(injectionPoint, key); + Type originalType = injectionPoint.getType(); + Type convertedType = unwrapType(originalType); + types.add(convertedType); + configured = true; + LOG.finest(() -> "Enabling Tamaya JavaConfig Configuration on bean: " + configuredType.getName()); + }else if(injectionPoint.getMember() instanceof Method){ + Method method = (Method)injectionPoint.getMember(); + for(AnnotatedType paramType: method.getAnnotatedParameterTypes()){ + if(paramType.isAnnotationPresent(ConfigProperty.class)) { + LOG.fine("Configuring method: " + injectionPoint); + final ConfigProperty annotation = paramType.getAnnotation(ConfigProperty.class); + String key = !annotation.name().isEmpty() ? annotation.name() : JavaConfigConfigurationProducer.getDefaultKey(injectionPoint); + configuredType.addConfiguredMember(injectionPoint, key); + Type originalType = paramType.getType(); + Type convertedType = unwrapType(originalType); + types.add(convertedType); + configured = true; + LOG.finest(() -> "Enabling Tamaya JavaConfig Configuration on bean: " + configuredType.getName()); + } + } + } + } + if(configured) { + beanManager.fireEvent(configuredType); + } + } + + + public void captureConvertBean(@Observes final ProcessProducerMethod<?, ?> ppm) { + if (ppm.getAnnotated().isAnnotationPresent(ConfigProperty.class)) { + convBean = ppm.getBean(); + } + } + + public void addConverter(@Observes final AfterBeanDiscovery abd, final BeanManager bm) { + if(!types.isEmpty() && convBean!=null) { + abd.addBean(new BridgingConfigBean(convBean, types)); + } + } + + private Type unwrapType(Type type) { + if(type instanceof ParameterizedType) { + Type rawType = ((ParameterizedType) type).getRawType(); + if(rawType == Provider.class || rawType == Instance.class) { + return ((ParameterizedType) type).getActualTypeArguments()[0]; + } + } + return type; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/JavaConfigConfigurationProducer.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/JavaConfigConfigurationProducer.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/JavaConfigConfigurationProducer.java new file mode 100644 index 0000000..5794c31 --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/cdi/JavaConfigConfigurationProducer.java @@ -0,0 +1,153 @@ +/* + * 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.jsr382.cdi; + +import org.apache.tamaya.ConfigException; +import org.apache.tamaya.Configuration; +import org.apache.tamaya.ConfigurationProvider; +import org.apache.tamaya.TypeLiteral; +import org.apache.tamaya.spi.ConversionContext; +import org.apache.tamaya.spi.PropertyConverter; + +import javax.config.Config; +import javax.config.ConfigProvider; +import javax.config.inject.ConfigProperty; +import javax.config.spi.ConfigBuilder; +import javax.config.spi.ConfigProviderResolver; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; +import javax.enterprise.inject.spi.InjectionPoint; +import javax.inject.Provider; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.List; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Producer bean for configuration properties. + */ +@ApplicationScoped +public class JavaConfigConfigurationProducer { + + private static final Logger LOGGER = Logger.getLogger(JavaConfigConfigurationProducer.class.getName()); + + @Produces + @ConfigProperty + public Object resolveAndConvert(final InjectionPoint injectionPoint) { + LOGGER.finest( () -> "Inject: " + injectionPoint); + final ConfigProperty annotation = injectionPoint.getAnnotated().getAnnotation(ConfigProperty.class); + String key = annotation.name(); + if(key.isEmpty()){ + key = getDefaultKey(injectionPoint); + } + + // unless the extension is not installed, this should never happen because the extension + // enforces the resolvability of the config + + String defaultTextValue = annotation.defaultValue().equals(ConfigProperty.UNCONFIGURED_VALUE) ? null : annotation.defaultValue(); + ConversionContext conversionContext = createConversionContext(key, injectionPoint); + Object value = resolveValue(defaultTextValue, conversionContext, injectionPoint); + if (value == null) { + throw new ConfigException(String.format( + "Can't resolve any of the possible config keys: %s to the required target type: %s, supported formats: %s", + key, conversionContext.getTargetType(), conversionContext.getSupportedFormats().toString())); + } + LOGGER.finest(String.format("Injecting %s for key %s in class %s", key, value.toString(), injectionPoint.toString())); + return value; + } + + static String getDefaultKey(InjectionPoint injectionPoint) { + Class declaringType = injectionPoint.getMember().getDeclaringClass(); + return declaringType.getCanonicalName() + "." + injectionPoint.getMember().getName(); + } + + static ConversionContext createConversionContext(String key, InjectionPoint injectionPoint) { + final Type targetType = injectionPoint.getAnnotated().getBaseType(); + Configuration config = ConfigurationProvider.getConfiguration(); + ConversionContext.Builder builder = new ConversionContext.Builder(config, + ConfigurationProvider.getConfiguration().getContext(), key, TypeLiteral.of(targetType)); + if(targetType instanceof ParameterizedType){ + ParameterizedType pt = (ParameterizedType)targetType; + if(pt.getRawType().equals(Provider.class)) { + builder = new ConversionContext.Builder(config, + ConfigurationProvider.getConfiguration().getContext(), key, + TypeLiteral.of(pt.getActualTypeArguments()[0])); + } + } + if (injectionPoint.getMember() instanceof AnnotatedElement) { + AnnotatedElement annotated = (AnnotatedElement)injectionPoint.getMember(); + if(annotated.isAnnotationPresent(ConfigProperty.class)) { + builder.setAnnotatedElement(annotated); + } + }else if(injectionPoint.getMember() instanceof Method){ + Method method = (Method)injectionPoint.getMember(); + for(Type type:method.getParameterTypes()){ + if(type instanceof AnnotatedElement){ + AnnotatedElement annotated = (AnnotatedElement)type; + if(annotated.isAnnotationPresent(ConfigProperty.class)) { + builder.setAnnotatedElement(annotated); + } + } + } + } + return builder.build(); + } + + static Object resolveValue(String defaultTextValue, ConversionContext context, InjectionPoint injectionPoint) { + Config config = ConfigProviderResolver.instance().getConfig(); + String textValue = config.getOptionalValue(context.getKey(), String.class).orElse(defaultTextValue); + if(String.class.equals(context.getTargetType().getRawType())){ + return textValue; + } + Object value = null; + if (textValue != null || Optional.class.equals(context.getTargetType().getRawType())) { + LOGGER.log(Level.FINEST, () -> "Converting KEY: " + context.getKey() + "("+context.getTargetType()+"), textValue: " + textValue); + List<PropertyConverter> converters = ConfigurationProvider.getConfiguration().getContext() + .getPropertyConverters((TypeLiteral)context.getTargetType()); + for (PropertyConverter<Object> converter : converters) { + try { + value = converter.convert(textValue, context); + if (value != null) { + LOGGER.log(Level.FINEST, "Parsed default value from '" + textValue + "' into " + + injectionPoint); + break; + } + } catch (Exception e) { + LOGGER.log(Level.FINEST, "Failed to convert value '" + textValue + "' for " + + injectionPoint, e); + } + } + } + return value; + } + + @Produces + public Config getConfiguration(){ + return ConfigProvider.getConfig(); + } + + @Produces + public ConfigBuilder getConfigBuilder(){ + return ConfigProviderResolver.instance().getBuilder(); + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/converter/BooleanAsIntegerConverterFix.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/converter/BooleanAsIntegerConverterFix.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/converter/BooleanAsIntegerConverterFix.java new file mode 100644 index 0000000..e43b2fe --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/converter/BooleanAsIntegerConverterFix.java @@ -0,0 +1,61 @@ +/* + * 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.jsr382.converter; + +import org.apache.tamaya.spi.ConversionContext; +import org.apache.tamaya.spi.PropertyConverter; + +import javax.annotation.Priority; +import java.util.Locale; +import java.util.Objects; +import java.util.logging.Logger; + +/** + * Converter, converting from String to Boolean for 1 = true, otherwise false. + */ +@Priority(-1) +public class BooleanAsIntegerConverterFix implements PropertyConverter<Boolean> { + + private final Logger LOG = Logger.getLogger(getClass().getName()); + + @Override + public Boolean convert(String value, ConversionContext context) { + context.addSupportedFormats(getClass(), "'1' (true), otherwise false."); + try{ + int val = Integer.parseInt(Objects.requireNonNull(value).trim()); + if(val==1) { + return Boolean.TRUE; + } + return Boolean.FALSE; + }catch(Exception e){ + // OK + return Boolean.FALSE; + } + } + + @Override + public boolean equals(Object o){ + return getClass().equals(o.getClass()); + } + + @Override + public int hashCode(){ + return getClass().hashCode(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/java/org/apache/tamaya/jsr382/converter/ProviderConverter.java ---------------------------------------------------------------------- diff --git a/configjsr/src/main/java/org/apache/tamaya/jsr382/converter/ProviderConverter.java b/configjsr/src/main/java/org/apache/tamaya/jsr382/converter/ProviderConverter.java new file mode 100644 index 0000000..432d05d --- /dev/null +++ b/configjsr/src/main/java/org/apache/tamaya/jsr382/converter/ProviderConverter.java @@ -0,0 +1,98 @@ +/* + * 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.jsr382.converter; + +import org.apache.tamaya.ConfigException; +import org.apache.tamaya.ConfigQuery; +import org.apache.tamaya.Configuration; +import org.apache.tamaya.TypeLiteral; +import org.apache.tamaya.spi.ConversionContext; +import org.apache.tamaya.spi.PropertyConverter; + +import javax.annotation.Priority; +import javax.inject.Provider; +import java.lang.reflect.Type; +import java.util.List; +import java.util.Objects; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Converter, converting from String to Boolean for 1 = true, otherwise false. + */ +@Priority(-1) +public class ProviderConverter implements PropertyConverter<Provider> { + + private static final Logger LOG = Logger.getLogger(ProviderConverter.class.getName()); + + @Override + public Provider convert(String value, ConversionContext context) { + return () -> { + try{ + Type targetType = context.getTargetType().getType(); + ConvertQuery converter = new ConvertQuery(value, TypeLiteral.of(targetType)); + return context.getConfiguration().query(converter); + }catch(Exception e){ + throw new ConfigException("Error evaluating config value.", e); + } + }; + } + + @Override + public boolean equals(Object o){ + return getClass().equals(o.getClass()); + } + + @Override + public int hashCode(){ + return getClass().hashCode(); + } + + private static final class ConvertQuery<T> implements ConfigQuery<T> { + + private String rawValue; + private TypeLiteral<T> type; + + public ConvertQuery(String rawValue, TypeLiteral<T> type) { + this.rawValue = Objects.requireNonNull(rawValue); + this.type = Objects.requireNonNull(type); + } + + @Override + public T query(Configuration config) { + List<PropertyConverter<T>> converters = config.getContext().getPropertyConverters(type); + ConversionContext context = new ConversionContext.Builder(type).setConfigurationContext(config.getContext()) + .setConfiguration(config).setKey(ConvertQuery.class.getName()).build(); + for(PropertyConverter<?> conv: converters) { + try{ + if(conv instanceof ProviderConverter){ + continue; + } + T result = (T)conv.convert(rawValue, context); + if(result!=null){ + return result; + } + }catch(Exception e){ + LOG.log(Level.FINEST, e, () -> "Converter "+ conv +" failed to convert to " + type); + } + } + return null; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/67245331/configjsr/src/main/resources/META-INF/services/javax.config.spi.ConfigProviderResolver ---------------------------------------------------------------------- diff --git a/configjsr/src/main/resources/META-INF/services/javax.config.spi.ConfigProviderResolver b/configjsr/src/main/resources/META-INF/services/javax.config.spi.ConfigProviderResolver new file mode 100644 index 0000000..4a9b29e --- /dev/null +++ b/configjsr/src/main/resources/META-INF/services/javax.config.spi.ConfigProviderResolver @@ -0,0 +1,19 @@ +# +# 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. +# +org.apache.tamaya.jsr382.JavaConfigProviderResolver \ No newline at end of file
