diff --git a/.travis.yml b/.travis.yml.disabled
similarity index 100%
rename from .travis.yml
rename to .travis.yml.disabled
diff --git a/NOTICE b/NOTICE
index 451c174..231dcfe 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,4 +1,4 @@
-Copyright 2016-2017 original author and authors
+Copyright 2009-2017 Mark Struberg
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/README.adoc b/README.adoc
index 5f6c584..e346ca3 100644
--- a/README.adoc
+++ b/README.adoc
@@ -19,46 +19,28 @@
## Status
-Microprofile proposal!
+The content of this repository is OUTDATED!
-== Rational
+Please go to the Apache Geronimo Config project for further information.
-Many project artifacts (e.g. WAR, EAR) should only be created once and then get installed at different customers, stages, etc
-They need to target those different execution environments without necessity of any repackaging.
-In other words: depending on the situation they need different configuration.
-
-This is easily achievable by having a set of default configuration values inside the project artifact.
-But be able to overwrite those default values from external.
+$> svn co https://svn.apache.org/repos/asf/geronimo/components/config/trunk
== History
-This very configuration approach has it's roots in the Apache OpenWebBeans internal SPI configuration.
-In 2010 it got moved over to the Apache MyFaces CODI project and enhanced to also fit the need of customer projects by Gerhard Petracek and Mark Struberg.
-In 2011 we further enhanced it while moving CODI to the Apache DeltaSpike project.
-Romain Manni-Bucau (Apache/Tomitribe), Ron Smeral (JBoss) and Anatole Tresch also gave appreciated input in the last years.
-
-== How it works
-
-A 'Configuration' consists of the information collected from the registered `javax.config.spi.ConfigSource` s.
-These `ConfigSource`s get sorted according to their _ordinal_.
-That way it is possible to overwrite configuration with lower importance from outside.
-
-By default there are 3 default ConfigSources:
+This repository contains the original MicroProfile Config proposal and a Config JSR proposal based on the concepts Gerhard and I created in Apache OpenWebBeans, CODI and DeltaSpike.
+See the separate branches for more info.
-* `System.getenv()` (ordinal=400)
-* `System.getProperties()` (ordinal=300)
-* all `META-INF/java-config.properties` files on the ClassPath. (ordinal=100, separately configurable via a config_ordinal property inside each file)
+== The Config API
-That means that I can put my default configuration in a `META-INF/java-config.properties` anywhere on the classpath.
-And I can later simply e.g set a system property to change this default configuration.
+The API later got moved to the MicroProfile repository which itself later moved under the Eclipse umbrella.
+It now can be found at
-== Custom ConfigSources
+https://github.com/eclipse/microprofile-config/
-It is possible to write and register custom `ConfigSource` s.
-An example would be a ConfigSource which gets the configured values from a shared database table in a cluster.
-== Building
+== The Config IMPL
-`$> mvn clean install`
+The implementation of MicroProfile Config can be found at the Apache Geronimo Project.
-After that the specification PDF can be found in `spec/target/generated-docs/microprofile-config-spec.pdf`
\ No newline at end of file
+$> svn co https://svn.apache.org/repos/asf/geronimo/components/config/trunk
+
diff --git a/api/pom.xml b/api/pom.xml
deleted file mode 100644
index 3a68c25..0000000
--- a/api/pom.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
- 4.0.0
-
-
-
- org.apache.geronimo.config
- config-parent
- 0.1-SNAPSHOT
-
-
- org.apache.geronimo.config
- config-api
-
-
-
- Apache License, Version 2.0
- https://www.apache.org/licenses/LICENSE-2.0.txt
- repo
- A business-friendly OSS license
-
-
-
-
-
diff --git a/api/src/main/java/io/microprofile/config/Config.java b/api/src/main/java/io/microprofile/config/Config.java
deleted file mode 100644
index 76e2e55..0000000
--- a/api/src/main/java/io/microprofile/config/Config.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * See the NOTICE file distributed with this work for additional information
- * regarding copyright ownership.
- * The author 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 io.microprofile.config;
-
-import java.util.Map;
-
-import io.microprofile.config.spi.ConfigSourceProvider;
-import io.microprofile.config.spi.Converter;
-import io.microprofile.config.spi.ConfigSource;
-
-/**
- *
Resolves configured values of properties by going through the list
- * of configured {@link ConfigSource}s and using the one with the highest ordinal.
- * If multiple {@link ConfigSource}s have the same ordinal, their order is undefined.
- *
- *
You can provide your own lookup paths by implementing and registering additional
- * {@link ConfigSource}s and {@link ConfigSourceProvider} implementations.
- *
- *
- * @see ConfigProvider to resolve the current configuration.
- *
- * @author Mark Struberg
- */
-public interface Config {
-
- /**
- * Create a {@link ConfigValue} to access the underlying configuration.
- *
- * @param key the property key
- */
- ConfigValue access(String key);
-
- /**
- * Resolves the value configured for the given key.
- *
- * @param key the property key
- *
- * @return the configured property value from the {@link ConfigSource} with the highest ordinal
- * or {@code null} if there is no configured value for it
- */
- String getValue(String key);
-
- /**
- * Resolves the value configured for the given key and convert it to the required asType.
- *
- * @param key
- * @param asType Also support parameterized Types?
- * @param
- * @return
- * @throws UnsupportedOperationException if there is no {@link Converter} registered for asType
- */
- T getValue(String key, Class asType);
-
- /**
- * Apply the
- * @return the String converted
- * @throws UnsupportedOperationException if there is no {@link Converter} registered for asType
- */
- T convert(String value, Class asType);
-
- /**
- * Returns a Map of all properties from all scannable config sources. The values of the properties reflect the
- * values that would be obtained by a call to {@link #getValue(java.lang.String)}, that is, the value of the
- * property from the ConfigSource with the highest ordinal.
- */
- Map getAllProperties();
-
- /**
- * @return all currently registered {@link ConfigSource}s
- */
- ConfigSource[] getConfigSources();
-
-}
diff --git a/api/src/main/java/io/microprofile/config/ConfigProvider.java b/api/src/main/java/io/microprofile/config/ConfigProvider.java
deleted file mode 100644
index ae0f690..0000000
--- a/api/src/main/java/io/microprofile/config/ConfigProvider.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * See the NOTICE file distributed with this work for additional information
- * regarding copyright ownership.
- * The author 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 io.microprofile.config;
-
-import java.util.ServiceLoader;
-import java.util.logging.Logger;
-
-import io.microprofile.config.spi.ConfigSource;
-import io.microprofile.config.spi.Converter;
-
-/**
- *
This is the central class to access a {@link Config}.
- *
- *
A {@link Config} contains the configuration for a certain
- * situation. That might be the configuration found in a certain ClassLoader
- * or even a manually created Configuration
- *
- *
The default usage is to use {@link #getConfig()} to automatically
- * pick up the 'Configuration' for the Thread Context ClassLoader
- * (See {@link Thread#getContextClassLoader()}).
- *
- *
A 'Configuration' consists of the information collected from the registered
- * {@link ConfigSource}s. These {@link ConfigSource}s
- * get sorted according to their ordinal defined via {@link ConfigSource#getOrdinal()}.
- * That way it is possible to overwrite configuration with lower importance from outside.
- *
- *
It is also possible to register custom {@link ConfigSource}s to
- * flexibly extend the configuration mechanism. An example would be to pick up configuration values
- * from a database table./p>
- *
- *
- *
- *
- *
- * @author Mark Struberg
- * @author Romain Manni-Bucau
- */
-public class ConfigProvider {
-
- private static volatile SPI instance;
-
- /**
- * Provide a {@link Config} based on all {@link ConfigSource}s
- * of the current Thread Context ClassLoader (TCCL)
- *
- *
There is exactly a single Config instance per Application
- */
- public static Config getConfig() {
- return loadSpi().getConfig();
- }
-
- /**
- * Provide a {@link Config} based on all {@link ConfigSource}s
- * of the given ClassLoader.
- *
- *
There is exactly a single Config instance per Application. The Application get's identified via a ClassLoader
- */
- public static Config getConfig(ClassLoader forClassLoader) {
- return instance.getConfig(forClassLoader);
- }
-
- /**
- * Create a {@link ConfigBuilder} for providing a fresh {@link Config} instance.
- *
- * The ConfigProvider will not manage the Config instance internally.
- * That means that {@link #getConfig()} does not pick up a Config created that way.
- */
- public static ConfigBuilder newConfig() {
- return instance.newConfig();
- }
-
- /**
- * Create a {@link ConfigBuilder} for register a {@link Config} instance to a certain Application.
- * Invoking {@link ConfigBuilder#build()} will effectively register the Config.
- * Use {@link ConfigBuilder#forClassLoader(ClassLoader)} to define the application the Config should be for,
- * otherwise the current ThreadContextClassLoader will be used.
- *
- * A {@link Config} registered that way will get picked up on any subsequent call to {@link ConfigProvider#getConfig()}.
- *
- * @throws IllegalStateException if a {@link Config} has already been associated for the Application.
- */
- public static ConfigBuilder registerConfig() {
- return instance.registerConfig();
- }
-
-
- /**
- * A {@link Config} normally gets released if the ClassLoader it represents gets destroyed.
- * Invoke this method if you like to destroy the Config prematurely.
- */
- public static void releaseConfig(Config config) {
- instance.releaseConfig(config);
- }
-
-
- /**
- * Builder for manually creating an instance of a {@code Config}.
- *
- * @see ConfigProvider#newConfig()
- */
- public interface ConfigBuilder {
- ConfigBuilder ignoreDefaultSources();
- ConfigBuilder forClassLoader(ClassLoader loader);
- ConfigBuilder withSources(ConfigSource... sources);
- ConfigBuilder withConverters(Converter>... filters);
- Config build();
- }
-
- /**
- * This interface gets implemented internally by the Config library.
- * The implementation registers itself via {@link java.util.ServiceLoader} mechanism.
- * In an OSGi environment
- */
- public interface SPI {
- Config getConfig();
- Config getConfig(ClassLoader forClassLoader);
- ConfigBuilder newConfig();
- ConfigBuilder registerConfig();
- void releaseConfig(Config config);
- }
-
- /**
- * Attention, handle with care!
- * This method is not intended to be used from a user.
- * It is for integration with e.g. OSGi from within a BundleActivator.
- * TODO probably remove this and add native OSGi support later.
- */
- public static synchronized void setSPI(SPI newInstance) {
- instance = newInstance;
- }
-
- private static SPI loadSpi() {
- if (instance == null) {
- synchronized (SPI.class) {
- if (instance != null) {
- return instance;
- }
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- if (cl == null) {
- cl = SPI.class.getClassLoader();
- }
-
- SPI newInstance = loadSpi(cl);
-
- if (newInstance == null) {
- throw new IllegalStateException("No ConfigResolver SPI implementation found!");
- }
-
- instance = newInstance;
- }
- }
-
- return instance;
- }
-
- private static SPI loadSpi(ClassLoader cl) {
- if (cl == null) {
- return null;
- }
-
- // start from the root CL and go back down to the TCCL
- SPI instance = loadSpi(cl.getParent());
-
- if (instance == null) {
- ServiceLoader sl = ServiceLoader.load(SPI.class, cl);
- for (SPI spi : sl) {
- if (instance != null) {
- Logger.getLogger(ConfigProvider.class.getName())
- .warning("Multiple ConfigResolver SPIs found. Ignoring " + spi.getClass().getName());
- } else {
- instance = spi;
- }
- }
- }
- return instance;
- }
-
-
-}
diff --git a/api/src/main/java/io/microprofile/config/ConfigValue.java b/api/src/main/java/io/microprofile/config/ConfigValue.java
deleted file mode 100644
index d93b95b..0000000
--- a/api/src/main/java/io/microprofile/config/ConfigValue.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * See the NOTICE file distributed with this work for additional information
- * regarding copyright ownership.
- * The author 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 io.microprofile.config;
-
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Accessor to a configured value.
- * It follows a builder pattern.
- *
- * Accessing the configured value is finally done via {@link #getValue()}
- *
- * @author Mark Struberg
- * @author Gerhard Petracek
- * @author Ron Smeral
- */
-public interface ConfigValue {
-
- /**
- * Sets the type of the configuration entry to the given class and returns this builder.
- * The default type of a ConfigValue is {@code String}.
- *
- * @param clazz The target type
- * @param The target type
- * @return This builder as a typed ConfigValue
- */
- ConfigValue as(Class clazz);
-
- /**
- * Sets the default value to use in case the resolution returns null.
- * @param value the default value
- * @return This builder
- */
- ConfigValue withDefault(T value);
-
- /**
- * Sets the default value to use in case the resolution returns null. Converts the given String to the type of
- * this resolver using the same method as used for the configuration entries.
- * @param value string value to be converted and used as default
- * @return This builder
- */
- ConfigValue withStringDefault(String value);
-
- /**
- * Specify that a resolved value will get cached for a certain amount of time.
- * After the time expires the next {@link #getValue()} will again resolve the value
- * from the underlying {@link Config}.
- *
- * @param value the amount of the TimeUnit to wait
- * @param timeUnit the TimeUnit for the value
- *
- * @return This builder
- */
- ConfigValue cacheFor(long value, TimeUnit timeUnit);
-
- /**
- * Whether to evaluate variables in configured values.
- * A variable starts with '${' and ends with '}', e.g.
- *
- * If 'evaluateVariables' is enabled, the result for the above key
- * {@code "mycompany.some.url"} would be:
- * {@code "http://localhost:8081/some/path"}
- * @param evaluateVariables whether to evaluate variables in values or not
- * @return This builder
- */
- ConfigValue evaluateVariables(boolean evaluateVariables);
-
- /**
- * Appends the resolved value of the given property to the key of this builder.
- * TODO further explain.
- * @return This builder
- */
- ConfigValue withLookupChain(String... postfixNames);
-
- /**
- * Whether to log picking up any value changes as INFO.
- *
- * @return This builder
- */
- ConfigValue logChanges(boolean logChanges);
-
- /**
- * Returns the converted resolved filtered value.
- * @return the resolved value
- */
- T getValue();
-
- /**
- * Resolves the value and split it on each comma (',') character.
- * If a comma is contained in the values it must get escaped with a preceding backslash ("\,").
- * Any backslash needs to get escaped via double-backslash ("\\").
- *
- * @return the list of configured comma separated values or an empty Iterable if no
- */
- Iterable getValueList();
-
- /**
- * Returns the key given in {@link Config#access(String)}.
- * @return the original key
- */
- String getKey();
-
- /**
- * Returns the actual key which led to successful resolution and corresponds to the resolved value. This applies
- * only when {@link #withLookupChain(String...)} is used.
- * Otherwise the resolved key should always be equal to the original key.
- * This method is provided for cases, when arameterized resolution is
- * requested but the value for such appended key is not found and some of the fallback keys is used.
- *
- * This should be called only after calling {@link #getValue()} otherwise the value is undefined (but likely
- * null).
- */
- String getResolvedKey();
-
- /**
- * Returns the default value provided by {@link #withDefault(Object)} or {@link #withStringDefault(String)}.
- * Returns null if no default was provided.
- * @return the default value or {@code null}
- */
- T getDefaultValue();
-}
diff --git a/api/src/main/java/io/microprofile/config/spi/ConfigSource.java b/api/src/main/java/io/microprofile/config/spi/ConfigSource.java
deleted file mode 100644
index 6340aea..0000000
--- a/api/src/main/java/io/microprofile/config/spi/ConfigSource.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * See the NOTICE file distributed with this work for additional information
- * regarding copyright ownership.
- * The author 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 io.microprofile.config.spi;
-
-import java.util.Map;
-
-/**
- *
Implement this interfaces to provide a ConfigSource.
- * A ConfigSource provides properties from a specific place, like
- * JNDI configuration, a properties file, etc.
- * A ConfigSource is always read-only, any potential updates of the
- * configured values must be handled directly inside each ConfigSource.
- *
- *
The custom implementation can be 'registered' using a
- * {@link ConfigSourceProvider} or via the
- * {@link java.util.ServiceLoader} mechanism. In the later case
- * it must get registered via creating a
- * META-INF/services/javax.config.spi.ConfigSource
- * file and adding the fully qualified class name of your ConfigSource
- * implementation into it.
- *
- * @author Mark Struberg
- * @author Gerhard Petracek
- */
-public interface ConfigSource {
- /**
- * The default name for the ordinal field.
- * Any ConfigSource might use it's own though or even return a hardcoded
- * in {@link #getOrdinal()}.
- */
- String CONFIG_ORDINAL = "config_ordinal";
-
-
- /**
- * Lookup order:
- *
- *
- *
- * If a custom implementation should be invoked before the default implementations, use a value > 400
- *
- *
- * If a custom implementation should be invoked after the default implementations, use a value < 100
- *
- *
- *
- *
- *
- *
- *
Reordering of the default order of the config-sources:
- *
Example: If the properties file/s should be used before the other implementations,
- * you have to configure an ordinal > 400. That means, you have to add e.g. config_ordinal=401 to
- * /META-INF/java-config.properties . Hint: In case of property files every file is handled as independent
- * config-source, but all of them have ordinal 400 by default (and can be reordered in a fine-grained manner.
- *
- * @return the 'importance' aka ordinal of the configured values. The higher, the more important.
- */
- int getOrdinal();
-
- /**
- * Return properties contained in this config source.
- * @return Properties available in this config source.
- */
- Map getProperties();
-
- /**
- * @param key for the property
- * @return configured value or null if this ConfigSource doesn't provide any value for the given key.
- */
- String getPropertyValue(String key);
-
- /**
- * The name of the config might be used for logging or analysis of configured values.
- *
- * @return the 'name' of the configuration source, e.g. 'property-file mylocation/myproperty.properties'
- */
- String getConfigName();
-
-}
diff --git a/api/src/main/java/io/microprofile/config/spi/ConfigSourceProvider.java b/api/src/main/java/io/microprofile/config/spi/ConfigSourceProvider.java
deleted file mode 100644
index ca4e04c..0000000
--- a/api/src/main/java/io/microprofile/config/spi/ConfigSourceProvider.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * See the NOTICE file distributed with this work for additional information
- * regarding copyright ownership.
- * The author 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 io.microprofile.config.spi;
-
-import java.util.List;
-
-/**
- *
Implement this interfaces to provide a ConfigSource provider which
- * is able to maintain multiple ConfigSources. This is e.g. needed if
- * there are multiple property files of a given name.
- *
- *
If a ConfigSource like JNDI only exists once, then there is no need
- * to implement it via the ConfigSourceProvider but should directly
- * expose a {@link ConfigSource}.
- *
- *
A ConfigSourceProvider will get picked up via the
- * {@link java.util.ServiceLoader} mechanism and must get registered via
- * META-INF/services/javax.config.spi.ConfigSourceProvider
- *
- * @author Mark Struberg
- */
-public interface ConfigSourceProvider
-{
-
- /**
- * @param forClassLoader the classloader which should be used if any is needed
- *
- * @return For each e.g. property file, we return a single ConfigSource or an empty list if no ConfigSource exists.
- */
- List getConfigSources(ClassLoader forClassLoader);
-}
diff --git a/api/src/main/java/io/microprofile/config/spi/Converter.java b/api/src/main/java/io/microprofile/config/spi/Converter.java
deleted file mode 100644
index b6565b5..0000000
--- a/api/src/main/java/io/microprofile/config/spi/Converter.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * See the NOTICE file distributed with this work for additional information
- * regarding copyright ownership.
- * The author 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 io.microprofile.config.spi;
-
-/**
- *
A very simple interface for conversion of configuration values from String to any Java type.
- *
- *
A Converter can specify a {@link javax.annotation.Priority}.
- * If no priority is explicitly assigned, the value of 100 is assumed.
- *
- *
If multiple Converter get found the one with the highest priority will be used.
- *
- *
The Converter for the following types are automatically enabled:
- *
Float, a dot '.' is used to separate the fractional digits
- *
Double, a dot '.' is used to separate the fractional digits>
- *
- *
- *
- *
- * @author Mark Struberg
- * @author Ron Smeral
- * @author Gerhard Petracek
- */
-public interface Converter {
- /**
- * Returns the converted value of the configuration entry.
- * @param value The String property value to convert
- * @return Converted value
- */
- T convert(String value);
-
-}
diff --git a/impl/debug-suite.xml b/impl/debug-suite.xml
index 10e8976..b121bee 100644
--- a/impl/debug-suite.xml
+++ b/impl/debug-suite.xml
@@ -24,7 +24,7 @@
-
+
diff --git a/impl/pom.xml b/impl/pom.xml
index 69d8a7c..f67ec8a 100644
--- a/impl/pom.xml
+++ b/impl/pom.xml
@@ -30,17 +30,34 @@
org.apache.geronimo.configconfig-impl
+
+ 1.1.13.Final
+
+
+
+
+
+ org.jboss.arquillian
+ arquillian-bom
+ ${arquillian.version}
+ pom
+ import
+
+
+
+
+
- org.apache.geronimo.config
- config-api
- 0.1-SNAPSHOT
+ org.eclipse.microprofile.apis
+ microprofile-config_1.0_api
+ 1.0-SNAPSHOT
- org.apache.geronimo.config
- config-tck
- 0.1-SNAPSHOT
+ org.eclipse.microprofile.config.tck
+ microprofile-config-tck
+ 1.0-SNAPSHOTtest
@@ -57,6 +74,15 @@
provided
+
+ org.jboss.arquillian.testng
+ arquillian-testng-container
+ ${arquillian.version}
+ test
+
+
+
+
@@ -73,4 +99,65 @@
+
+
+
+ OWB
+
+ true
+
+
+
+ 1.7.3-SNAPSHOT
+
+
+
+
+ org.apache.geronimo.specs
+ geronimo-atinject_1.0_spec
+ 1.0
+ provided
+
+
+ org.apache.geronimo.specs
+ geronimo-jcdi_1.1_spec
+ 1.0
+ provided
+
+
+ org.apache.geronimo.specs
+ geronimo-interceptor_1.2_spec
+ 1.0
+ provided
+
+
+ org.apache.geronimo.specs
+ geronimo-el_2.2_spec
+ 1.0.2
+ provided
+
+
+
+ org.apache.openwebbeans
+ openwebbeans-spi
+ ${owb.version}
+ test
+
+
+ org.apache.openwebbeans
+ openwebbeans-impl
+ ${owb.version}
+ test
+
+
+ org.apache.openwebbeans.arquillian
+ owb-arquillian-standalone
+ ${owb.version}
+ test
+
+
+
+
+
+
diff --git a/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java b/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java
index a9feb00..f2ab338 100644
--- a/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java
+++ b/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java
@@ -18,20 +18,31 @@
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Optional;
+import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
-import io.microprofile.config.Config;
-import io.microprofile.config.ConfigValue;
-import io.microprofile.config.spi.ConfigSource;
-import io.microprofile.config.spi.Converter;
+import org.apache.geronimo.config.converters.DurationConverter;
+import org.apache.geronimo.config.converters.LocalDateConverter;
+import org.apache.geronimo.config.converters.LocalDateTimeConverter;
+import org.apache.geronimo.config.converters.LocalTimeConverter;
+import org.apache.geronimo.config.converters.StringConverter;
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.spi.ConfigSource;
+import org.eclipse.microprofile.config.spi.Converter;
import org.apache.geronimo.config.converters.BooleanConverter;
import org.apache.geronimo.config.converters.DoubleConverter;
import org.apache.geronimo.config.converters.FloatConverter;
@@ -39,14 +50,18 @@
import org.apache.geronimo.config.converters.LongConverter;
import javax.annotation.Priority;
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.Vetoed;
/**
* @author Mark Struberg
*/
+@Typed
+@Vetoed
public class ConfigImpl implements Config {
protected Logger logger = Logger.getLogger(ConfigImpl.class.getName());
- protected ConfigSource[] configSources = new ConfigSource[0];
+ protected List configSources = new ArrayList<>();
protected Map converters = new HashMap<>();
@@ -55,40 +70,60 @@ public ConfigImpl() {
}
private void registerDefaultConverter() {
+ converters.put(String.class, StringConverter.INSTANCE);
converters.put(Boolean.class, BooleanConverter.INSTANCE);
converters.put(Double.class, DoubleConverter.INSTANCE);
converters.put(Float.class, FloatConverter.INSTANCE);
converters.put(Integer.class, IntegerConverter.INSTANCE);
converters.put(Long.class, LongConverter.INSTANCE);
+
+ converters.put(Duration.class, DurationConverter.INSTANCE);
+ converters.put(LocalTime.class, LocalTimeConverter.INSTANCE);
+ converters.put(LocalDate.class, LocalDateConverter.INSTANCE);
+ converters.put(LocalDateTime.class, LocalDateTimeConverter.INSTANCE);
+ }
+
+
+ @Override
+ public Optional getOptionalValue(String propertyName, Class asType) {
+ String value = getValue(propertyName);
+ if (value != null && value.length() == 0) {
+ // treat an empty string as not existing
+ value = null;
+ }
+ return Optional.ofNullable(convert(value, asType));
}
@Override
+ public T getValue(String propertyName, Class propertyType) {
+ String value = getValue(propertyName);
+ if (value == null || value.length() == 0) {
+ throw new NoSuchElementException("No configured value found for config key " + propertyName);
+ }
+
+ return convert(value, propertyType);
+ }
+
public String getValue(String key) {
for (ConfigSource configSource : configSources) {
- String value = configSource.getPropertyValue(key);
+ String value = configSource.getValue(key);
if (value != null) {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "found value {0} for key {1} in ConfigSource {2}.",
- new Object[]{value, key, configSource.getConfigName()});
+ new Object[]{value, key, configSource.getName()});
}
return value;
}
}
- return null;
- }
- @Override
- public T getValue(String key, Class asType) {
- String value = getValue(key);
- return convert(value, asType);
+ return null;
}
- @Override
public T convert(String value, Class asType) {
- Converter converter = getConverter(asType);
if (value != null) {
+ Converter converter = getConverter(asType);
return converter.convert(value);
}
@@ -103,30 +138,30 @@ private Converter getConverter(Class asType) {
return converter;
}
- public ConfigValue access(String key) {
- return new ConfigValueImpl<>(this, key);
+ public ConfigValueImpl access(String key) {
+ return new ConfigValueImpl(this, key);
}
@Override
- public Map getAllProperties() {
- Map result = new HashMap();
+ public Iterable getPropertyNames() {
+ Set result = new HashSet<>();
- for (int i = configSources.length; i > 0; i--) {
- ConfigSource configSource = configSources[i];
- result.putAll(configSource.getProperties());
- }
+ for (ConfigSource configSource : configSources) {
+ result.addAll(configSource.getProperties().keySet());
- return Collections.unmodifiableMap(result);
+ }
+ return result;
}
+
@Override
- public ConfigSource[] getConfigSources() {
- return configSources;
+ public Iterable getConfigSources() {
+ return Collections.unmodifiableList(configSources);
}
public synchronized void addConfigSources(List configSourcesToAdd) {
- List allConfigSources = new ArrayList<>(Arrays.asList(configSources));
+ List allConfigSources = new ArrayList<>(configSources);
allConfigSources.addAll(configSourcesToAdd);
// finally put all the configSources back into the map
@@ -165,14 +200,14 @@ public Map getConverters() {
}
- protected ConfigSource[] sortDescending(List configSources) {
+ protected List sortDescending(List configSources) {
Collections.sort(configSources, new Comparator() {
@Override
public int compare(ConfigSource configSource1, ConfigSource configSource2) {
return (configSource1.getOrdinal() > configSource2.getOrdinal()) ? -1 : 1;
}
});
- return configSources.toArray(new ConfigSource[configSources.size()]);
+ return configSources;
}
diff --git a/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java b/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java
index b552493..b88a0ff 100644
--- a/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java
+++ b/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java
@@ -16,17 +16,22 @@
*/
package org.apache.geronimo.config;
-import io.microprofile.config.ConfigValue;
-import io.microprofile.config.spi.Converter;
+import org.eclipse.microprofile.config.spi.Converter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Optional;
import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.enterprise.inject.Typed;
+
/**
* @author Mark Struberg
*/
-public class ConfigValueImpl implements ConfigValue {
+@Typed
+public class ConfigValueImpl {
private static final Logger logger = Logger.getLogger(ConfigValueImpl.class.getName());
private final ConfigImpl config;
@@ -39,78 +44,107 @@ public class ConfigValueImpl implements ConfigValue {
private String[] lookupChain;
- private boolean withDefault = false;
- private T defaultValue;
-
-
- private Converter> converter;
-
private boolean evaluateVariables = false;
- private boolean logChanges = false;
-
private long cacheTimeMs = -1;
private volatile long reloadAfter = -1;
private T lastValue = null;
+ private ConfigChanged valueChangeListener;
public ConfigValueImpl(ConfigImpl config, String key) {
this.config = config;
this.keyOriginal = key;
}
- @Override
- public ConfigValue as(Class clazz) {
+ //X @Override
+ public ConfigValueImpl as(Class clazz) {
configEntryType = clazz;
- this.converter = null;
- return (ConfigValue) this;
+ return (ConfigValueImpl) this;
}
- @Override
- public ConfigValue withDefault(T value) {
- defaultValue = value;
- withDefault = true;
- return this;
- }
-
- @Override
- public ConfigValue withStringDefault(String value) {
- if (value == null || value.isEmpty())
- {
- throw new RuntimeException("Empty String or null supplied as string-default value for property "
- + keyOriginal);
- }
-
- defaultValue = convert(value);
- withDefault = true;
- return this;
- }
- @Override
- public ConfigValue cacheFor(long value, TimeUnit timeUnit) {
+ //X @Override
+ public ConfigValueImpl cacheFor(long value, TimeUnit timeUnit) {
this.cacheTimeMs = timeUnit.toMillis(value);
return this;
}
- @Override
- public ConfigValue evaluateVariables(boolean evaluateVariables) {
+ //X @Override
+ public ConfigValueImpl evaluateVariables(boolean evaluateVariables) {
this.evaluateVariables = evaluateVariables;
return this;
}
- @Override
- public ConfigValue withLookupChain(String... postfixNames) {
+ public ConfigValueImpl withLookupChain(String... postfixNames) {
this.lookupChain = postfixNames;
return this;
}
- @Override
- public ConfigValue logChanges(boolean logChanges) {
- this.logChanges = logChanges;
+ //X @Override
+ public T get() {
+ T val = getValue();
+ if (val == null) {
+ throw new NoSuchElementException("No config value present for key " + keyOriginal);
+ }
+ return val;
+ }
+
+ //X @Override
+ public Optional getOptional() {
+ return Optional.ofNullable(getValue());
+ }
+
+ //X @Override
+ public ConfigValueImpl onChange(ConfigChanged valueChangeListener) {
+ this.valueChangeListener = valueChangeListener;
return this;
}
- @Override
+ //X @Override
+ public List getValueList() {
+ String rawList = (String) getValue(false);
+ List values = new ArrayList();
+ StringBuilder sb = new StringBuilder(64);
+ for (int i= 0; i < rawList.length(); i++) {
+ char c = rawList.charAt(i);
+ if ('\\' == c) {
+ if (i == rawList.length()) {
+ throw new IllegalStateException("incorrect escaping of key " + keyOriginal + " value: " + rawList);
+ }
+ char nextChar = rawList.charAt(i+1);
+ if (nextChar == '\\') {
+ sb.append('\\');
+ }
+ else if (nextChar == ',') {
+ sb.append(',');
+ }
+ i++;
+ }
+ else if (',' == c) {
+ addListValue(values, sb);
+ }
+ else {
+ sb.append(c);
+ }
+ }
+ addListValue(values, sb);
+
+ return values;
+ }
+
+ private void addListValue(List values, StringBuilder sb) {
+ String val = sb.toString().trim();
+ if (!val.isEmpty()) {
+ values.add(convert(val));
+ }
+ sb.setLength(0);
+ }
+
public T getValue() {
+ return getValue(true);
+ }
+
+ private T getValue(boolean convert) {
long now = -1;
if (cacheTimeMs > 0)
{
@@ -122,17 +156,11 @@ public T getValue() {
}
String valueStr = resolveStringValue();
- T value = convert(valueStr);
+ T value = convert ? convert(valueStr) : (T) valueStr;
- if (withDefault)
+ if (valueChangeListener != null && (value != null && !value.equals(lastValue) || (value == null && lastValue != null)) )
{
- value = fallbackToDefaultIfEmpty(keyResolved, value, defaultValue);
- }
-
- if (logChanges && (value != null && !value.equals(lastValue) || (value == null && lastValue != null)) )
- {
- logger.log(Level.INFO, "New value {0} for key {1}.",
- new Object[]{valueStr, keyOriginal});
+ valueChangeListener.onValueChange(keyOriginal, lastValue, value);
}
lastValue = value;
@@ -165,7 +193,7 @@ private String resolveStringValue() {
{
break;
}
- String variableValue = config.access(varName).evaluateVariables(true).withLookupChain(lookupChain).getValue();
+ String variableValue = config.access(varName).evaluateVariables(true).get();
if (variableValue != null)
{
value = value.replace("${" + varName + "}", variableValue);
@@ -176,21 +204,16 @@ private String resolveStringValue() {
return value;
}
- @Override
+ //X @Override
public String getKey() {
return keyOriginal;
}
- @Override
+ //X @Override
public String getResolvedKey() {
return keyResolved;
}
- @Override
- public T getDefaultValue() {
- return defaultValue;
- }
-
private T convert(String value) {
if (String.class == configEntryType) {
return (T) value;
@@ -204,16 +227,12 @@ private T convert(String value) {
return (T) converter.convert(value);
}
- private T fallbackToDefaultIfEmpty(String key, T value, T defaultValue) {
- if (value == null || (value instanceof String && ((String)value).isEmpty()))
- {
- logger.log(Level.FINE, "no configured value found for key {0}, using default value {1}.",
- new Object[]{key, defaultValue});
-
- return defaultValue;
- }
-
- return value;
+ /**
+ * TODO feedback from gunnar: could be interesting to have this functionality also as Config#onChange(ConfigChanged)
+ * Callback which can be used with {@link #onChange(ConfigChanged)}
+ */
+ interface ConfigChanged {
+ void onValueChange(String key, T oldValue, T newValue);
}
}
diff --git a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java
index 2d504d3..ad56326 100644
--- a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java
+++ b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java
@@ -16,11 +16,11 @@
*/
package org.apache.geronimo.config;
-import io.microprofile.config.Config;
-import io.microprofile.config.ConfigProvider;
-import io.microprofile.config.spi.ConfigSource;
-import io.microprofile.config.spi.ConfigSourceProvider;
-import io.microprofile.config.spi.Converter;
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.spi.ConfigBuilder;
+import org.eclipse.microprofile.config.spi.ConfigSource;
+import org.eclipse.microprofile.config.spi.ConfigSourceProvider;
+import org.eclipse.microprofile.config.spi.Converter;
import org.apache.geronimo.config.configsource.PropertyFileConfigSourceProvider;
import org.apache.geronimo.config.configsource.SystemEnvConfigSource;
import org.apache.geronimo.config.configsource.SystemPropertyConfigSource;
@@ -30,38 +30,50 @@
import java.util.List;
import java.util.ServiceLoader;
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.Vetoed;
+
import static java.util.Arrays.asList;
/**
* @author Romain Manni-Bucau
* @author Mark Struberg
*/
-public class DefaultConfigBuilder implements ConfigProvider.ConfigBuilder {
+@Typed
+@Vetoed
+public class DefaultConfigBuilder implements ConfigBuilder {
protected ClassLoader forClassLoader;
private final List sources = new ArrayList<>();
private final List> converters = new ArrayList<>();
- private boolean ignoreDefaultSources = false;
+ private boolean ignoreDefaultSources = true;
+ private boolean ignoreDiscoveredSources = true;
+
+ @Override
+ public ConfigBuilder addDefaultSources() {
+ this.ignoreDefaultSources = false;
+ return this;
+ }
@Override
- public ConfigProvider.ConfigBuilder ignoreDefaultSources() {
- this.ignoreDefaultSources = true;
+ public ConfigBuilder addDiscoveredSources() {
+ this.ignoreDiscoveredSources = false;
return this;
}
@Override
- public ConfigProvider.ConfigBuilder forClassLoader(final ClassLoader loader) {
+ public ConfigBuilder forClassLoader(final ClassLoader loader) {
this.forClassLoader = loader;
return this;
}
@Override
- public ConfigProvider.ConfigBuilder withSources(final ConfigSource... sources) {
+ public ConfigBuilder withSources(final ConfigSource... sources) {
this.sources.addAll(asList(sources));
return this;
}
@Override
- public ConfigProvider.ConfigBuilder withConverters(Converter>... converters) {
+ public ConfigBuilder withConverters(Converter>... converters) {
this.converters.addAll(asList(converters));
return this;
}
@@ -69,24 +81,28 @@ public ConfigProvider.ConfigBuilder withConverters(Converter>... converters) {
@Override
public Config build() {
List configSources = new ArrayList<>();
+ if (forClassLoader == null) {
+ forClassLoader = Thread.currentThread().getContextClassLoader();
+ if (forClassLoader == null) {
+ forClassLoader = DefaultConfigProvider.class.getClassLoader();
+ }
+ }
if (!ignoreDefaultSources) {
configSources.addAll(getBuiltInConfigSources(forClassLoader));
}
configSources.addAll(sources);
- if (!ignoreDefaultSources) {
+ if (!ignoreDiscoveredSources) {
// load all ConfigSource services
ServiceLoader configSourceLoader = ServiceLoader.load(ConfigSource.class, forClassLoader);
- for (ConfigSource configSource : configSourceLoader) {
- configSources.add(configSource);
- }
+ configSourceLoader.forEach(configSource -> configSources.add(configSource));
// load all ConfigSources from ConfigSourceProviders
ServiceLoader configSourceProviderLoader = ServiceLoader.load(ConfigSourceProvider.class, forClassLoader);
- for (ConfigSourceProvider configSourceProvider : configSourceProviderLoader) {
- configSources.addAll(configSourceProvider.getConfigSources(forClassLoader));
- }
+ configSourceProviderLoader.forEach(configSourceProvider ->
+ configSourceProvider.getConfigSources(forClassLoader)
+ .forEach(configSource -> configSources.add(configSource)));
}
ConfigImpl config = new ConfigImpl();
@@ -104,7 +120,7 @@ protected Collection extends ConfigSource> getBuiltInConfigSources(ClassLoader
configSources.add(new SystemEnvConfigSource());
configSources.add(new SystemPropertyConfigSource());
- configSources.addAll(new PropertyFileConfigSourceProvider("META-INF/java-config.properties", true, forClassLoader).getConfigSources(forClassLoader));
+ configSources.addAll(new PropertyFileConfigSourceProvider("/META-INF/microprofile-config.properties", true, forClassLoader).getConfigSources(forClassLoader));
return configSources;
}
diff --git a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java
index 03adbff..d70b9d2 100644
--- a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java
+++ b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java
@@ -21,28 +21,32 @@
import java.util.Iterator;
import java.util.Map;
import java.util.WeakHashMap;
-import io.microprofile.config.Config;
-import io.microprofile.config.ConfigProvider;
+
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.Vetoed;
+
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.spi.ConfigBuilder;
+import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
/**
* @author Mark Struberg
*/
-public class DefaultConfigProvider implements ConfigProvider.SPI {
+@Typed
+@Vetoed
+public class DefaultConfigProvider extends ConfigProviderResolver {
- protected static Map> configs
+ private static Map> configs
= Collections.synchronizedMap(new WeakHashMap>());
@Override
public Config getConfig() {
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- if (cl == null) {
- cl = DefaultConfigProvider.class.getClassLoader();
- }
- return getConfig(cl);
+ return getConfig(null);
}
+
@Override
public Config getConfig(ClassLoader forClassLoader) {
@@ -51,7 +55,7 @@ public Config getConfig(ClassLoader forClassLoader) {
synchronized (DefaultConfigProvider.class) {
config = existingConfig(forClassLoader);
if (config == null) {
- config = createConfig(forClassLoader);
+ config = getBuilder().forClassLoader(forClassLoader).addDefaultSources().addDiscoveredSources().build();
registerConfig(config, forClassLoader);
}
}
@@ -64,28 +68,31 @@ Config existingConfig(ClassLoader forClassLoader) {
return configRef != null ? configRef.get() : null;
}
- protected Config createConfig(ClassLoader forClassLoader) {
- return newConfig().forClassLoader(forClassLoader).build();
- }
- void registerConfig(Config config, ClassLoader forClassLoader) {
+ @Override
+ public void registerConfig(Config config, ClassLoader forClassLoader) {
synchronized (DefaultConfigProvider.class) {
configs.put(forClassLoader, new WeakReference<>(config));
}
}
@Override
- public ConfigProvider.ConfigBuilder newConfig() {
+ public ConfigBuilder getBuilder() {
return new DefaultConfigBuilder();
}
- @Override
- public ConfigProvider.ConfigBuilder registerConfig() {
- return new ManualApplicationConfigBuilder(this);
- }
@Override
public void releaseConfig(Config config) {
+ if (config == null) {
+ // get the config from the current TCCL
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ if (classLoader == null) {
+ classLoader = DefaultConfigProvider.class.getClassLoader();
+ }
+ config = existingConfig(classLoader);
+ }
+
if (config != null) {
synchronized (DefaultConfigProvider.class) {
Iterator>> it = configs.entrySet().iterator();
diff --git a/impl/src/main/java/org/apache/geronimo/config/ManualApplicationConfigBuilder.java b/impl/src/main/java/org/apache/geronimo/config/ManualApplicationConfigBuilder.java
deleted file mode 100644
index 9b91edf..0000000
--- a/impl/src/main/java/org/apache/geronimo/config/ManualApplicationConfigBuilder.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.geronimo.config;
-
-import io.microprofile.config.Config;
-import io.microprofile.config.ConfigProvider;
-
-/**
- * @author Mark Struberg
- */
-public class ManualApplicationConfigBuilder extends DefaultConfigBuilder {
- private DefaultConfigProvider configProvider;
-
- public ManualApplicationConfigBuilder(DefaultConfigProvider configProvider) {
- this.configProvider = configProvider;
- }
-
- @Override
- public synchronized Config build() {
- Config config = super.build();
- ClassLoader cl = forClassLoader;
- if (cl == null) {
- cl = Thread.currentThread().getContextClassLoader();
- if (cl == null) {
- cl = ConfigProvider.SPI.class.getClassLoader();
- }
- }
- Config oldConfig = configProvider.existingConfig(cl);
- if (oldConfig != null) {
- throw new IllegalStateException("This Application already has a registered Configuration!");
- }
- configProvider.registerConfig(config, cl);
- return config;
- }
-}
diff --git a/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigExtension.java b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigExtension.java
new file mode 100644
index 0000000..94b1b39
--- /dev/null
+++ b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigExtension.java
@@ -0,0 +1,102 @@
+/*
+ * 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.geronimo.config.cdi;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeShutdown;
+import javax.enterprise.inject.spi.DeploymentException;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.ProcessInjectionPoint;
+import javax.inject.Provider;
+
+import org.apache.geronimo.config.DefaultConfigProvider;
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+
+/**
+ * @author Mark Struberg
+ */
+public class ConfigExtension implements Extension {
+
+ private Config config;
+
+ private Set injectionPoints = new HashSet<>();
+
+ public void collectConfigProducer(@Observes ProcessInjectionPoint, ?> pip) {
+ ConfigProperty configProperty = pip.getInjectionPoint().getAnnotated().getAnnotation(ConfigProperty.class);
+ if (configProperty != null) {
+ injectionPoints.add(pip.getInjectionPoint());
+ }
+ }
+
+ public void registerConfigProducer(@Observes AfterBeanDiscovery abd, BeanManager bm) {
+ Set types = injectionPoints.stream()
+ .filter(ip -> ip.getType() instanceof Class)
+ .map(ip -> (Class) ip.getType())
+ .collect(Collectors.toSet());
+
+ // Provider and Optional are ParameterizedTypes and not a Class, so we need to add them manually
+ types.add(Provider.class);
+ types.add(Optional.class);
+
+ types.forEach(type -> abd.addBean(new ConfigInjectionBean(bm, type)));
+ }
+
+ public void validate(@Observes AfterDeploymentValidation add) {
+ List deploymentProblems = new ArrayList<>();
+
+ config = ConfigProvider.getConfig();
+
+ for (InjectionPoint injectionPoint : injectionPoints) {
+ Type type = injectionPoint.getType();
+ ConfigProperty configProperty = injectionPoint.getAnnotated().getAnnotation(ConfigProperty.class);
+ if (type instanceof Class) {
+ // a direct injection of a ConfigProperty
+ // that means a Converter must exist.
+ String key = ConfigInjectionBean.getConfigKey(injectionPoint, configProperty);
+ if (!config.getOptionalValue(key, (Class) type).isPresent()) {
+ deploymentProblems.add("No Config Value exists for " + key);
+ }
+ }
+ }
+
+ if (!deploymentProblems.isEmpty()) {
+ add.addDeploymentProblem(new DeploymentException("Error while validating Configuration\n"
+ + String.join("\n", deploymentProblems)));
+ }
+
+ }
+
+ public void shutdown(@Observes BeforeShutdown bsd) {
+ DefaultConfigProvider.instance().releaseConfig(config);
+ }
+
+
+}
diff --git a/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java
new file mode 100644
index 0000000..ba2b39b
--- /dev/null
+++ b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java
@@ -0,0 +1,250 @@
+/*
+ * 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.geronimo.config.cdi;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.AnnotatedMember;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.DeploymentException;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.PassivationCapable;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.inject.Provider;
+
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
+
+/**
+ * @author Mark Struberg
+ */
+public class ConfigInjectionBean implements Bean, PassivationCapable {
+
+ private final static Set QUALIFIERS = new HashSet<>();
+ static {
+ QUALIFIERS.add(new ConfigPropertyLiteral());
+ }
+
+ private final BeanManager bm;
+ private final Class rawType;
+ private final Set types;
+
+ /**
+ * only access via {@link #getConfig(}
+ */
+ private Config _config;
+
+ public ConfigInjectionBean(BeanManager bm, Type type) {
+ this.bm = bm;
+
+ types = new HashSet<>();
+ types.add(type);
+ rawType = getRawType(type);
+ }
+
+ private Class getRawType(Type type) {
+ if (type instanceof Class) {
+ return (Class) type;
+ }
+ else if (type instanceof ParameterizedType) {
+ ParameterizedType paramType = (ParameterizedType) type;
+
+ return (Class) paramType.getRawType();
+ }
+
+ throw new UnsupportedOperationException("No idea how to handle " + type);
+ }
+
+ @Override
+ public Set getInjectionPoints() {
+ return Collections.EMPTY_SET;
+ }
+
+ @Override
+ public Class> getBeanClass() {
+ return rawType;
+ }
+
+ @Override
+ public boolean isNullable() {
+ return false;
+ }
+
+ @Override
+ public T create(CreationalContext context) {
+ Set> beans = bm.getBeans(InjectionPoint.class);
+ Bean> bean = bm.resolve(beans);
+ InjectionPoint ip = (InjectionPoint) bm.getReference(bean, InjectionPoint.class, context);
+ if (ip == null) {
+ throw new IllegalStateException("Could not retrieve InjectionPoint");
+ }
+ Annotated annotated = ip.getAnnotated();
+ ConfigProperty configProperty = annotated.getAnnotation(ConfigProperty.class);
+ String key = configProperty.name();
+
+ if (annotated.getBaseType() instanceof ParameterizedType) {
+ ParameterizedType paramType = (ParameterizedType) annotated.getBaseType();
+ Type rawType = paramType.getRawType();
+
+ // handle Provider
+ if (rawType instanceof Class && ((Class) rawType).isAssignableFrom(Provider.class) && paramType.getActualTypeArguments().length == 1) {
+ Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check type again, etc
+ return (T) new ConfigValueProvider(getConfig(), key, clazz);
+ }
+
+ // handle Optional
+ if (rawType instanceof Class && ((Class) rawType).isAssignableFrom(Optional.class) && paramType.getActualTypeArguments().length == 1) {
+ Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check type again, etc
+ return (T) getConfig().getOptionalValue(key, clazz);
+ }
+ }
+ else {
+ Class clazz = (Class) annotated.getBaseType();
+ return (T) getConfig().getValue(key, clazz);
+ }
+
+ throw new IllegalStateException("unhandled ConfigProperty");
+ }
+
+
+ /**
+ * Get the property key to use.
+ * In case the {@link ConfigProperty#name()} is empty we will try to determine the key name from the InjectionPoint.
+ */
+ public static String getConfigKey(InjectionPoint ip, ConfigProperty configProperty) {
+ String key = configProperty.name();
+ if (key.length() > 0) {
+ return key;
+ }
+ if (ip.getAnnotated() instanceof AnnotatedMember) {
+ AnnotatedMember member = (AnnotatedMember) ip.getAnnotated();
+ AnnotatedType declaringType = member.getDeclaringType();
+ if (declaringType != null) {
+ String[] parts = declaringType.getJavaClass().getName().split(".");
+ String cn = parts[parts.length-1];
+ parts[parts.length-1] = Character.toLowerCase(cn.charAt(0)) + (cn.length() > 1 ? cn.substring(1) : "");
+ StringBuilder sb = new StringBuilder(parts[0]);
+ for (int i = 1; i < parts.length; i++) {
+ sb.append(".").append(parts[i]);
+ }
+
+ // now add the field name
+ sb.append(".").append(member.getJavaMember().getName());
+ return sb.toString();
+ }
+ }
+
+ throw new IllegalStateException("Could not find default name for @ConfigProperty InjectionPoint " + ip);
+ }
+
+ public Config getConfig() {
+ if (_config == null) {
+ _config = ConfigProvider.getConfig();
+ }
+ return _config;
+ }
+
+ @Override
+ public void destroy(T instance, CreationalContext context) {
+
+ }
+
+ @Override
+ public Set getTypes() {
+ return types;
+ }
+
+ @Override
+ public Set getQualifiers() {
+ return QUALIFIERS;
+ }
+
+ @Override
+ public Class extends Annotation> getScope() {
+ return Dependent.class;
+ }
+
+ @Override
+ public String getName() {
+ return null;
+ }
+
+ @Override
+ public Set> getStereotypes() {
+ return Collections.EMPTY_SET;
+ }
+
+ @Override
+ public boolean isAlternative() {
+ return true;
+ }
+
+ @Override
+ public String getId() {
+ return "ConfigInjectionBean_" + rawType.getName();
+ }
+
+ private static class ConfigPropertyLiteral extends AnnotationLiteral implements ConfigProperty {
+ @Override
+ public String name() {
+ return "";
+ }
+
+ @Override
+ public String defaultValue() {
+ return "";
+ }
+ }
+
+ public static class ConfigValueProvider implements Provider, Serializable {
+ private transient Config config;
+ private final String key;
+ private final Class type;
+
+ ConfigValueProvider(Config config, String key, Class type) {
+ this.config = config;
+ this.key = key;
+ this.type = type;
+ }
+
+ @Override
+ public T get() {
+ return (T) config.getValue(key, type);
+ }
+
+ private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ config = ConfigProviderResolver.instance().getConfig();
+ }
+
+ }
+}
diff --git a/tck/src/main/java/io/microprofile/config/tck/converters/Duck.java b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionProducer.java
similarity index 57%
rename from tck/src/main/java/io/microprofile/config/tck/converters/Duck.java
rename to impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionProducer.java
index 23a0542..ce16e8e 100644
--- a/tck/src/main/java/io/microprofile/config/tck/converters/Duck.java
+++ b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionProducer.java
@@ -14,20 +14,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.microprofile.config.tck.converters;
+package org.apache.geronimo.config.cdi;
+
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.ConfigProvider;
/**
- * @author Mark Struberg
+ * @author Mark Struberg
*/
-public class Duck {
- private final String name;
+@ApplicationScoped
+public class ConfigInjectionProducer {
+ private Config config;
- public Duck(String name) {
- this.name = name;
+ @PostConstruct
+ void init() {
+ config = ConfigProvider.getConfig();
}
- public String getName() {
- return name;
+ @Produces
+ @ApplicationScoped
+ public Config createConfig() {
+ return config;
}
+
+
}
diff --git a/impl/src/main/java/org/apache/geronimo/config/configsource/BaseConfigSource.java b/impl/src/main/java/org/apache/geronimo/config/configsource/BaseConfigSource.java
index 9ffbc10..d7117be 100644
--- a/impl/src/main/java/org/apache/geronimo/config/configsource/BaseConfigSource.java
+++ b/impl/src/main/java/org/apache/geronimo/config/configsource/BaseConfigSource.java
@@ -21,7 +21,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;
-import io.microprofile.config.spi.ConfigSource;
+import org.eclipse.microprofile.config.spi.ConfigSource;
/**
@@ -31,6 +31,9 @@
* @author Gerhard Petracek
*/
public abstract class BaseConfigSource implements ConfigSource {
+
+ public final static String CONFIG_ORDINAL = "config_ordinal";
+
protected Logger log = Logger.getLogger(getClass().getName());
private int ordinal = 1000; // default
@@ -50,7 +53,7 @@ public int getOrdinal() {
protected void initOrdinal(int defaultOrdinal) {
ordinal = defaultOrdinal;
- String configuredOrdinalString = getPropertyValue(ConfigSource.CONFIG_ORDINAL);
+ String configuredOrdinalString = getValue(CONFIG_ORDINAL);
try {
if (configuredOrdinalString != null) {
diff --git a/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSource.java b/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSource.java
index d98826d..e7c0b2c 100644
--- a/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSource.java
+++ b/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSource.java
@@ -22,9 +22,14 @@
import java.util.Map;
import java.util.Properties;
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.Vetoed;
+
/**
* @author Mark Struberg
*/
+@Typed
+@Vetoed
public class PropertyFileConfigSource extends BaseConfigSource {
private Map properties;
private String fileName;
@@ -42,12 +47,12 @@ public PropertyFileConfigSource(URL propertyFileUrl) {
* @return value for the given key or null if there is no configured value
*/
@Override
- public String getPropertyValue(String key) {
- return (String) properties.get(key);
+ public String getValue(String key) {
+ return properties.get(key);
}
@Override
- public String getConfigName() {
+ public String getName() {
return fileName;
}
diff --git a/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSourceProvider.java b/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSourceProvider.java
index 6404f92..abbf199 100644
--- a/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSourceProvider.java
+++ b/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSourceProvider.java
@@ -26,8 +26,11 @@
import java.util.logging.Level;
import java.util.logging.Logger;
-import io.microprofile.config.spi.ConfigSource;
-import io.microprofile.config.spi.ConfigSourceProvider;
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.Vetoed;
+
+import org.eclipse.microprofile.config.spi.ConfigSource;
+import org.eclipse.microprofile.config.spi.ConfigSourceProvider;
/**
@@ -36,6 +39,8 @@
*
* @author Mark Struberg
*/
+@Typed
+@Vetoed
public class PropertyFileConfigSourceProvider implements ConfigSourceProvider {
private static final Logger LOG = Logger.getLogger(PropertyFileConfigSourceProvider.class.getName());
diff --git a/impl/src/main/java/org/apache/geronimo/config/configsource/SystemEnvConfigSource.java b/impl/src/main/java/org/apache/geronimo/config/configsource/SystemEnvConfigSource.java
index bf5e171..6eefca5 100644
--- a/impl/src/main/java/org/apache/geronimo/config/configsource/SystemEnvConfigSource.java
+++ b/impl/src/main/java/org/apache/geronimo/config/configsource/SystemEnvConfigSource.java
@@ -21,7 +21,10 @@
import java.util.Map;
-import io.microprofile.config.spi.ConfigSource;
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.Vetoed;
+
+import org.eclipse.microprofile.config.spi.ConfigSource;
/**
* {@link ConfigSource} which uses {@link System#getenv()}
@@ -31,6 +34,8 @@
*
* @author Mark Struberg
*/
+@Typed
+@Vetoed
public class SystemEnvConfigSource extends BaseConfigSource {
private Map configValues;
@@ -40,7 +45,7 @@ public SystemEnvConfigSource() {
}
@Override
- public String getConfigName() {
+ public String getName() {
return "system_env";
}
@@ -50,7 +55,7 @@ public Map getProperties() {
}
@Override
- public String getPropertyValue(String key) {
+ public String getValue(String key) {
String val = configValues.get(key);
if (val == null || val.isEmpty()) {
val = configValues.get(key.replace('.', '_'));
diff --git a/impl/src/main/java/org/apache/geronimo/config/configsource/SystemPropertyConfigSource.java b/impl/src/main/java/org/apache/geronimo/config/configsource/SystemPropertyConfigSource.java
index 73ce7f1..4d741bd 100644
--- a/impl/src/main/java/org/apache/geronimo/config/configsource/SystemPropertyConfigSource.java
+++ b/impl/src/main/java/org/apache/geronimo/config/configsource/SystemPropertyConfigSource.java
@@ -20,13 +20,18 @@
import java.util.Map;
-import io.microprofile.config.spi.ConfigSource;
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.Vetoed;
+
+import org.eclipse.microprofile.config.spi.ConfigSource;
/**
* {@link ConfigSource} which uses {@link System#getProperties()}
*
* @author Mark Struberg
*/
+@Typed
+@Vetoed
public class SystemPropertyConfigSource extends BaseConfigSource {
public SystemPropertyConfigSource() {
initOrdinal(400);
@@ -38,12 +43,12 @@ public Map getProperties() {
}
@Override
- public String getPropertyValue(String key) {
+ public String getValue(String key) {
return System.getProperty(key);
}
@Override
- public String getConfigName() {
+ public String getName() {
return "system-properties";
}
}
diff --git a/impl/src/main/java/org/apache/geronimo/config/converters/BooleanConverter.java b/impl/src/main/java/org/apache/geronimo/config/converters/BooleanConverter.java
index 72e03b4..9f70a33 100644
--- a/impl/src/main/java/org/apache/geronimo/config/converters/BooleanConverter.java
+++ b/impl/src/main/java/org/apache/geronimo/config/converters/BooleanConverter.java
@@ -16,14 +16,16 @@
*/
package org.apache.geronimo.config.converters;
-import io.microprofile.config.spi.Converter;
+import org.eclipse.microprofile.config.spi.Converter;
import javax.annotation.Priority;
+import javax.enterprise.inject.Vetoed;
/**
* @author Mark Struberg
*/
@Priority(1)
+@Vetoed
public class BooleanConverter implements Converter {
public static final BooleanConverter INSTANCE = new BooleanConverter();
@@ -35,6 +37,7 @@ public Boolean convert(String value) {
|| "1".equalsIgnoreCase(value)
|| "YES".equalsIgnoreCase(value)
|| "Y".equalsIgnoreCase(value)
+ || "ON".equalsIgnoreCase(value)
|| "JA".equalsIgnoreCase(value)
|| "J".equalsIgnoreCase(value)
|| "OUI".equalsIgnoreCase(value);
diff --git a/impl/src/main/java/org/apache/geronimo/config/converters/DoubleConverter.java b/impl/src/main/java/org/apache/geronimo/config/converters/DoubleConverter.java
index c32860f..28cd9f8 100644
--- a/impl/src/main/java/org/apache/geronimo/config/converters/DoubleConverter.java
+++ b/impl/src/main/java/org/apache/geronimo/config/converters/DoubleConverter.java
@@ -16,14 +16,16 @@
*/
package org.apache.geronimo.config.converters;
-import io.microprofile.config.spi.Converter;
+import org.eclipse.microprofile.config.spi.Converter;
import javax.annotation.Priority;
+import javax.enterprise.inject.Vetoed;
/**
* @author Mark Struberg
*/
@Priority(1)
+@Vetoed
public class DoubleConverter implements Converter {
public static final DoubleConverter INSTANCE = new DoubleConverter();
diff --git a/tck/src/main/java/io/microprofile/config/tck/CustomConfigSourceTest.java b/impl/src/main/java/org/apache/geronimo/config/converters/DurationConverter.java
similarity index 54%
rename from tck/src/main/java/io/microprofile/config/tck/CustomConfigSourceTest.java
rename to impl/src/main/java/org/apache/geronimo/config/converters/DurationConverter.java
index 5a8d80d..8f04abb 100644
--- a/tck/src/main/java/io/microprofile/config/tck/CustomConfigSourceTest.java
+++ b/impl/src/main/java/org/apache/geronimo/config/converters/DurationConverter.java
@@ -14,22 +14,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.microprofile.config.tck;
+package org.apache.geronimo.config.converters;
-import io.microprofile.config.Config;
-import io.microprofile.config.ConfigProvider;
-import org.testng.Assert;
-import org.testng.annotations.Test;
+import java.time.Duration;
+import java.time.format.DateTimeParseException;
+
+import javax.annotation.Priority;
+import javax.enterprise.inject.Vetoed;
+
+import org.eclipse.microprofile.config.spi.Converter;
/**
* @author Mark Struberg
*/
-public class CustomConfigSourceTest {
+@Priority(1)
+@Vetoed
+public class DurationConverter implements Converter {
- @Test
- public void testConfigSourceProvider() {
- Config config = ConfigProvider.getConfig();
+ public static final DurationConverter INSTANCE = new DurationConverter();
- Assert.assertEquals(config.getValue("tck.config.test.customDbConfig.key1"), "valueFromDb1");
+ @Override
+ public Duration convert(String value) {
+ if (value != null) {
+ try {
+ return Duration.parse(value);
+ }
+ catch (DateTimeParseException dtpe) {
+ throw new IllegalArgumentException(dtpe);
+ }
+ }
+ return null;
}
}
diff --git a/impl/src/main/java/org/apache/geronimo/config/converters/FloatConverter.java b/impl/src/main/java/org/apache/geronimo/config/converters/FloatConverter.java
index fa7372a..94c14d7 100644
--- a/impl/src/main/java/org/apache/geronimo/config/converters/FloatConverter.java
+++ b/impl/src/main/java/org/apache/geronimo/config/converters/FloatConverter.java
@@ -17,13 +17,15 @@
package org.apache.geronimo.config.converters;
import javax.annotation.Priority;
+import javax.enterprise.inject.Vetoed;
-import io.microprofile.config.spi.Converter;
+import org.eclipse.microprofile.config.spi.Converter;
/**
* @author Mark Struberg
*/
@Priority(1)
+@Vetoed
public class FloatConverter implements Converter {
public static final FloatConverter INSTANCE = new FloatConverter();
diff --git a/impl/src/main/java/org/apache/geronimo/config/converters/IntegerConverter.java b/impl/src/main/java/org/apache/geronimo/config/converters/IntegerConverter.java
index cb76c63..d34c468 100644
--- a/impl/src/main/java/org/apache/geronimo/config/converters/IntegerConverter.java
+++ b/impl/src/main/java/org/apache/geronimo/config/converters/IntegerConverter.java
@@ -17,13 +17,15 @@
package org.apache.geronimo.config.converters;
import javax.annotation.Priority;
+import javax.enterprise.inject.Vetoed;
-import io.microprofile.config.spi.Converter;
+import org.eclipse.microprofile.config.spi.Converter;
/**
* @author Mark Struberg
*/
@Priority(1)
+@Vetoed
public class IntegerConverter implements Converter {
public static final IntegerConverter INSTANCE = new IntegerConverter();
diff --git a/impl/src/main/java/org/apache/geronimo/config/converters/LocalDateConverter.java b/impl/src/main/java/org/apache/geronimo/config/converters/LocalDateConverter.java
new file mode 100644
index 0000000..41b9968
--- /dev/null
+++ b/impl/src/main/java/org/apache/geronimo/config/converters/LocalDateConverter.java
@@ -0,0 +1,48 @@
+/*
+ * 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.geronimo.config.converters;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeParseException;
+
+import javax.annotation.Priority;
+import javax.enterprise.inject.Vetoed;
+
+import org.eclipse.microprofile.config.spi.Converter;
+
+/**
+ * @author Mark Struberg
+ */
+@Priority(1)
+@Vetoed
+public class LocalDateConverter implements Converter {
+
+ public static final LocalDateConverter INSTANCE = new LocalDateConverter();
+
+ @Override
+ public LocalDate convert(String value) {
+ if (value != null) {
+ try {
+ return LocalDate.parse(value);
+ }
+ catch (DateTimeParseException dtpe) {
+ throw new IllegalArgumentException(dtpe);
+ }
+ }
+ return null;
+ }
+}
diff --git a/tck/src/main/java/io/microprofile/config/tck/configsources/SampleYamlConfigSource.java b/impl/src/main/java/org/apache/geronimo/config/converters/LocalDateTimeConverter.java
similarity index 54%
rename from tck/src/main/java/io/microprofile/config/tck/configsources/SampleYamlConfigSource.java
rename to impl/src/main/java/org/apache/geronimo/config/converters/LocalDateTimeConverter.java
index 1d64de5..fe5c09e 100644
--- a/tck/src/main/java/io/microprofile/config/tck/configsources/SampleYamlConfigSource.java
+++ b/impl/src/main/java/org/apache/geronimo/config/converters/LocalDateTimeConverter.java
@@ -14,42 +14,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.microprofile.config.tck.configsources;
+package org.apache.geronimo.config.converters;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeParseException;
-import io.microprofile.config.spi.ConfigSource;
+import javax.annotation.Priority;
+import javax.enterprise.inject.Vetoed;
+
+import org.eclipse.microprofile.config.spi.Converter;
/**
* @author Mark Struberg
*/
-public class SampleYamlConfigSource implements ConfigSource {
- private Map config = new HashMap<>();
-
- public SampleYamlConfigSource(URL url) {
- config.put("tck.config.test.sampleyaml.key1", "yamlvalue1");
- }
-
- @Override
- public int getOrdinal() {
- return config.get("ordinal") != null ? Integer.valueOf(config.get("ordinal")) : 110;
- }
+@Priority(1)
+@Vetoed
+public class LocalDateTimeConverter implements Converter {
- @Override
- public Map getProperties() {
- return config;
- }
-
- @Override
- public String getPropertyValue(String key) {
- return config.get(key);
- }
+ public static final LocalDateTimeConverter INSTANCE = new LocalDateTimeConverter();
@Override
- public String getConfigName() {
+ public LocalDateTime convert(String value) {
+ if (value != null) {
+ try {
+ return LocalDateTime.parse(value);
+ }
+ catch (DateTimeParseException dtpe) {
+ throw new IllegalArgumentException(dtpe);
+ }
+ }
return null;
}
-
}
diff --git a/impl/src/main/java/org/apache/geronimo/config/converters/LocalTimeConverter.java b/impl/src/main/java/org/apache/geronimo/config/converters/LocalTimeConverter.java
new file mode 100644
index 0000000..326c167
--- /dev/null
+++ b/impl/src/main/java/org/apache/geronimo/config/converters/LocalTimeConverter.java
@@ -0,0 +1,48 @@
+/*
+ * 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.geronimo.config.converters;
+
+import java.time.LocalTime;
+import java.time.format.DateTimeParseException;
+
+import javax.annotation.Priority;
+import javax.enterprise.inject.Vetoed;
+
+import org.eclipse.microprofile.config.spi.Converter;
+
+/**
+ * @author Mark Struberg
+ */
+@Priority(1)
+@Vetoed
+public class LocalTimeConverter implements Converter {
+
+ public static final LocalTimeConverter INSTANCE = new LocalTimeConverter();
+
+ @Override
+ public LocalTime convert(String value) {
+ if (value != null) {
+ try {
+ return LocalTime.parse(value);
+ }
+ catch (DateTimeParseException dtpe) {
+ throw new IllegalArgumentException(dtpe);
+ }
+ }
+ return null;
+ }
+}
diff --git a/impl/src/main/java/org/apache/geronimo/config/converters/LongConverter.java b/impl/src/main/java/org/apache/geronimo/config/converters/LongConverter.java
index 4df6eaa..007d1c7 100644
--- a/impl/src/main/java/org/apache/geronimo/config/converters/LongConverter.java
+++ b/impl/src/main/java/org/apache/geronimo/config/converters/LongConverter.java
@@ -16,14 +16,16 @@
*/
package org.apache.geronimo.config.converters;
-import io.microprofile.config.spi.Converter;
+import org.eclipse.microprofile.config.spi.Converter;
import javax.annotation.Priority;
+import javax.enterprise.inject.Vetoed;
/**
* @author Mark Struberg
*/
@Priority(1)
+@Vetoed
public class LongConverter implements Converter {
public static final LongConverter INSTANCE = new LongConverter();
diff --git a/tck/src/main/java/io/microprofile/config/tck/ConfigSourceProviderTest.java b/impl/src/main/java/org/apache/geronimo/config/converters/StringConverter.java
similarity index 60%
rename from tck/src/main/java/io/microprofile/config/tck/ConfigSourceProviderTest.java
rename to impl/src/main/java/org/apache/geronimo/config/converters/StringConverter.java
index 28a65a9..0d5ccbc 100644
--- a/tck/src/main/java/io/microprofile/config/tck/ConfigSourceProviderTest.java
+++ b/impl/src/main/java/org/apache/geronimo/config/converters/StringConverter.java
@@ -14,22 +14,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.microprofile.config.tck;
+package org.apache.geronimo.config.converters;
-import io.microprofile.config.Config;
-import io.microprofile.config.ConfigProvider;
-import org.testng.Assert;
-import org.testng.annotations.Test;
+import javax.annotation.Priority;
+import javax.enterprise.inject.Vetoed;
+
+import org.eclipse.microprofile.config.spi.Converter;
/**
- * @author Mark Struberg
+ * 1:1 string output. Just to make converter logic happy.
+ *
+ * @author Mark Struberg
*/
-public class ConfigSourceProviderTest {
+@Priority(1)
+@Vetoed
+public class StringConverter implements Converter {
- @Test
- public void testConfigSourceProvider() {
- Config config = ConfigProvider.getConfig();
+ public static final StringConverter INSTANCE = new StringConverter();
- Assert.assertEquals(config.getValue("tck.config.test.sampleyaml.key1"), "yamlvalue1");
+ @Override
+ public String convert(String value) {
+ return value;
}
}
diff --git a/impl/src/main/resources/META-INF/beans.xml b/impl/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..48bb5d2
--- /dev/null
+++ b/impl/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,18 @@
+
diff --git a/tck/src/main/resources/META-INF/services/io.microprofile.config.spi.ConfigSource b/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
similarity index 92%
rename from tck/src/main/resources/META-INF/services/io.microprofile.config.spi.ConfigSource
rename to impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
index 677a9fb..f949a49 100644
--- a/tck/src/main/resources/META-INF/services/io.microprofile.config.spi.ConfigSource
+++ b/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -17,4 +17,4 @@
# under the License.
#
-io.microprofile.config.tck.configsources.CustomDbConfigSource
\ No newline at end of file
+org.apache.geronimo.config.cdi.ConfigExtension
\ No newline at end of file
diff --git a/impl/src/main/resources/META-INF/services/io.microprofile.config.ConfigProvider$SPI b/impl/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigProviderResolver
similarity index 100%
rename from impl/src/main/resources/META-INF/services/io.microprofile.config.ConfigProvider$SPI
rename to impl/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigProviderResolver
diff --git a/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigArchiveProcessor.java b/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigArchiveProcessor.java
new file mode 100644
index 0000000..7316c01
--- /dev/null
+++ b/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigArchiveProcessor.java
@@ -0,0 +1,56 @@
+/*
+ * 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.geronimo.config.test;
+
+import org.apache.geronimo.config.ConfigImpl;
+import org.apache.geronimo.config.DefaultConfigProvider;
+import org.apache.geronimo.config.cdi.ConfigInjectionProducer;
+import org.apache.geronimo.config.configsource.BaseConfigSource;
+import org.apache.geronimo.config.converters.BooleanConverter;
+import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
+import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
+import org.jboss.arquillian.test.spi.TestClass;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+
+/**
+ * Adds the whole Config implementation classes and resources to the
+ * Arqillian deployment archive. This is needed to have the container
+ * pick up the beans from within the impl for the TCK tests.
+ *
+ * @author Mark Struberg
+ */
+public class GeronimoConfigArchiveProcessor implements ApplicationArchiveProcessor {
+
+ @Override
+ public void process(Archive> applicationArchive, TestClass testClass) {
+ if (applicationArchive instanceof WebArchive) {
+ JavaArchive configJar = ShrinkWrap
+ .create(JavaArchive.class, "geronimo-config-impl.jar")
+ .addPackage(ConfigImpl.class.getPackage())
+ .addPackage(BooleanConverter.class.getPackage())
+ .addPackage(BaseConfigSource.class.getPackage())
+ .addPackage(ConfigInjectionProducer.class.getPackage())
+ .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
+ .addAsServiceProvider(ConfigProviderResolver.class, DefaultConfigProvider.class);
+ ((WebArchive) applicationArchive).addAsLibraries(configJar);
+ }
+ }
+}
diff --git a/tck/src/main/java/io/microprofile/config/tck/converters/DuckConverter.java b/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigExtension.java
similarity index 62%
rename from tck/src/main/java/io/microprofile/config/tck/converters/DuckConverter.java
rename to impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigExtension.java
index b653fc1..22335a0 100644
--- a/tck/src/main/java/io/microprofile/config/tck/converters/DuckConverter.java
+++ b/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigExtension.java
@@ -14,17 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.microprofile.config.tck.converters;
+package org.apache.geronimo.config.test;
-import io.microprofile.config.spi.Converter;
+import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
+import org.jboss.arquillian.core.spi.LoadableExtension;
/**
- * @author Mark Struberg
+ * @author Mark Struberg
*/
-public class DuckConverter implements Converter {
-
+public class GeronimoConfigExtension implements LoadableExtension {
@Override
- public Duck convert(String value) {
- return new Duck(value);
+ public void register(ExtensionBuilder extensionBuilder) {
+ extensionBuilder.service(ApplicationArchiveProcessor.class, GeronimoConfigArchiveProcessor.class);
}
}
diff --git a/tck/src/main/resources/META-INF/services/io.microprofile.config.spi.ConfigSourceProvider b/impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
similarity index 92%
rename from tck/src/main/resources/META-INF/services/io.microprofile.config.spi.ConfigSourceProvider
rename to impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
index bbcd7a0..91c04d4 100644
--- a/tck/src/main/resources/META-INF/services/io.microprofile.config.spi.ConfigSourceProvider
+++ b/impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
@@ -17,4 +17,5 @@
# under the License.
#
-io.microprofile.config.tck.configsources.CustomConfigSourceProvider
\ No newline at end of file
+
+org.apache.geronimo.config.test.GeronimoConfigExtension
\ No newline at end of file
diff --git a/impl/tck-suite.xml b/impl/tck-suite.xml
index ab445be..a9fd699 100644
--- a/impl/tck-suite.xml
+++ b/impl/tck-suite.xml
@@ -15,18 +15,14 @@
the specific language governing permissions and limitations under the
License.
-->
-
-
-
-
-
+
+
-
+
-
diff --git a/pom.xml b/pom.xml
index cf08594..05e8c78 100644
--- a/pom.xml
+++ b/pom.xml
@@ -45,15 +45,12 @@
- 1.7
- 1.7
+ 1.8
+ 1.8
- api
- tckimpl
- spec
@@ -70,7 +67,7 @@
- .travis.yml
+ .travis.yml.*
diff --git a/spec/pom.xml b/spec/pom.xml
deleted file mode 100644
index 6389337..0000000
--- a/spec/pom.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-
-
-
- 4.0.0
-
-
-
- org.apache.geronimo.config
- config-parent
- 0.1-SNAPSHOT
-
-
- org.apache.geronimo.config
- config-spec
- pom
-
-
-
- Apache License, Version 2.0
- https://www.apache.org/licenses/LICENSE-2.0.txt
- repo
- A business-friendly OSS license
-
-
-
-
- 1.5.3
- 1.5.0-alpha.10.1
- Apache License v 2.0
- MMMM dd, yyyy
- ${maven.build.timestamp}
-
-
-
- clean package
-
-
- org.asciidoctor
- asciidoctor-maven-plugin
- ${asciidoctor-maven.version}
-
-
- org.asciidoctor
- asciidoctorj-pdf
- ${asciidoctorj-pdf.version}
-
-
-
-
- generate-pdf-doc
- generate-resources
-
- process-asciidoc
-
-
- pdf
-
-
-
- output-html
- generate-resources
-
- process-asciidoc
-
-
- html5
-
-
-
-
- microprofile-config-spec.asciidoc
- coderay
-
- Apache License v2.0
-
-
-
-
-
-
-
diff --git a/spec/src/main/asciidoc/architecture.asciidoc b/spec/src/main/asciidoc/architecture.asciidoc
deleted file mode 100644
index b715436..0000000
--- a/spec/src/main/asciidoc/architecture.asciidoc
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// Licensed under the Apache License, Version 2.0 (the "License").
-// See the NOTICE file distributed with this work
-// for additional information regarding copyright ownership.
-// The author 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.
-//
-
-[[architecture]]
-== Architecture
-
-This specification defines an easy to use and flexible system for application configuration.
-It also defines a way to extend the configuration mechanism itself via a SPI (Service Provider Interface) in a portable way.
-
-=== Rational
-
-Released binaries often contain functionality which need to behave slightly differently depending on the deployment.
-This might be different REST endpoints to talk to (e.g. depending on the customer for whom a WAR is deployed).
-Or it might even be different features which need to be switched on and off depending on the installation.
-All this must be possible without the need to re-package the whole application binary.
-
-Microprofile-Config provides a way to achieve this goal by aggregating configuration from many different <> and presents a single merged view to the user.
-This allows the application to bundle default configuration within the application.
-It also allows to override the defaults from outside, e.g. via an environment variable a Java system property or via Docker.
-Microprofile-Config also allows to implement and register own configuration sources in a portable way, e.g. for reading configuration values from a shared database in an application cluster.
-
-
-The core Microprofile-Config mechanism is purely String/String based.
-Type-safety is only provided on top of that by using the proper <> before handing the value out to the caller.
-
-The configuration key might use dot-separated namespaces similar to Java package namespacing:
-
-[source, text]
-----
-com.acme.myproject.someserver.url = http://some.server/some/endpoint
-com.acme.myproject.someserver.port = 9085
-com.acme.myproject.someserver.active = true
-com.acme.other.stuff.name = Karl
-com.acme.myproject.notify.onerror=karl@mycompany,sue@mcompany
-----
-
-Config keys are usually case sensitive.
diff --git a/spec/src/main/asciidoc/configexamples.asciidoc b/spec/src/main/asciidoc/configexamples.asciidoc
deleted file mode 100644
index 4799e11..0000000
--- a/spec/src/main/asciidoc/configexamples.asciidoc
+++ /dev/null
@@ -1,92 +0,0 @@
-//
-// Licensed under the Apache License, Version 2.0 (the "License").
-// See the NOTICE file distributed with this work
-// for additional information regarding copyright ownership.
-// The author 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.
-//
-
-[[configexamples]]
-== Configuration Usage Examples
-
-An application can access it's configured values via a `Config` instance.
-A user can use the `ConfigProvider` to access the `Config` of an application or simply use `@Inject Config` within CDI managed components.
-
-=== Simple Example
-
-[source, java]
-----
-ppublic class ConfigUsageSample {
-
- public void useTheConfig() {
- // get access to the Config instance
- Config config = ConfigProvider.getConfig();
-
- String serverUrl = config.getValue("com.acme.myproject.someserver.url");
- Integer serverPort = config.getValue("com.acme.myproject.someserver.port",
- Integer.class);
-
- callToServer(serverUrl, serverPort);
- }
-}
-----
-
-If you need to access a different server then you can e.g. change the configuration via a `-D` system property:
-
-[source, text]
-----
-$> java -jar some.jar -Dcom.acme.myproject.someserver.url=http://other.server/other/endpoint
-----
-
-Note that the way to inject this configuration into the application can be extended by providing custom `ConfigSource` s.
-
-
-
-=== Some advanced features
-
-It is also possible to dynamically pick up values which might change at runtime.
-For example if the configured values get picked up from a custom <> which picks up it's values from a Database.
-
-[source, java]
-----
-@ApplicationScoped
-public class DynamicConfigUsageSample {
-
- private @Inject Config config;
-
- private ConfigValue serverUrlCfg;
- private ConfigValue serverPortCfg
-
- @PostConstruct
- private void init() {
- serverUrlCfg= config.access("com.acme.myproject.someserver.url")
- .cacheFor(5, TimeUnit.MINUTES)
- .logChanges(true)
- .evaluateVariables(true);
-
- serverPortCfg = config.access("com.acme.myproject.someserver.port")
- .as(Integer.class)
- .cacheFor(5, TimeUnit.MINUTES)
- .logChanges(true)
- .evaluateVariables(true)
- .withDefault(8080);
- }
-
- public void useTheConfig() {
- callToServer(serverUrlCfg.getValue(), serverPortCfg.getValue());
- }
-}
-----
-
-The `cacheFor(5, TimeUnit.MINUTES)` will have the `ConfigValue` behave like a local cache and thus reduce load on the configuration system.
-5 minutes after `getValue()` got called the last time any fresh value will get picked up.
-If `logChanges(true)` is set then any value change will get logged.
\ No newline at end of file
diff --git a/spec/src/main/asciidoc/configprovider.asciidoc b/spec/src/main/asciidoc/configprovider.asciidoc
deleted file mode 100644
index ce39eb4..0000000
--- a/spec/src/main/asciidoc/configprovider.asciidoc
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// Licensed under the Apache License, Version 2.0 (the "License").
-// See the NOTICE file distributed with this work
-// for additional information regarding copyright ownership.
-// The author 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.
-//
-
-[[configprovider]]
-== Accessing or Creating a certain Configuration
-
-
-For manually accessing the `ConfigProvider` is the central class to access a configuration.
-It allows access to different configurations (represented by a `Config` instance) based on the application in which it is used.
-We distinguish 5 different ways to create or `Config` instance:
-
-* In CDI manged components a user can use `@Inject` to access the current application configuration.
- If no configuration is registered the automatic discovery of <> will be performed.
-
-* A factory method `ConfigProvider#getConfig()` to create a `Config` object based on automatically picked up `ConfigSources`
- of the Application identified by the current Thread Context ClassLoader classpath.
- Subsequent calls to this method for a certain Application will return the same `Config` instance.
-
-* A factory method `ConfigProvider#getConfig(ClassLoader forClassLoader)` to create a `Config` object based on automatically picked up `ConfigSources`
- of the Application identified by the given ClassLoader.
- This can be used if the Thread Context ClassLoader does not represent the correct layer.
- E.g. if you need the Config for a class in a shared EAR lib folder.
- Subsequent calls to this method for a certain Application will return the same `Config` instance.
-
-* A factory method `ConfigProvider#newConfig()` to create an empty `Config` object which can be filled manually via a builder.
- This configuration instance will not be shared by the `ConfigProvider`.
- This method is intended be used if a IoT container or any other external Factory can be used to give access to a manually created shared `Config`.
-
-* A factory method `ConfigProvider#registerConfig()` to create an empty `Config` object which can be filled manually via a builder.
- This configuration instance *will* be shared by the `ConfigProvider`.
- Any subsequent call to `ConfigProvider#getConfig()` will return the registered `Config` instance.
-
-
-All methods in the `ConfigProvider` and `Config` implementations are thread safe and reentrant.
-
-If a `Config` is bound to an Application it is ensured that it gets properly removed if the Application gets destroyed.
-The Config system deos not create any memory leaks in that case.
-
-A `Config` can be release manually by calling `ConfigProvider#release(Config)`.
-ConfigSources which implement the `java.io.Closeable` interface will be properly destroyed.
-Any subsequent call to `ConfigProvider#getConfig()` or `ConfigProvider#getConfig(ClassLoader forClassLoader)` will result in a new `Config` instance.
-
-<<<
\ No newline at end of file
diff --git a/spec/src/main/asciidoc/configsources.asciidoc b/spec/src/main/asciidoc/configsources.asciidoc
deleted file mode 100644
index 22e5d85..0000000
--- a/spec/src/main/asciidoc/configsources.asciidoc
+++ /dev/null
@@ -1,137 +0,0 @@
-//
-// Licensed under the Apache License, Version 2.0 (the "License").
-// See the NOTICE file distributed with this work
-// for additional information regarding copyright ownership.
-// The author 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.
-//
-
-[[configsource]]
-== ConfigSource
-
-A `ConfigSource` is exactly what its name says: a source for configured values.
-The `Config` uses all configured implementations of `ConfigSource` to look up the property in question.
-
-=== ConfigSource Ordering
-
-Each `ConfigSource` has a specified `ordinal`, which is used to determine the importance of the values taken from the associated `ConfigSource`.
-A higher `ordinal` means that the values taken from this `ConfigSource` will override values from lower-priority `ConfigSource` s.
-This allows a configuration to be customized from outside a binary, assuming that external `ConfigSource` s have higher `ordinal` values than the ones whose values originate within the release binaries.
-
-It can also be used to implement a drop-in configuration approach.
-Simply create a jar containing a `ConfigSource` with a higher ordinal and override configuration values in it.
-If the jar is present on the classpath then it will override configuration values from `ConfigSource` s with lower `ordinal` values.
-
-The ordinal for property file based `ConfigSource` s can be configured using the key `config_ordinal` inside the property file.
-
-[source, text]
-----
-config_ordinal = 120
-com.acme.myproject.someserver.url = http://more_important.server/some/endpoint
-----
-
-[[default_configsources]]
-=== Default ConfigSources
-
-A Microprofile-Config implementation must provide `ConfigSource` s for the following data out of the box:
-
-* System properties (ordinal=400)
-* Environment properties (ordinal=300).
- The built in `ConfigSource` for the environment provides an all upper-case fallback lookup where dots are replaced with underlines.
- An environment setting `ACME_MYKEY=bla` machtches a lookup for `config.getValue("acme.mykey")`.
-* A `ConfigSource` for each property file `META-INF/java-config.properties` found on the classpath. (default ordinal = 100)
-
-=== Custom ConfigSources
-
-`ConfigSource` s are discovered using the `java.util.ServiceLoader` mechanism.
-
-To add a custom `ConfigSource`, implement the interface `io.microprofile.config.spi.ConfigSource`.
-
-[source, java]
-----
-public class CustomDbConfigSource implements ConfigSource {
-
- @Override
- public int getOrdinal() {
- return 112;
- }
-
- @Override
- public Map getProperties() {
- return readPropertiesFromDb();
- }
-
- @Override
- public String getPropertyValue(String key) {
- return readPropertyFromDb(key);
- }
-
- @Override
- public String getConfigName() {
- return "customDbConfig";
- }
-
- // + methods to read from the DB
-}
-
-----
-
-Then register your implementation in a resource file `/META-INF/services/io.microprofile.config.spi.ConfigSource` by including the fully-qualified class name of the custom implementation in the file.
-
-
-=== Custom ConfigSources via ConfigSourceProvider
-
-If you need dynamic `ConfigSource` s you can also register a `ConfigSourceProvider` in a similar manner.
-This is useful if you are required to dynamically pick up multiple `ConfigSource` s of the same kind;
-for example, to pick up all `myproject.properties` resources from all the JARs in your classpath.
-
-A custom `ConfigSourceProvider` must implement the interface `io.microprofile.config.spi.ConfigSourceProvider`.
-Register your implementation in a resource file `/META-INF/services/io.microprofile.config.spi.ConfigSourceProvider` by including the fully-qualified class name of the custom implementation/s in the file.
-
-An example which registers all YAML files with the name `exampleconfig.yaml`:
-
-[source, java]
-----
-public class ExampleYamlConfigSourceProvider
- implements io.microprofile.config.spi.ConfigSourceProvider {
- @Override
- public List getConfigSources(ClassLoader forClassLoader) {
- List configSources = new ArrayList<>();
-
- Enumeration yamlFiles
- = forClassLoader.getResources("sampleconfig.yaml");
- while (yamlFiles.hasMoreElements()) {
- configSources.add(new SampleYamlConfigSource(yamlFiles.nextElement()));
- }
- return configSources;
- }
-}
-----
-
-Please note that a single `ConfigSource` should be either registered directly or via a `ConfigSourceProvider`, but never both ways.
-
-
-=== ConfigSource and Mutable Data
-
-A `Config` instance provides no caching but iterates over all `ConfigSources` for each `getValue(String)` operation.
-A `ConfigSource` is allowed to cache the underlying values itself.
-
-Users might use the `cacheFor(long, TimeUnit)` method of a `ConfigValue` to pick up values which might change at runtime without penetrating the configuration system.
-
-
-=== Manually adding ConfigSources
-
-A user can manually register `ConfigSource` s by using the method `void addConfigSources(List configSourcesToAdd)`.
-This will add the given list to the already registered `ConfigSources` of the current `Config` instance.
-
-The order in which the `ConfigSources` are evaluated when using `Config#getValue(String key)` is independent of the order in which they were added to the `Config`; this depends only on the `ordinal` values of the available `ConfigSources`.
-
diff --git a/spec/src/main/asciidoc/converters.asciidoc b/spec/src/main/asciidoc/converters.asciidoc
deleted file mode 100644
index 0131c39..0000000
--- a/spec/src/main/asciidoc/converters.asciidoc
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// Licensed under the Apache License, Version 2.0 (the "License").
-// See the NOTICE file distributed with this work
-// for additional information regarding copyright ownership.
-// The author 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.
-//
-
-[[converter]]
-== Converter
-
-For providing typeseafe configuration we need to convert from the configured Strings into target types.
-This happens by providing `Converter` s in the `Config`.
-
-=== Built-in Converters
-
-The following `Converter` s are provided by Microprofile-Config by default:
-
-* `Boolean` , values for `true` (case insensitive) "true", "1", "YES", "Y" "JA" "J", "OUI".
- Any other value will be interpreted as `false`
-* `Integer`
-* `Long`
-* `Float` , a dot '.' is used to separate the fractional digits
-* `Double` , a dot '.' is used to separate the fractional digits
-* `java.util.Date` in ISO-8601 format (https://www.ietf.org/rfc/rfc3339.txt), e.g. YYYY-MM-DD. Remaining fractions are set to 0.
-* Java8 `LocalDate` and `LocalDateTime`in ISO-8601 format
-
-
-=== Adding custom Converters
-
-A custom `Converter` must implement the generic interface `io.microprofile.config.spi.Converter`.
-The TypedParameter of the interface is the target type the String is converted to
-You have to register your implementation in a file `/META-INF/services/io.microprofile.config.spi.Converter` by writing the fully qualified class name of the custom implementation into it.
-
-A custom `Converter` can define a priority with the `@javax.annotation.Priority` annotation.
-If a Priority annotation isn't applied, a default priority of 100 is assumed.
-The `Config` will use the `Converter` with the highest `Priority` for each target type.
-
-A custom `Converter` for a target type of any of the built-in Converters will overwrite the default Converter.
diff --git a/spec/src/main/asciidoc/license-alv2.asciidoc b/spec/src/main/asciidoc/license-alv2.asciidoc
deleted file mode 100644
index 276af0a..0000000
--- a/spec/src/main/asciidoc/license-alv2.asciidoc
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// Licensed under the Apache License, Version 2.0 (the "License").
-// See the NOTICE file distributed with this work
-// for additional information regarding copyright ownership.
-// The author 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.
-//
-
-[subs="normal"]
-....
-
-Specification: {doctitle}
-
-Version: {revnumber}
-
-Status: {revremark}
-
-Specification Lead: Mark Struberg, Emily Jiang
-
-Release: {revdate}
-
-Copyright 2016-2017 Original Authors,
-Licensed 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.
-
-....
diff --git a/spec/src/main/asciidoc/microprofile-config-spec.asciidoc b/spec/src/main/asciidoc/microprofile-config-spec.asciidoc
deleted file mode 100644
index eca5e96..0000000
--- a/spec/src/main/asciidoc/microprofile-config-spec.asciidoc
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// Licensed under the Apache License, Version 2.0 (the "License").
-// See the NOTICE file distributed with this work
-// for additional information regarding copyright ownership.
-// The author 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.
-//
-
-= Configuration for Microprofile
-:author: Mark Struberg
-:email: struberg@apache.org
-:revnumber: 0.2
-:revdate: 2017-01-15
-:revremark: Proposal
-:version-label!:
-:sectanchors:
-:doctype: book
-:license: Apache License v2.0
-:source-highlighter: coderay
-:toc: left
-:toclevels: 4
-:sectnumlevels: 4
-ifdef::backend-pdf[]
-:pagenums:
-endif::[]
-
-include::license-alv2.asciidoc[]
-
-include::architecture.asciidoc[]
-
-include::configexamples.asciidoc[]
-
-include::configprovider.asciidoc[]
-
-include::configsources.asciidoc[]
-
-include::converters.asciidoc[]
diff --git a/tck/pom.xml b/tck/pom.xml
deleted file mode 100644
index cff61bd..0000000
--- a/tck/pom.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
- 4.0.0
-
-
- org.apache.geronimo.config
- config-parent
- 0.1-SNAPSHOT
-
-
- org.apache.geronimo.config
- config-tck
-
-
-
- Apache License, Version 2.0
- https://www.apache.org/licenses/LICENSE-2.0.txt
- repo
- A business-friendly OSS license
-
-
-
-
-
- org.apache.geronimo.config
- config-api
- 0.1-SNAPSHOT
-
-
-
- org.testng
- testng
- 6.9.9
- compile
-
-
-
diff --git a/tck/src/main/java/io/microprofile/config/tck/ConfigProviderTest.java b/tck/src/main/java/io/microprofile/config/tck/ConfigProviderTest.java
deleted file mode 100644
index 6b9a4b0..0000000
--- a/tck/src/main/java/io/microprofile/config/tck/ConfigProviderTest.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package io.microprofile.config.tck;
-
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Map;
-import java.util.Properties;
-
-import io.microprofile.config.Config;
-import io.microprofile.config.ConfigProvider;
-
-import io.microprofile.config.tck.configsources.SampleYamlConfigSource;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-/**
- * @author Mark Struberg
- */
-public class ConfigProviderTest {
-
- @Test
- public void testConfigProviderWithDefaultTCCL() {
- ClassLoader oldTccl = Thread.currentThread().getContextClassLoader();
- try {
- ClassLoader tempCl = new URLClassLoader(new URL[0], this.getClass().getClassLoader());
- Thread.currentThread().setContextClassLoader(tempCl);
- Config config = ConfigProvider.getConfig();
- Assert.assertNotNull(config);
-
- Config config2 = ConfigProvider.getConfig(tempCl);
- Assert.assertNotNull(config2);
- Assert.assertEquals(config, config2);
- }
- finally {
- Thread.currentThread().setContextClassLoader(oldTccl);
- }
- }
-
- @Test
- public void testEnvironmentConfigSource() {
- Map env = System.getenv();
- Config config = ConfigProvider.getConfig();
- for (Map.Entry envEntry : env.entrySet()) {
- Assert.assertEquals(envEntry.getValue(), config.getValue(envEntry.getKey()));
- }
- }
-
- @Test
- public void testPropertyConfigSource() {
- Properties properties = System.getProperties();
- Config config = ConfigProvider.getConfig();
-
- for (Map.Entry