diff --git a/.travis.yml.disabled b/.travis.yml.disabled
new file mode 100644
index 0000000..dff5f3a
--- /dev/null
+++ b/.travis.yml.disabled
@@ -0,0 +1 @@
+language: java
diff --git a/NOTICE b/NOTICE
index 27e30dd..231dcfe 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,5 +1,4 @@
-Apache Geronimo Configuration
-Copyright 2016 The Apache Software Foundation
+Copyright 2009-2017 Mark Struberg
This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
+The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/README.adoc b/README.adoc
index 30bd075..e346ca3 100644
--- a/README.adoc
+++ b/README.adoc
@@ -1,46 +1,46 @@
-# Configuration for Java SE and EE JSR
+//
+// 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.
+//
+
+# Configuration for Java SE and EE
## Status
-JSR 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 2012 we further enhanced it while moving CODI to the Apache DeltaSpike project.
-
-== 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/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 8dd1fe7..0000000
--- a/api/pom.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
- 4.0.0
-
-
-
- org.apache.geronimo.config
- config-parent
- 0.1-SNAPSHOT
-
-
- org.apache.geronimo.config
- config-api
-
-
-
- org.apache.geronimo.specs
- geronimo-annotation_1.2_spec
- 1.0
- provided
-
-
-
diff --git a/api/src/main/java/javx/config/Config.java b/api/src/main/java/javx/config/Config.java
deleted file mode 100644
index 5795970..0000000
--- a/api/src/main/java/javx/config/Config.java
+++ /dev/null
@@ -1,117 +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 javx.config;
-
-import java.util.List;
-import java.util.Map;
-
-import javx.config.spi.ConfigFilter;
-import javx.config.spi.ConfigSource;
-import javx.config.spi.ConfigSourceProvider;
-import javx.config.spi.Converter;
-
-/**
- *
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.
- *
- *
A configured value can be accessed with {@link #getValue(String)}.
- *
- *
For accessing a coniguration in a dynamic way you can also use {@link #access(String)}.
- * This method returns a builder-style {@link ConfigValue} instance for the given key.
- * You can further specify a Type of the underlying configuration, a cache time, lookup paths and
- * many more.
- *
- *
- * @author Mark Struberg
- */
-public interface Config {
-
- /**
- * 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);
-
- /**
- * Create a {@link ConfigValue} to access the underlying configuration.
- *
- * @param key the property key
- */
- ConfigValue access(String key);
-
- /**
- * 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.
- *
- * @see ConfigSource#isScannable()
- */
- Map getAllProperties();
-
- /**
- * Filter the configured value.
- * This can e.g. be used for decryption.
- * @return the filtered value
- */
- String filterConfigValue(String key, String value);
-
- /**
- * Filter the configured value for logging.
- * This can e.g. be used for displaying ***** instead of a real password.
- * @return the filtered value
- */
- String filterConfigValueForLog(String key, String value);
-
- /**
- * This method might be useful for debugging purpose or to
- * show the values of all ConfigSources in an admin page.
- *
- * @return all currently registered {@link ConfigSource}s
- */
- ConfigSource[] getConfigSources();
-
- /**
- * This method can be used for programmatically adding {@link ConfigSource}s
- * to this very Config.
- * It is not needed for normal 'usage' by end users, but only for Extension Developers!
- *
- * @param configSourcesToAdd the ConfigSources to add
- */
- void addConfigSources(List configSourcesToAdd);
-
- /**
- * Add a {@link ConfigFilter} to this very Config
- *
- * It is not needed for normal 'usage' by end users, but only for Extension Developers!
- */
- void addConfigFilter(ConfigFilter configFilterToAdd);
-
- /**
- * Add a custom {@link Converter}
- *
- * @param converter
- */
- void addConverter(Converter> converter);
-}
diff --git a/api/src/main/java/javx/config/ConfigProvider.java b/api/src/main/java/javx/config/ConfigProvider.java
deleted file mode 100644
index 9962096..0000000
--- a/api/src/main/java/javx/config/ConfigProvider.java
+++ /dev/null
@@ -1,121 +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 javx.config;
-
-import java.util.ServiceLoader;
-import java.util.logging.Logger;
-
-import javx.config.spi.ConfigFilter;
-import javx.config.spi.ConfigSource;
-
-/**
- *
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
- */
-public class ConfigProvider {
-
- private static final SPI instance = loadSpi();
-
- /**
- * 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 ClassLoader
- */
- public static Config getConfig() {
- return instance.getConfig();
- }
-
- /**
- * Provide a {@link Config} based on all {@link ConfigSource}s
- * of the given ClassLoader.
- *
- *
There is exactly a single Config instance per ClassLoader
- */
- public static Config getConfig(ClassLoader forClassLoader) {
- return instance.getConfig(forClassLoader);
- }
-
- /**
- * Create a fresh {@link Config} instance.
- * This Config will initially contain no
- * {@link ConfigSource} nor any {@link ConfigFilter}.
- * Those have to be added manually.
- *
- * The ConfigProvider will not manage the Config instance internally
- */
- public static Config newConfig() {
- return instance.newConfig();
- }
-
- /**
- * 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);
- }
-
-
- /**
- * This interface gets implemented internally by the Config library.
- * The implementation registers itself via {@link java.util.ServiceLoader} mechanism.
- */
- public interface SPI {
- Config getConfig();
- Config getConfig(ClassLoader forClassLoader);
- Config newConfig();
- void releaseConfig(Config config);
- }
-
- private static SPI loadSpi() {
- ServiceLoader sl = ServiceLoader.load(SPI.class);
- SPI instance = null;
- for (SPI spi : sl) {
- if (instance != null) {
- Logger.getLogger(ConfigProvider.class.getName()).warning("Multiple ConfigResolver SPIs found. Ignoring " + spi.getClass().getName());
- }
- else {
- instance = spi;
- }
- }
- if (instance == null) {
- throw new IllegalStateException("No ConfigResolver SPI implementation found!");
- }
- return instance;
- }
-
-
-}
diff --git a/api/src/main/java/javx/config/ConfigValue.java b/api/src/main/java/javx/config/ConfigValue.java
deleted file mode 100644
index 5661fed..0000000
--- a/api/src/main/java/javx/config/ConfigValue.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package javx.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();
-
- /**
- * 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/javx/config/spi/ConfigFilter.java b/api/src/main/java/javx/config/spi/ConfigFilter.java
deleted file mode 100644
index 0e01b51..0000000
--- a/api/src/main/java/javx/config/spi/ConfigFilter.java
+++ /dev/null
@@ -1,53 +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 javx.config.spi;
-
-import javx.config.Config;
-
-/**
- *
A filter which can be added to the
- * {@link Config}.
- * The filter can be used to decrypt config values or prepare
- * values for logging.
- *
- *
Registering a {@code ConfigFilter} can either be done via the
- * {@code java.util.ServiceLoader} pattern or by manually adding it via
- * {@link Config#addConfigFilter(ConfigFilter)}.
- *
- * @author Mark Struberg
- */
-public interface ConfigFilter
-{
- /**
- * Filter the given configuration value
- * @param key
- * @param value
- * @return the filtered value or the original input String if no filter shall be applied
- */
- String filterValue(String key, String value);
-
- /**
- * Filter the given configuration value for usage in logs.
- * This might be used to mask out passwords, etc.
- * @param key
- * @param value
- * @return the filtered value or the original input String if no filter shall be applied
- */
- String filterValueForLog(String key, String value);
-}
diff --git a/api/src/main/java/javx/config/spi/ConfigSource.java b/api/src/main/java/javx/config/spi/ConfigSource.java
deleted file mode 100644
index 254d796..0000000
--- a/api/src/main/java/javx/config/spi/ConfigSource.java
+++ /dev/null
@@ -1,108 +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 javx.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();
-
- /**
- * Determines if this config source should be scanned for its list of properties.
- *
- * Generally, slow ConfigSources should return {@code false} here.
- *
- * @return {@code true} if this ConfigSource should be scanned for its list of properties,
- * {@code false} if it should not be scanned.
- */
- boolean isScannable();
-}
diff --git a/api/src/main/java/javx/config/spi/ConfigSourceProvider.java b/api/src/main/java/javx/config/spi/ConfigSourceProvider.java
deleted file mode 100644
index b3f3a46..0000000
--- a/api/src/main/java/javx/config/spi/ConfigSourceProvider.java
+++ /dev/null
@@ -1,47 +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 javx.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/javx/config/spi/Converter.java b/api/src/main/java/javx/config/spi/Converter.java
deleted file mode 100644
index 9bac50c..0000000
--- a/api/src/main/java/javx/config/spi/Converter.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package javx.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/api/src/main/java/javx/config/spi/PropertyFileConfig.java b/api/src/main/java/javx/config/spi/PropertyFileConfig.java
deleted file mode 100644
index 2fdf996..0000000
--- a/api/src/main/java/javx/config/spi/PropertyFileConfig.java
+++ /dev/null
@@ -1,67 +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 javx.config.spi;
-
-/**
- *
- * If you implement this interface, the property files with the given file name will be registered as
- * {@link ConfigSource}s.
- *
- **
- *
Automatic pickup via {@code java.util.ServiceLoader} mechanism
- *
You need to register the PropertyFileConfig via the {@code java.util.ServiceLoader} mechanism.
- *
- *
The {@code ServiceLoader} mechanism requires to have a file
- *
- *
- *
- */
-public interface PropertyFileConfig
-{
- /**
- * All the property files on the classpath which have this name will get picked up and registered as
- * {@link ConfigSource}s.
- *
- * @return the full file name (including path) of the property files to pick up.
- */
- String getPropertyFileName();
-
- /**
- * @return true if the file is optional, false if the specified file has to be in place.
- */
- boolean isOptional();
-}
diff --git a/impl/debug-suite.xml b/impl/debug-suite.xml
index 65957e2..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 ed56aa3..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,21 +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 javx.config.Config;
-import javx.config.ConfigValue;
-import javx.config.spi.ConfigFilter;
-import javx.config.spi.ConfigSource;
-import javx.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;
@@ -40,15 +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 configFilters = new ArrayList<>();
+ protected List configSources = new ArrayList<>();
protected Map converters = new HashMap<>();
@@ -57,96 +70,105 @@ 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[]{filterConfigValueForLog(key, value), key, configSource.getConfigName()});
+ new Object[]{value, key, configSource.getName()});
}
- return filterConfigValue(key, value);
+ return value;
}
}
- return null;
- }
- @Override
- public ConfigValue access(String key) {
- return new ConfigValueImpl<>(this, key);
+ return null;
}
- @Override
- public Map getAllProperties() {
- Map result = new HashMap();
-
- for (int i = configSources.length; i > 0; i--) {
- ConfigSource configSource = configSources[i];
- if (configSource.isScannable()) {
- result.putAll(configSource.getProperties());
- }
+ public T convert(String value, Class asType) {
+ if (value != null) {
+ Converter converter = getConverter(asType);
+ return converter.convert(value);
}
- // now filter them
- for (Map.Entry entries : result.entrySet()) {
- entries.setValue(filterConfigValue(entries.getKey(), entries.getValue()));
+ return null;
+ }
+
+ private Converter getConverter(Class asType) {
+ Converter converter = converters.get(asType);
+ if (converter == null) {
+ throw new UnsupportedOperationException("No Converter registered for class " + asType);
}
+ return converter;
+ }
- return Collections.unmodifiableMap(result);
+ public ConfigValueImpl access(String key) {
+ return new ConfigValueImpl(this, key);
}
@Override
- public String filterConfigValue(String key, String value) {
- String filteredValue = value;
+ public Iterable getPropertyNames() {
+ Set result = new HashSet<>();
+
+ for (ConfigSource configSource : configSources) {
+ result.addAll(configSource.getProperties().keySet());
- for (ConfigFilter filter : configFilters) {
- filteredValue = filter.filterValue(key, filteredValue);
}
- return filteredValue;
+ return result;
}
- @Override
- public String filterConfigValueForLog(String key, String value) {
- String logValue = value;
- for (ConfigFilter filter : configFilters) {
- logValue = filter.filterValueForLog(key, logValue);
- }
-
- return logValue;
- }
@Override
- public ConfigSource[] getConfigSources() {
- return configSources;
+ public Iterable getConfigSources() {
+ return Collections.unmodifiableList(configSources);
}
- @Override
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
configSources = sortDescending(allConfigSources);
}
- @Override
- public synchronized void addConfigFilter(ConfigFilter configFilter) {
- configFilters.add(configFilter);
-
- }
- @Override
public synchronized void addConverter(Converter> converter) {
if (converter == null) {
return;
@@ -178,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 5d0fd8f..b88a0ff 100644
--- a/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java
+++ b/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java
@@ -1,16 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.apache.geronimo.config;
-import javx.config.ConfigValue;
-import javx.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;
@@ -23,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)
{
@@ -106,17 +156,11 @@ public T getValue() {
}
String valueStr = resolveStringValue();
- T value = convert(valueStr);
-
- if (withDefault)
- {
- value = fallbackToDefaultIfEmpty(keyResolved, value, defaultValue);
- }
+ T value = convert ? convert(valueStr) : (T) valueStr;
- if (logChanges && (value != null && !value.equals(lastValue) || (value == null && lastValue != null)) )
+ if (valueChangeListener != null && (value != null && !value.equals(lastValue) || (value == null && lastValue != null)) )
{
- logger.log(Level.INFO, "New value {0} for key {1}.",
- new Object[]{config.filterConfigValueForLog(keyOriginal, valueStr), keyOriginal});
+ valueChangeListener.onValueChange(keyOriginal, lastValue, value);
}
lastValue = value;
@@ -149,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);
@@ -160,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;
@@ -188,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
new file mode 100644
index 0000000..ad56326
--- /dev/null
+++ b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java
@@ -0,0 +1,127 @@
+/*
+ * 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 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;
+
+import java.util.ArrayList;
+import java.util.Collection;
+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
+ */
+@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 = true;
+ private boolean ignoreDiscoveredSources = true;
+
+ @Override
+ public ConfigBuilder addDefaultSources() {
+ this.ignoreDefaultSources = false;
+ return this;
+ }
+
+ @Override
+ public ConfigBuilder addDiscoveredSources() {
+ this.ignoreDiscoveredSources = false;
+ return this;
+ }
+
+ @Override
+ public ConfigBuilder forClassLoader(final ClassLoader loader) {
+ this.forClassLoader = loader;
+ return this;
+ }
+
+ @Override
+ public ConfigBuilder withSources(final ConfigSource... sources) {
+ this.sources.addAll(asList(sources));
+ return this;
+ }
+
+ @Override
+ public ConfigBuilder withConverters(Converter>... converters) {
+ this.converters.addAll(asList(converters));
+ return this;
+ }
+
+ @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 (!ignoreDiscoveredSources) {
+ // load all ConfigSource services
+ ServiceLoader configSourceLoader = ServiceLoader.load(ConfigSource.class, forClassLoader);
+ configSourceLoader.forEach(configSource -> configSources.add(configSource));
+
+ // load all ConfigSources from ConfigSourceProviders
+ ServiceLoader configSourceProviderLoader = ServiceLoader.load(ConfigSourceProvider.class, forClassLoader);
+ configSourceProviderLoader.forEach(configSourceProvider ->
+ configSourceProvider.getConfigSources(forClassLoader)
+ .forEach(configSource -> configSources.add(configSource)));
+ }
+
+ ConfigImpl config = new ConfigImpl();
+ config.addConfigSources(configSources);
+
+ for (Converter> converter : converters) {
+ config.addConverter(converter);
+ }
+
+ return config;
+ }
+
+ protected Collection extends ConfigSource> getBuiltInConfigSources(ClassLoader forClassLoader) {
+ List configSources = new ArrayList<>();
+
+ configSources.add(new SystemEnvConfigSource());
+ configSources.add(new SystemPropertyConfigSource());
+ 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 a2ce39e..d70b9d2 100644
--- a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java
+++ b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java
@@ -17,46 +17,36 @@
package org.apache.geronimo.config;
import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
-import java.util.ServiceLoader;
import java.util.WeakHashMap;
-import javx.config.Config;
-import javx.config.ConfigProvider;
-import javx.config.spi.ConfigFilter;
-import javx.config.spi.ConfigSource;
-import javx.config.spi.ConfigSourceProvider;
-import javx.config.spi.Converter;
-import javx.config.spi.PropertyFileConfig;
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.Vetoed;
-import org.apache.geronimo.config.configsource.PropertyFileConfigSourceProvider;
-import org.apache.geronimo.config.configsource.SystemEnvConfigSource;
-import org.apache.geronimo.config.configsource.SystemPropertyConfigSource;
+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) {
@@ -65,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);
}
}
@@ -73,87 +63,47 @@ public Config getConfig(ClassLoader forClassLoader) {
return config;
}
- private Config existingConfig(ClassLoader forClassLoader) {
+ Config existingConfig(ClassLoader forClassLoader) {
WeakReference configRef = configs.get(forClassLoader);
return configRef != null ? configRef.get() : null;
}
- protected Config createConfig(ClassLoader forClassLoader) {
- ConfigImpl config = new ConfigImpl();
-
- List configSources = new ArrayList<>();
-
- configSources.addAll(getBuiltInConfigSources(forClassLoader));
-
-
- // load all ConfigSource services
- ServiceLoader configSourceLoader = ServiceLoader.load(ConfigSource.class, forClassLoader);
- for (ConfigSource configSource : configSourceLoader) {
- configSources.add(configSource);
- }
-
- // load all ConfigSources from ConfigSourceProviders
- ServiceLoader configSourceProviderLoader = ServiceLoader.load(ConfigSourceProvider.class, forClassLoader);
- for (ConfigSourceProvider configSourceProvider : configSourceProviderLoader) {
- configSources.addAll(configSourceProvider.getConfigSources(forClassLoader));
- }
-
- config.addConfigSources(configSources);
- addConverters(config, forClassLoader);
-
- // also register all ConfigFilters
- ServiceLoader configFilterLoader = ServiceLoader.load(ConfigFilter.class, forClassLoader);
- for (ConfigFilter configFilter : configFilterLoader) {
- config.addConfigFilter(configFilter);
- }
-
- return config;
- }
-
- protected Collection extends ConfigSource> getBuiltInConfigSources(ClassLoader forClassLoader) {
- List configSources = new ArrayList<>();
- configSources.add(new SystemEnvConfigSource());
- configSources.add(new SystemPropertyConfigSource());
- configSources.addAll(new PropertyFileConfigSourceProvider("META-INF/java-config.properties", true, forClassLoader).getConfigSources(forClassLoader));
- configSources.addAll(getCustomPropertyFiles(forClassLoader));
-
- return configSources;
- }
-
- private Collection extends ConfigSource> getCustomPropertyFiles(ClassLoader forClassLoader) {
- List configSources = new ArrayList<>();
- ServiceLoader propertyFileConfigLoader = ServiceLoader.load(PropertyFileConfig.class);
- for (PropertyFileConfig propConfig : propertyFileConfigLoader) {
- configSources.addAll(new PropertyFileConfigSourceProvider(propConfig.getPropertyFileName(), propConfig.isOptional(), forClassLoader).getConfigSources(forClassLoader));
- }
-
- return configSources;
- }
-
- protected void addConverters(Config config, ClassLoader forClassLoader) {
- ServiceLoader converters = ServiceLoader.load(Converter.class, forClassLoader);
- for (Converter converter : converters) {
- config.addConverter(converter);
- }
- }
-
- private 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 Config newConfig() {
- return new ConfigImpl();
+ public ConfigBuilder getBuilder() {
+ return new DefaultConfigBuilder();
}
+
@Override
public void releaseConfig(Config config) {
- Iterator>> it = configs.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry> next = it.next();
+ 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();
+ while (it.hasNext()) {
+ Map.Entry> entry = it.next();
+ if (entry.getValue().get() != null && entry.getValue().get() == config) {
+ it.remove();
+ break;
+ }
+ }
+ }
}
}
}
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/org/apache/geronimo/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/org/apache/geronimo/config/tck/converters/Duck.java
rename to impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionProducer.java
index 18d0fb0..ce16e8e 100644
--- a/tck/src/main/java/org/apache/geronimo/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 org.apache.geronimo.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 c8c8da1..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 javx.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) {
@@ -63,8 +66,4 @@ protected void initOrdinal(int defaultOrdinal) {
}
}
- @Override
- public boolean isScannable() {
- return true;
- }
}
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 9d6e218..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 javx.config.spi.ConfigSource;
-import javx.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 c45a47d..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 javx.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 f29cf23..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 javx.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 5df76ee..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 javx.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 99b0add..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 javx.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/org/apache/geronimo/config/tck/PropertyFileConfigSourceTest.java b/impl/src/main/java/org/apache/geronimo/config/converters/DurationConverter.java
similarity index 54%
rename from tck/src/main/java/org/apache/geronimo/config/tck/PropertyFileConfigSourceTest.java
rename to impl/src/main/java/org/apache/geronimo/config/converters/DurationConverter.java
index 229e42b..8f04abb 100644
--- a/tck/src/main/java/org/apache/geronimo/config/tck/PropertyFileConfigSourceTest.java
+++ b/impl/src/main/java/org/apache/geronimo/config/converters/DurationConverter.java
@@ -14,26 +14,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.geronimo.config.tck;
+package org.apache.geronimo.config.converters;
-import javx.config.Config;
-import javx.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 PropertyFileConfigSourceTest {
- @Test
- public void testCustomPropertyFilesConfigSource() {
- Config config = ConfigProvider.getConfig();
- Assert.assertEquals(config.getValue("tck.config.test.propertyfileconfig.custom.key1"), "value1");
- }
+@Priority(1)
+@Vetoed
+public class DurationConverter implements Converter {
+
+ public static final DurationConverter INSTANCE = new DurationConverter();
- @Test
- public void testPropertyOverwrite() {
- Config config = ConfigProvider.getConfig();
- Assert.assertEquals(config.getValue("tck.config.test.overwritten.in.custompropertyfile.key1"), "value from some/custom.properties");
+ @Override
+ public Duration convert(String value) {
+ if (value != null) {
+ try {
+ return Duration.parse(value);
+ }
+ catch (DateTimeParseException dtpe) {
+ throw new IllegalArgumentException(dtpe);
+ }
+ }
+ return null;
}
-}
\ No newline at end of file
+}
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 c8d5806..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 javx.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 e3c7e0d..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 javx.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/org/apache/geronimo/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/org/apache/geronimo/config/tck/configsources/SampleYamlConfigSource.java
rename to impl/src/main/java/org/apache/geronimo/config/converters/LocalDateTimeConverter.java
index 8112088..fe5c09e 100644
--- a/tck/src/main/java/org/apache/geronimo/config/tck/configsources/SampleYamlConfigSource.java
+++ b/impl/src/main/java/org/apache/geronimo/config/converters/LocalDateTimeConverter.java
@@ -14,46 +14,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.geronimo.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 javx.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 110;
- }
-
- @Override
- public Map getProperties() {
- return config;
- }
+@Priority(1)
+@Vetoed
+public class LocalDateTimeConverter implements Converter {
- @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;
}
-
- @Override
- public boolean isScannable() {
- return false;
- }
}
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 2d9eff6..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 javx.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/org/apache/geronimo/config/tck/configsources/CustomPropertyFileConfig.java b/impl/src/main/java/org/apache/geronimo/config/converters/StringConverter.java
similarity index 61%
rename from tck/src/main/java/org/apache/geronimo/config/tck/configsources/CustomPropertyFileConfig.java
rename to impl/src/main/java/org/apache/geronimo/config/converters/StringConverter.java
index f7589ad..0d5ccbc 100644
--- a/tck/src/main/java/org/apache/geronimo/config/tck/configsources/CustomPropertyFileConfig.java
+++ b/impl/src/main/java/org/apache/geronimo/config/converters/StringConverter.java
@@ -14,21 +14,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.geronimo.config.tck.configsources;
+package org.apache.geronimo.config.converters;
-import javx.config.spi.PropertyFileConfig;
+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 CustomPropertyFileConfig implements PropertyFileConfig {
- @Override
- public String getPropertyFileName() {
- return "some/custom.properties";
- }
+@Priority(1)
+@Vetoed
+public class StringConverter implements Converter {
+
+ public static final StringConverter INSTANCE = new StringConverter();
@Override
- public boolean isOptional() {
- return false;
+ 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/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000..f949a49
--- /dev/null
+++ b/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy current the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+org.apache.geronimo.config.cdi.ConfigExtension
\ No newline at end of file
diff --git a/impl/src/main/resources/META-INF/services/javx.config.ConfigProvider$SPI b/impl/src/main/resources/META-INF/services/javx.config.ConfigProvider$SPI
deleted file mode 100644
index c22654d..0000000
--- a/impl/src/main/resources/META-INF/services/javx.config.ConfigProvider$SPI
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.geronimo.config.DefaultConfigProvider
\ No newline at end of file
diff --git a/impl/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigProviderResolver b/impl/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigProviderResolver
new file mode 100644
index 0000000..b3580b9
--- /dev/null
+++ b/impl/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigProviderResolver
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy current the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+org.apache.geronimo.config.DefaultConfigProvider
\ No newline at end of file
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/org/apache/geronimo/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/org/apache/geronimo/config/tck/converters/DuckConverter.java
rename to impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigExtension.java
index f8337bd..22335a0 100644
--- a/tck/src/main/java/org/apache/geronimo/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 org.apache.geronimo.config.tck.converters;
+package org.apache.geronimo.config.test;
-import javx.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/impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension b/impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
new file mode 100644
index 0000000..91c04d4
--- /dev/null
+++ b/impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy current the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+
+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 63b79ce..05e8c78 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
org.apacheapache
- 17
+ 18org.apache.geronimo.config
@@ -31,19 +31,46 @@
0.1-SNAPSHOTpom
+
+
+ Apache License, Version 2.0
+ https://www.apache.org/licenses/LICENSE-2.0.txt
+ repo
+ A business-friendly OSS license
+
+
+
3.1.0
- 1.7
- 1.7
+ 1.8
+ 1.8
- api
- tckimpl
- spec
+
+
+
+
+ org.apache.rat
+ apache-rat-plugin
+ 0.12
+
+
+ rat-check
+ check
+
+
+
+
+ .travis.yml.*
+
+
+
+
+
diff --git a/spec/pom.xml b/spec/pom.xml
deleted file mode 100644
index b8a8c17..0000000
--- a/spec/pom.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-
-
-
- 4.0.0
-
-
-
- org.apache.geronimo.config
- config-parent
- 0.1-SNAPSHOT
-
-
- org.apache.geronimo.config
- config-spec
- pom
-
-
- 1.5.3
- 1.5.0-alpha.10.1
- asl2
- 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
-
-
-
-
- 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 cc1a15f..0000000
--- a/spec/src/main/asciidoc/architecture.asciidoc
+++ /dev/null
@@ -1,77 +0,0 @@
-[[architecture]]
-== Architecture
-
-This specification defines a 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).
-
-=== Rational
-
-Released binaries often contain classes which need to behave slightly different depending on the deployment.
-This might be different REST endpoints to talk with depending on the customer at which a WAR gets 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.
-
-Java-config provides a way to achieve this goal by allowing the application to bundle default configuration within the application.
-But it also allows to overwrite them from outside, e.g. via an environment variable, a Java system property or even a database entry.
-
-=== Accessing a certain Configuration
-
-The `ConfigProvider` is the central class to access a configuration.
-It must allow access to different configurations based on the application it gets used in.
-We distinguish 3 different ways to resolve a `Config` instance:
-
-* A factory method `ConfigProvider#getConfig()` to create a `Config` object based on automatically picked up `ConfigSource` s from the current Thread Context ClassLoader classpath.
- Subsequent calls to this method for a certain ClassLoader will return the same `Config` instance.
-
-* A factory method `ConfigProvider#getConfig(ClassLoader forClassLoader)` to create a `Config` object based on automatically picked up `ConfigSource` s from a 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 ClassLoader will return the same `Config` instance.
-
-* A factory method `ConfigProvider#newConfig()` to to create an empty `Config` object which can be filled manually.
- No automatic `ConfigSource` and `ConfigFilter` lookup will be performed.
- 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 manualy created shared `Config`.
-
-All methods in the `ConfigProvider` and `Config` implementations are thread safe and reentrant.
-
-If a `Config` is bound to a ClassLoader ist must be made sure that it gets properly removed if the ClassLoader gets destroyed.
-It must not create any mem leaks in that case.
-
-=== Configuration Lookup Mechanism Example
-
-Java-config is a String/String based mechanism.
-
-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.active = true
-com.acme.other.stuff.name = Karl
-----
-
-An application can access this configuration via a `Config` instance.
-
-[source, java]
-----
-public class ConfigUsageSample {
-
- public void useTheConfig() {
- // get access to the Config instance
- Config config = ConfigProvider.getConfig();
- String serverUrl = config.getValue("com.acme.myproject.someserver.url");
-
- callToServer(serverUrl);
- }
-}
-----
-
-If you like 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.
\ No newline at end of file
diff --git a/spec/src/main/asciidoc/config-spec.asciidoc b/spec/src/main/asciidoc/config-spec.asciidoc
deleted file mode 100644
index cd8de66..0000000
--- a/spec/src/main/asciidoc/config-spec.asciidoc
+++ /dev/null
@@ -1,31 +0,0 @@
-= JSR XXX: Configuration for Java
-:author: Mark Struberg
-:email: struberg@apache.org
-:revnumber: 0.1
-:revdate: 2016-07-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::configsources.asciidoc[]
-
-include::configfilters.asciidoc[]
-
-include::converters.asciidoc[]
-
-include::configvalue.asciidoc[]
-
diff --git a/spec/src/main/asciidoc/configfilters.asciidoc b/spec/src/main/asciidoc/configfilters.asciidoc
deleted file mode 100644
index f3dbde7..0000000
--- a/spec/src/main/asciidoc/configfilters.asciidoc
+++ /dev/null
@@ -1,59 +0,0 @@
-[[configfilters]]
-== ConfigFilters
-
-A `ConfigFilter` allows to act as a valve which is able to modify the configured values before they get handed out to the caller.
-
-The spec does not require the implementations to ship with any `ConfigFilters` enabled by default.
-
-A custom `ConfigFilter` must implement the interface `javx.config.spi.ConfigFilter`.
-You have to register your implementation in a file `/META-INF/services/javx.config.spi.ConfigFilter` by writing the fully qualified class name of the custom implementation into it.
-
-Alternative to that a user can register a `ConfigFilter` manually via `void Config#addConfigFilter(ConfigFilter configFilterToAdd)`.
-
-=== Filtering a value for Usage
-
-A `ConfigFilter` can e.g. be used to decrypt a stored password on the fly:
-
-[source, java]
-----
-public class PasswordDecryptionConfigFilter implements ConfigFilter {
- @Override
- public String filterValue(String key, String value) {
- if (value != null && key.endsWith(".password")) {
- return decrypt(value);
- }
- return value;
- }
-
- @Override
- public String filterValueForLog(String key, String value) {
- // do nothing
- return value;
- }
-}
-----
-
-=== Filtering a value for Logging
-
-To prevent passwords and other secret information to be printed out or logged away, a `ConfigFilter` can be used to mask out those values.
-
-[source, java]
-----
-public class PasswordConfigFilter implements ConfigFilter {
- @Override
- public String filterValue(String key, String value) {
- // do nothing
- return value;
- }
-
- @Override
- public String filterValueForLog(String key, String value) {
- if (value != null &&
- (key.contains("password") || key.contains("secret"))) {
- return "*******"; // simply star-out the password
- }
- return value;
- }
-}
-
-----
\ 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 1a283df..0000000
--- a/spec/src/main/asciidoc/configsources.asciidoc
+++ /dev/null
@@ -1,144 +0,0 @@
-[[configsources]]
-== ConfigSources
-
-A `ConfigSource` is exactly what its name says: a source for configured values.
-The `Config` uses all configured implementations of `ConfigSource` to lookup the property in question.
-
-=== ConfigSource Ordering
-
-Each `ConfigSource` has a specified `ordinal`.
-This ordinal get’s used to determine the importance of the values taken from the very `ConfigSource`.
-A higher ordinal means that the values taken from this ConfigSource will override values from less important ConfigSources.
-This is the trick which allows to amend configuration from outside a binary - given those outside ConfigSources have a higher `ordinal` than the ones who pickup the values from 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 overwrite configuration values in it.
-If the jar gets added to the classpath then it will overwrite the configuration from `ConfigSource` s with lower ordinal.
-
-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
-
-A Java-config implementation must provide `ConfigSource` s for the following data out of the box:
-
-* System properties (ordinal=400)
-* Environment properties (ordinal=300)
-* An own `ConfigSource` for each property file `META-INF/java-config.properties` found on the classpath. (default ordinal = 100)
-
-=== Custom ConfigSources
-
-ConfigSources are picked up using the `java.util.ServiceLoader` mechanism.
-
-To add a custom `ConfigSource`, you have to implement the interface `javx.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";
- }
-
- @Override
- public boolean isScannable() {
- return true;
- }
-
- // + methods to read from the DB
-}
-
-----
-
-Then register your implementation in a file `/META-INF/services/javx.config.spi.ConfigSource` by writing the fully qualified class name of the custom implementation into it.
-
-
-=== Custom ConfigSources via ConfigSourceProvider
-
-If you need dynamic ConfigSources you can also register a `ConfigSourceProvider` in a similar way.
-This is useful if you like to dynamically pick up multiple `ConfigSource` s of the same kind.
-For example, if you like to pick up all myproject.properties files from all the JARs in your classpath.
-
-A custom `ConfigSourceProvider` needs to implement the interface `javx.config.spi.ConfigSourceProvider`.
-Register your implementation in a file `/META-INF/services/javx.config.spi.ConfigSourceProvider` by writing the fully qualified class name of the custom implementation/s into it.
-
-An example which registers all yaml files with the name `exampleconfig.yaml`:
-
-[source, java]
-----
-public class ExampleYamlConfigSourceProvider
- implements javx.config.spi.ConfigSourceProvider {
- @Override
- public List getConfigSources(ClassLoader forClassLoader) {
- List configSources = new ArrayList<>();
-
- Enumeration yamlFiles = null;
- 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.
-
-
-=== PropertyFileConfig
-
-You can also make Java-config pick up property files with a custom name as `ConfigSource` s.
-The following example will pick up all property files with the name `some/custom.properties` from the classpath.
-
-[source, java]
-----
-public class CustomPropertyFileConfig implements PropertyFileConfig {
- @Override
- public String getPropertyFileName() {
- return "some/custom.properties";
- }
-
- @Override
- public boolean isOptional() {
- return false;
- }
-}
-----
-
-Register your implementation in a file `/META-INF/services/javx.config.spi.PropertyFileConfig` by writing the fully qualified class name of your `PropertyFileConfig` into it.
-
-
-=== 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.
-
-
-=== 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` get evaluates when using `Config#getValue(String key)` is independent from the order in which they got added to the `Config`.
-It is only depending on the `ordinal` of the `ConfigSources`.
\ No newline at end of file
diff --git a/spec/src/main/asciidoc/configvalue.asciidoc b/spec/src/main/asciidoc/configvalue.asciidoc
deleted file mode 100644
index d83d7d4..0000000
--- a/spec/src/main/asciidoc/configvalue.asciidoc
+++ /dev/null
@@ -1,3 +0,0 @@
-[[configvalue]]
-== ConfigValue
-
diff --git a/spec/src/main/asciidoc/converters.asciidoc b/spec/src/main/asciidoc/converters.asciidoc
deleted file mode 100644
index 46317ab..0000000
--- a/spec/src/main/asciidoc/converters.asciidoc
+++ /dev/null
@@ -1,29 +0,0 @@
-[[converters]]
-== Converters
-
-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 Java-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
-
-
-=== Adding custom Converters
-
-A custom `Converter` must implement the generic interface `javx.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/javx.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 1461ae1..0000000
--- a/spec/src/main/asciidoc/license-alv2.asciidoc
+++ /dev/null
@@ -1,28 +0,0 @@
-[subs="normal"]
-....
-
-Specification: {doctitle}
-
-Version: {revnumber}
-
-Status: {revremark}
-
-Specification Lead: Mark Struberg
-
-Release: {revdate}
-
-Copyright 2016 Apache Software Foundation
-
-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/tck/pom.xml b/tck/pom.xml
deleted file mode 100644
index d4858e0..0000000
--- a/tck/pom.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
- 4.0.0
-
-
- org.apache.geronimo.config
- config-parent
- 0.1-SNAPSHOT
-
-
- org.apache.geronimo.config
- config-tck
-
-
-
- org.apache.geronimo.config
- config-api
- 0.1-SNAPSHOT
-
-
-
- org.testng
- testng
- 6.9.9
- compile
-
-
-
diff --git a/tck/src/main/java/org/apache/geronimo/config/tck/ConfigFilterTest.java b/tck/src/main/java/org/apache/geronimo/config/tck/ConfigFilterTest.java
deleted file mode 100644
index 3bb7fc8..0000000
--- a/tck/src/main/java/org/apache/geronimo/config/tck/ConfigFilterTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.apache.geronimo.config.tck;
-
-import javx.config.Config;
-import javx.config.ConfigProvider;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-/**
- * @author Mark Struberg
- */
-public class ConfigFilterTest {
-
- @Test
- public void testConfigFiltering() {
- Config config = ConfigProvider.getConfig();
-
- // unfiltered
- Assert.assertEquals(config.getValue("tck.config.test.javaconfig.configfilter.my.secret"), "SOME_SECRET");
-
- // filtered
- Assert.assertEquals(config.getValue("tck.config.test.javaconfig.configfilter.my.password"), "some_password");
- }
-
- @Test
- public void testConfigFiltering_ForLogging() {
- Config config = ConfigProvider.getConfig();
-
- Assert.assertEquals(
- config.filterConfigValueForLog("tck.config.test.javaconfig.configfilter.my.password",
- config.getValue("tck.config.test.javaconfig.configfilter.my.password")), "*******");
- }
-}
diff --git a/tck/src/main/java/org/apache/geronimo/config/tck/ConfigProviderTest.java b/tck/src/main/java/org/apache/geronimo/config/tck/ConfigProviderTest.java
deleted file mode 100644
index 7e21402..0000000
--- a/tck/src/main/java/org/apache/geronimo/config/tck/ConfigProviderTest.java
+++ /dev/null
@@ -1,93 +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.tck;
-
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Map;
-import java.util.Properties;
-
-import javx.config.Config;
-import javx.config.ConfigProvider;
-
-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