You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by st...@apache.org on 2018/03/05 15:15:11 UTC

[1/4] deltaspike git commit: DELTASPIKE-1322 move config internas to impl

Repository: deltaspike
Updated Branches:
  refs/heads/master ca6b722bd -> 5b07e197c


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TestConfigSourceProvider.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TestConfigSourceProvider.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TestConfigSourceProvider.java
new file mode 100644
index 0000000..a2fda5f
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TestConfigSourceProvider.java
@@ -0,0 +1,115 @@
+/*
+ * 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.deltaspike.test.core.api.config;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.deltaspike.core.spi.config.ConfigSource;
+import org.apache.deltaspike.core.spi.config.ConfigSourceProvider;
+
+/**
+ * ConfigSourceProvider for basic unit-test
+ */
+public class TestConfigSourceProvider implements ConfigSourceProvider
+{
+    @Override
+    public List<ConfigSource> getConfigSources()
+    {
+        return Arrays.asList(new TestConfigSource1(), new TestConfigSource2());
+    }
+
+    private static class TestConfigSource1 implements ConfigSource
+    {
+        @Override
+        public int getOrdinal()
+        {
+            return 1;
+        }
+
+        @Override
+        public String getPropertyValue(String key)
+        {
+            if ("test".equals(key))
+            {
+                return "test1";
+            }
+            return null;
+        }
+
+        @Override
+        public Map<String, String> getProperties()
+        {
+            Map<String, String> map = new HashMap<String, String>();
+            map.put("test", "test1");
+            return map;
+        }
+
+        @Override
+        public String getConfigName()
+        {
+            return TestConfigSourceProvider.class.getName();
+        }
+
+		@Override
+		public boolean isScannable() {
+			return true;
+		}
+    }
+
+    private static class TestConfigSource2 implements ConfigSource
+    {
+        @Override
+        public int getOrdinal()
+        {
+            return 2;
+        }
+
+        @Override
+        public String getPropertyValue(String key)
+        {
+            if ("test".equals(key))
+            {
+                return "test2";
+            }
+            return null;
+        }
+
+        @Override
+        public Map<String, String> getProperties()
+        {
+            Map<String, String> map = new HashMap<String, String>();
+            map.put("test", "test2");
+            return map;
+        }
+
+        @Override
+        public String getConfigName()
+        {
+            return TestConfigSourceProvider.class.getName();
+        }
+
+		@Override
+		public boolean isScannable() {
+			return false;
+		}
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TypedResolverTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TypedResolverTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TypedResolverTest.java
new file mode 100644
index 0000000..dab4d3d
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TypedResolverTest.java
@@ -0,0 +1,235 @@
+/*
+ * 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.deltaspike.test.core.api.config;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+import org.apache.deltaspike.core.api.projectstage.ProjectStage;
+import org.apache.deltaspike.core.util.ProjectStageProducer;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.concurrent.TimeUnit;
+
+public class TypedResolverTest
+{
+    @Before
+    public void init()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.UnitTest);
+    }
+
+    @Test
+    public void testValidTypes()
+    {
+        Assert.assertEquals("configured", ConfigResolver.resolve("deltaspike.test.string-value").getValue());
+
+        Assert.assertEquals(Boolean.FALSE, ConfigResolver.resolve("deltaspike.test.boolean-value").as(Boolean.class)
+                .getValue());
+
+        Assert.assertEquals(TestConfigSource.class, ConfigResolver.resolve("deltaspike.test.class-value").as(Class
+                .class).getValue());
+
+        Assert.assertEquals(5l, (int) ConfigResolver.resolve("deltaspike.test.integer-value").as(Integer.class)
+                .getValue());
+
+        Assert.assertEquals(8589934592l, (long) ConfigResolver.resolve("deltaspike.test.long-value").as(Long.class)
+                .getValue());
+
+        Assert.assertEquals(-1.1f, (float) ConfigResolver.resolve("deltaspike.test.float-value").as(Float.class)
+                .getValue(), 0);
+
+        Assert.assertEquals(4e40d, (double) ConfigResolver.resolve("deltaspike.test.double-value").as(Double.class)
+                .getValue(), 0);
+    }
+
+    @Test
+    public void testConverter()
+    {
+        Assert.assertEquals(new GregorianCalendar(2014, 12, 24).getTime(),
+                ConfigResolver.resolve("deltaspike.test.date-value")
+                        .as(Date.class, new TestDateConverter()).getValue());
+
+        // test fallback to default
+        Assert.assertEquals(new GregorianCalendar(2015, 01, 01).getTime(),
+                ConfigResolver.resolve("deltaspike.test.INVALID-date-value")
+                        .as(Date.class, new TestDateConverter())
+                        .withDefault(new GregorianCalendar(2015, 01, 01).getTime())
+                        .getValue());
+    }
+
+    @Test
+    public void testProjectStageAware()
+    {
+        Assert.assertEquals("unittestvalue",
+                ConfigResolver.resolve("testkey")
+                        .withCurrentProjectStage(true)
+                        .getValue());
+
+        Assert.assertEquals("testvalue",
+                ConfigResolver.resolve("testkey")
+                        .withCurrentProjectStage(false)
+                        .getValue());
+
+        // property without PS, with PS-aware
+        Assert.assertEquals("testvalue",
+                ConfigResolver.resolve("testkey2")
+                        .withCurrentProjectStage(true)
+                        .getValue());
+    }
+
+    @Test
+    public void testParameterized()
+    {
+        // param OK, ps OK
+        Assert.assertEquals("TestDataSource",
+                ConfigResolver.resolve("dataSource")
+                        .withCurrentProjectStage(true)
+                        .parameterizedBy("dbvendor")
+                        .getValue());
+
+        // param OK, NO ps
+        Assert.assertEquals("PostgreDataSource",
+                ConfigResolver.resolve("dataSource")
+                        .withCurrentProjectStage(false)
+                        .parameterizedBy("dbvendor")
+                        .getValue());
+
+        // param doesn't resolve, ps OK
+        Assert.assertEquals("UnitTestDataSource",
+                ConfigResolver.resolve("dataSource")
+                        .withCurrentProjectStage(true)
+                        .parameterizedBy("INVALIDPARAMETER")
+                        .getValue());
+
+        // param OK, ps OK, NO base.param.ps, NO base.param, fall back to base.ps
+        Assert.assertEquals("UnitTestDataSource",
+                ConfigResolver.resolve("dataSource")
+                        .withCurrentProjectStage(true)
+                        .parameterizedBy("dbvendor3")
+                        .getValue());
+
+        // param OK, NO ps, base.param undefined, fall back to base
+        Assert.assertEquals("DefaultDataSource",
+                ConfigResolver.resolve("dataSource")
+                        .withCurrentProjectStage(false)
+                        .parameterizedBy("dbvendor3")
+                        .getValue());
+    }
+
+    @Test
+    public void testDefault()
+    {
+        Assert.assertEquals(10l,
+                (long) ConfigResolver.resolve("INVALIDKEY")
+                .as(Long.class)
+                .withDefault(10l).getValue());
+
+        // string default
+        Assert.assertEquals(10l,
+                (long) ConfigResolver.resolve("INVALIDKEY")
+                        .as(Long.class)
+                        .withStringDefault("10").getValue());
+    }
+
+    @Test
+    public void testStrict()
+    {
+        Assert.assertEquals("TestDataSource",
+                ConfigResolver.resolve("dataSource")
+                        .withCurrentProjectStage(true)
+                        .parameterizedBy("dbvendor")
+                        .strictly(true)
+                        .getValue());
+
+        // no base.param, no value for base.param.ps
+        Assert.assertEquals(null,
+                ConfigResolver.resolve("dataSource")
+                        .withCurrentProjectStage(true)
+                        .parameterizedBy("dbvendor3")
+                        .strictly(true)
+                        .getValue());
+
+        // valid base.param, but no base.param.ps
+        Assert.assertEquals(null,
+                ConfigResolver.resolve("dataSource")
+                        .withCurrentProjectStage(true)
+                        .parameterizedBy("dbvendor2")
+                        .strictly(true)
+                        .getValue());
+    }
+
+    @Test
+    public void testGets()
+    {
+        ConfigResolver.TypedResolver<String> resolver = ConfigResolver.resolve("dataSource")
+                .withCurrentProjectStage(true)
+                .parameterizedBy("dbvendor")
+                .withDefault("TESTDEFAULT");
+
+        Assert.assertEquals("TestDataSource", resolver.getValue());
+        Assert.assertEquals("dataSource", resolver.getKey());
+        Assert.assertEquals("TESTDEFAULT", resolver.getDefaultValue());
+        Assert.assertEquals("dataSource.mysql.UnitTest", resolver.getResolvedKey());
+
+
+        ConfigResolver.TypedResolver<String> resolver2 = ConfigResolver.resolve("testkey2")
+                .withCurrentProjectStage(true)
+                .parameterizedBy("INVALIDPARAMETER");
+
+
+        Assert.assertEquals("testvalue", resolver2.getValue());
+        Assert.assertEquals("testkey2", resolver2.getResolvedKey());
+    }
+
+    @Test
+    public void testWithCacheTime() throws Exception
+    {
+        ConfigResolver.TypedResolver<String> resolver = ConfigResolver.resolve("dataSource")
+            .withCurrentProjectStage(true)
+            .parameterizedBy("dbvendor")
+            .cacheFor(TimeUnit.MILLISECONDS, 5)
+            .withDefault("TESTDEFAULT");
+
+        Assert.assertEquals("TestDataSource", resolver.getValue());
+        Assert.assertEquals("TestDataSource", resolver.getValue());
+        Assert.assertEquals("dataSource", resolver.getKey());
+        Assert.assertEquals("TESTDEFAULT", resolver.getDefaultValue());
+        Assert.assertEquals("dataSource.mysql.UnitTest", resolver.getResolvedKey());
+
+        // because the clock steps in certain OS is only 16ms
+        Thread.sleep(35L);
+        Assert.assertEquals("TestDataSource", resolver.getValue());
+    }
+
+    public static class TestDateConverter implements ConfigResolver.Converter<Date> {
+
+        @Override
+        public Date convert(String value)
+        {
+            String[] parts = value.split("-");
+            return new GregorianCalendar(Integer.valueOf(parts[0]), Integer.valueOf(parts[1]),
+                    Integer.valueOf(parts[2])).getTime();
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/util/activation/EditableTestDeactivator.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/util/activation/EditableTestDeactivator.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/util/activation/EditableTestDeactivator.java
new file mode 100644
index 0000000..173264c
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/util/activation/EditableTestDeactivator.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.deltaspike.test.util.activation;
+
+import org.apache.deltaspike.core.spi.activation.ClassDeactivator;
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class EditableTestDeactivator implements ClassDeactivator
+{
+    private static Map<Class<? extends Deactivatable>, Boolean> result = new HashMap<Class<? extends Deactivatable>, Boolean>();
+
+    @Override
+    public Boolean isActivated(Class<? extends Deactivatable> targetClass)
+    {
+        return result.get(targetClass);
+    }
+
+    public static void activate(Class<? extends Deactivatable> classToActivate)
+    {
+        result.put(classToActivate, true);
+    }
+
+    public static void deactivate(Class<? extends Deactivatable> classToActivate)
+    {
+        result.put(classToActivate, false);
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/util/activation/ProjectStageDependentClassDeactivationTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/util/activation/ProjectStageDependentClassDeactivationTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/util/activation/ProjectStageDependentClassDeactivationTest.java
new file mode 100644
index 0000000..2068320
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/util/activation/ProjectStageDependentClassDeactivationTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.deltaspike.test.util.activation;
+
+import org.apache.deltaspike.core.api.projectstage.ProjectStage;
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+import org.apache.deltaspike.core.util.ClassDeactivationUtils;
+import org.apache.deltaspike.core.util.ProjectStageProducer;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ProjectStageDependentClassDeactivationTest
+{
+    @Test
+    public void deactivationResultInProjectStageUnitTest()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.UnitTest);
+
+        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
+        EditableTestDeactivator.activate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
+
+        EditableTestDeactivator.deactivate(classToCheck);
+        Assert.assertEquals(false, ClassDeactivationUtils.isActivated(classToCheck));
+    }
+
+    @Test
+    public void deactivationResultInProjectStageDevelopment()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.Development);
+
+        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
+        EditableTestDeactivator.activate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
+
+        EditableTestDeactivator.deactivate(classToCheck);
+        Assert.assertEquals(false, ClassDeactivationUtils.isActivated(classToCheck));
+    }
+
+    @Test
+    public void deactivationResultInProjectStageProduction()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.Production);
+
+        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
+        EditableTestDeactivator.activate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
+
+        EditableTestDeactivator.deactivate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result
+    }
+
+    @Test
+    public void deactivationResultInProjectStageIntegrationTest()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.IntegrationTest);
+
+        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
+        EditableTestDeactivator.activate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
+
+        EditableTestDeactivator.deactivate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result
+    }
+
+    @Test
+    public void deactivationResultInProjectStageStaging()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.Staging);
+
+        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
+        EditableTestDeactivator.activate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
+
+        EditableTestDeactivator.deactivate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result
+    }
+
+    @Test
+    public void deactivationResultInProjectStageSystemTest()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.SystemTest);
+
+        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
+        EditableTestDeactivator.activate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
+
+        EditableTestDeactivator.deactivate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result
+    }
+
+    private static class TestDeactivatable implements Deactivatable
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource b/deltaspike/core/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource
new file mode 100644
index 0000000..833d367
--- /dev/null
+++ b/deltaspike/core/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource
@@ -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 of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#####################################################################################
+
+org.apache.deltaspike.test.core.api.config.TestConfigSource

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider b/deltaspike/core/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider
new file mode 100644
index 0000000..f06f220
--- /dev/null
+++ b/deltaspike/core/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider
@@ -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 of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+org.apache.deltaspike.test.core.api.config.TestConfigSourceProvider


[4/4] deltaspike git commit: DELTASPIKE-1322 mv more config pieces over 2 impl

Posted by st...@apache.org.
DELTASPIKE-1322 mv more config pieces over 2 impl


Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/5b07e197
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/5b07e197
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/5b07e197

Branch: refs/heads/master
Commit: 5b07e197cb808cee108e1935cae18fc199c82a9f
Parents: bd638aa
Author: Mark Struberg <st...@apache.org>
Authored: Mon Mar 5 15:51:53 2018 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Mon Mar 5 15:51:53 2018 +0100

----------------------------------------------------------------------
 .../deltaspike/core/api/config/Config.java      | 148 +++--
 .../core/api/config/ConfigResolver.java         | 615 ++-----------------
 .../core/api/config/ConfigResolverContext.java  |  73 ---
 .../deltaspike/core/impl/config/ConfigImpl.java | 320 +++++-----
 .../core/impl/config/ConfigResolverContext.java |  73 +++
 .../core/impl/config/TypedResolverImpl.java     | 565 +++++++++++++++++
 6 files changed, 918 insertions(+), 876 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/5b07e197/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/Config.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/Config.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/Config.java
index 2422c7b..47d2c50 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/Config.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/Config.java
@@ -1,68 +1,80 @@
-/*
- * 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.deltaspike.core.api.config;
-
-import org.apache.deltaspike.core.spi.config.ConfigFilter;
-import org.apache.deltaspike.core.spi.config.ConfigSource;
-
-import java.util.List;
-
-/**
- * The Configuration for an application/ClassLoader.
- */
-public interface Config
-{
-
-    /**
-     * @return all the current ConfigSources for this Config
-     */
-    ConfigSource[] getConfigSources();
-
-    /**
-     * This method can be used for programmatically adding {@link ConfigSource}s.
-     * It is not needed for normal 'usage' by end users, but only for Extension Developers!
-     *
-     * @param configSourcesToAdd the ConfigSources to add
-     */
-    void addConfigSources(List<ConfigSource> configSourcesToAdd);
-
-    /**
-     * @return the {@link ConfigFilter}s for the current application.
-     */
-    List<ConfigFilter> getConfigFilters();
-
-    /**
-     * Add a {@link ConfigFilter} to the ConfigResolver. This will only affect the current WebApp (or more precisely the
-     * current ClassLoader and it's children).
-     *
-     * @param configFilter
-     */
-    void addConfigFilter(ConfigFilter configFilter);
-
-    /**
-     * Filter the configured value.
-     * This can e.g. be used for decryption.
-     * @param key the key of the config property
-     * @param value to be filtered
-     * @param forLog whether the value is intended to be presented to some humans somehow.
-     *               If filtered for logging, then secrets might get starred out '*****'.
-     * @return the filtered value
-     */
-    String filterConfigValue(String key, String value, boolean forLog);
-}
+/*
+ * 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.deltaspike.core.api.config;
+
+import org.apache.deltaspike.core.spi.config.ConfigFilter;
+import org.apache.deltaspike.core.spi.config.ConfigSource;
+
+import java.util.List;
+
+/**
+ * The Configuration for an application/ClassLoader.
+ */
+public interface Config
+{
+
+    /**
+     * The entry point to the builder-based optionally typed configuration resolution mechanism.
+     *
+     * String is the default type for configuration entries and is not considered a 'type' by this resolver. Therefore
+     * an UntypedResolver is returned by this method. To convert the configuration value to another type, call
+     * {@link ConfigResolver.UntypedResolver#as(Class)}.
+     *
+     * @param name The property key to resolve
+     * @return A builder for configuration resolution.
+     */
+    ConfigResolver.UntypedResolver<String> resolve(String name);
+
+    /**
+     * @return all the current ConfigSources for this Config
+     */
+    ConfigSource[] getConfigSources();
+
+    /**
+     * This method can be used for programmatically adding {@link ConfigSource}s.
+     * It is not needed for normal 'usage' by end users, but only for Extension Developers!
+     *
+     * @param configSourcesToAdd the ConfigSources to add
+     */
+    void addConfigSources(List<ConfigSource> configSourcesToAdd);
+
+    /**
+     * @return the {@link ConfigFilter}s for the current application.
+     */
+    List<ConfigFilter> getConfigFilters();
+
+    /**
+     * Add a {@link ConfigFilter} to the ConfigResolver. This will only affect the current WebApp (or more precisely the
+     * current ClassLoader and it's children).
+     *
+     * @param configFilter
+     */
+    void addConfigFilter(ConfigFilter configFilter);
+
+    /**
+     * Filter the configured value.
+     * This can e.g. be used for decryption.
+     * @param key the key of the config property
+     * @param value to be filtered
+     * @param forLog whether the value is intended to be presented to some humans somehow.
+     *               If filtered for logging, then secrets might get starred out '*****'.
+     * @return the filtered value
+     */
+    String filterConfigValue(String key, String value, boolean forLog);
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/5b07e197/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
index fa280ef..8a5dbe9 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
@@ -29,17 +29,13 @@ import java.util.List;
 import java.util.Map;
 import java.util.ServiceLoader;
 import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.enterprise.inject.Typed;
 
-import org.apache.deltaspike.core.api.projectstage.ProjectStage;
 import org.apache.deltaspike.core.spi.config.ConfigFilter;
 import org.apache.deltaspike.core.spi.config.ConfigSource;
 import org.apache.deltaspike.core.util.ClassUtils;
-import org.apache.deltaspike.core.util.ExceptionUtils;
-import org.apache.deltaspike.core.util.ProjectStageProducer;
 
 /**
  * The main entry point to the DeltaSpike configuration mechanism.
@@ -155,11 +151,10 @@ public final class ConfigResolver
 
     public static String getPropertyValue(String key, String defaultValue, boolean evaluateVariables)
     {
-        ConfigResolverContext configResolverContext = evaluateVariables ?
-                ConfigResolverContext.EVAL_VARIABLES : ConfigResolverContext.NONE;
-        String value = getPropertyValue(key, configResolverContext);
-
-        return fallbackToDefaultIfEmpty(key, value, defaultValue, configResolverContext);
+        return getConfigProvider().getConfig().resolve(key)
+                .withDefault(defaultValue)
+                .evaluateVariables(evaluateVariables)
+                .getValue();
     }
 
     /**
@@ -172,9 +167,10 @@ public final class ConfigResolver
      */
     public static String getPropertyValue(String key)
     {
-        return getPropertyValue(
-                key, 
-                new ConfigResolverContext().setEvaluateVariables(true));
+        return getConfigProvider().getConfig().resolve(key)
+                .evaluateVariables(true)
+                .withCurrentProjectStage(false)
+                .getValue();
     }
 
     /**
@@ -188,9 +184,10 @@ public final class ConfigResolver
      */
     public static String getPropertyValue(String key, boolean evaluateVariables)
     {
-        return getPropertyValue(
-                key, 
-                evaluateVariables ? ConfigResolverContext.EVAL_VARIABLES : ConfigResolverContext.NONE);
+        return getConfigProvider().getConfig().resolve(key)
+                .evaluateVariables(evaluateVariables)
+                .withCurrentProjectStage(false)
+                .getValue();
     }
 
     /**
@@ -214,17 +211,10 @@ public final class ConfigResolver
      */
     public static String getProjectStageAwarePropertyValue(String key)
     {
-        ConfigResolverContext configResolverContext = ConfigResolverContext.PROJECTSTAGE_EVAL_VARIABLES;
-        
-        ProjectStage ps = getProjectStage();
-
-        String value = getPropertyValue(key + '.' + ps, configResolverContext);
-        if (value == null)
-        {
-            value = getPropertyValue(key, configResolverContext);
-        }
-
-        return value;
+        return getConfigProvider().getConfig().resolve(key)
+                .withCurrentProjectStage(true)
+                .evaluateVariables(true)
+                .getValue();
     }
     /**
      * {@link #getProjectStageAwarePropertyValue(String)} which returns the provided default value if no configured
@@ -238,9 +228,11 @@ public final class ConfigResolver
      */
     public static String getProjectStageAwarePropertyValue(String key, String defaultValue)
     {
-        String value = getProjectStageAwarePropertyValue(key);
-
-        return fallbackToDefaultIfEmpty(key, value, defaultValue, ConfigResolverContext.PROJECTSTAGE_EVAL_VARIABLES);
+        return getConfigProvider().getConfig().resolve(key)
+                .withCurrentProjectStage(true)
+                .withDefault(defaultValue)
+                .evaluateVariables(true)
+                .getValue();
     }
 
     /**
@@ -284,21 +276,11 @@ public final class ConfigResolver
      */
     public static String getPropertyAwarePropertyValue(String key, String property)
     {
-        String propertyValue = getProjectStageAwarePropertyValue(property);
-
-        String value = null;
-
-        if (propertyValue != null && propertyValue.length() > 0)
-        {
-            value = getProjectStageAwarePropertyValue(key + '.' + propertyValue);
-        }
-
-        if (value == null)
-        {
-            value = getProjectStageAwarePropertyValue(key);
-        }
-
-        return value;
+        return getConfigProvider().getConfig().resolve(key)
+                .withCurrentProjectStage(true)
+                .parameterizedBy(property)
+                .evaluateVariables(true)
+                .getValue();
     }
 
     /**
@@ -318,81 +300,12 @@ public final class ConfigResolver
      */
     public static String getPropertyAwarePropertyValue(String key, String property, String defaultValue)
     {
-        String value = getPropertyAwarePropertyValue(key, property);
-
-        return fallbackToDefaultIfEmpty(key, value, defaultValue, ConfigResolverContext.PROJECTSTAGE_EVAL_VARIABLES);
-    }
-    
-    private static String getPropertyValue(String key, ConfigResolverContext configResolverContext)
-    {
-        if (key == null)
-        {
-            return null;
-        }
-
-        ConfigSource[] appConfigSources = getConfigSources();
-        String value;
-
-        for (ConfigSource configSource : appConfigSources)
-        {
-            value = configSource.getPropertyValue(key);
-
-            if (value != null)
-            {
-                LOG.log(Level.FINE, "found value {0} for key {1} in ConfigSource {2}.",
-                        new Object[]{filterConfigValueForLog(key, value), key, configSource.getConfigName()});
-
-                if (configResolverContext.isEvaluateVariables())
-                {
-                    value = resolveVariables(value, configResolverContext);
-                }
-
-                return filterConfigValue(key, value);
-            }
-
-            LOG.log(Level.FINER, "NO value found for key {0} in ConfigSource {1}.",
-                    new Object[]{key, configSource.getConfigName()});
-        }
-
-        return null;        
-    }
-
-    /**
-     * recursively resolve any ${varName} in the value
-     */
-    private static String resolveVariables(String value, ConfigResolverContext configResolverContext)
-    {
-        int startVar = 0;
-        while ((startVar = value.indexOf("${", startVar)) >= 0)
-        {
-            int endVar = value.indexOf("}", startVar);
-            if (endVar <= 0)
-            {
-                break;
-            }
-            String varName = value.substring(startVar + 2, endVar);
-            if (varName.isEmpty())
-            {
-                break;
-            }
-            
-            String variableValue;
-            if (configResolverContext.isProjectStageAware())
-            {
-                variableValue = getProjectStageAwarePropertyValue(varName);
-            }
-            else
-            {
-                variableValue = getPropertyValue(varName, true);
-            }
-            
-            if (variableValue != null)
-            {
-                value = value.replace("${" + varName + "}", variableValue);
-            }
-            startVar++;
-        }
-        return value;
+        return getConfigProvider().getConfig().resolve(key)
+                .withCurrentProjectStage(true)
+                .parameterizedBy(property)
+                .withDefault(defaultValue)
+                .evaluateVariables(true)
+                .getValue();
     }
 
     /**
@@ -438,8 +351,8 @@ public final class ConfigResolver
     public static Map<String, String> getAllProperties()
     {
         // must use a new list because Arrays.asList() is resistant to sorting on some JVMs:
-        List<ConfigSource> appConfigSources = sortAscending(new ArrayList<ConfigSource>(
-                Arrays.<ConfigSource> asList(getConfigSources())));
+        List<ConfigSource> appConfigSources = sortAscending(new ArrayList<>(
+                Arrays.asList(getConfigSources())));
         Map<String, String> result = new HashMap<String, String>();
 
         for (ConfigSource configSource : appConfigSources)
@@ -453,7 +366,7 @@ public final class ConfigResolver
         return Collections.unmodifiableMap(result);
     }
 
-    public static synchronized ConfigSource[] getConfigSources()
+    public static ConfigSource[] getConfigSources()
     {
         return getConfigProvider().getConfig().getConfigSources();
     }
@@ -474,29 +387,6 @@ public final class ConfigResolver
         return configSources;
     }
 
-    private static ProjectStage getProjectStage()
-    {
-        return ProjectStageProducer.getInstance().getProjectStage();
-    }
-
-    private static <T> T fallbackToDefaultIfEmpty(String key, T value, T defaultValue,
-                                                  ConfigResolverContext configResolverContext)
-    {
-        if (value == null || (value instanceof String && ((String)value).isEmpty()))
-        {
-            if (configResolverContext != null && defaultValue instanceof String
-                    && configResolverContext.isEvaluateVariables())
-            {
-                defaultValue = (T) resolveVariables((String) defaultValue, configResolverContext);
-            }
-            LOG.log(Level.FINE, "no configured value found for key {0}, using default value {1}.",
-                    new Object[]{key, defaultValue});
-
-            return defaultValue;
-        }
-
-        return value;
-    }
 
     /**
      * Filter the configured value.
@@ -711,440 +601,7 @@ public final class ConfigResolver
      */
     public static UntypedResolver<String> resolve(String name)
     {
-        return new PropertyBuilder<String>(name);
-    }
-
-    private static class PropertyBuilder<T> implements UntypedResolver<T>
-    {
-
-        private String keyOriginal;
-
-        private String keyResolved;
-
-        private Type configEntryType = String.class;
-
-        private boolean withDefault = false;
-        private T defaultValue;
-
-        private boolean projectStageAware = true;
-
-        private String propertyParameter;
-
-        private String parameterValue;
-
-        private boolean strictly = false;
-
-        private boolean isList = false;
-
-        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 PropertyBuilder()
-        {
-        }
-
-        protected PropertyBuilder(String propertyName)
-        {
-            this.keyOriginal = propertyName;
-        }
-
-        @Override
-        @SuppressWarnings("unchecked")
-        public <N> TypedResolver<N> as(Class<N> clazz)
-        {
-            configEntryType = clazz;
-            return (TypedResolver<N>) this;
-        }
-
-        @Override
-        @SuppressWarnings("unchecked")
-        public TypedResolver<List<T>> asList()
-        {
-            isList = true;
-            TypedResolver<List<T>> listTypedResolver = (TypedResolver<List<T>>) this;
-
-            if (defaultValue == null)
-            {
-                // the default for lists is an empty list instead of null
-                return listTypedResolver.withDefault(Collections.<T>emptyList());
-            }
-
-            return listTypedResolver;
-        }
-
-        @Override
-        @SuppressWarnings("unchecked")
-        public <N> TypedResolver<N> as(Class<N> clazz, Converter<N> converter)
-        {
-            configEntryType = clazz;
-            this.converter = converter;
-
-            return (TypedResolver<N>) this;
-        }
-
-        @Override
-        @SuppressWarnings("unchecked")
-        public <N> TypedResolver<N> as(Type clazz, Converter<N> converter)
-        {
-            configEntryType = clazz;
-            this.converter = converter;
-
-            return (TypedResolver<N>) this;
-        }
-
-        @Override
-        public TypedResolver<T> withDefault(T value)
-        {
-            defaultValue = value;
-            withDefault = true;
-            return this;
-        }
-
-        @Override
-        public TypedResolver<T> withStringDefault(String value)
-        {
-            if (value == null || value.isEmpty())
-            {
-                throw new RuntimeException("Empty String or null supplied as string-default value for property "
-                        + keyOriginal);
-            }
-
-            if (isList)
-            {
-                defaultValue = splitAndConvertListValue(value);
-            }
-            else
-            {
-                defaultValue = convert(value);
-            }
-            withDefault = true;
-            return this;
-        }
-
-        @Override
-        public TypedResolver<T> cacheFor(TimeUnit timeUnit, long value)
-        {
-            this.cacheTimeMs = timeUnit.toMillis(value);
-            return this;
-        }
-
-        @Override
-        public TypedResolver<T> parameterizedBy(String propertyName)
-        {
-            this.propertyParameter = propertyName;
-
-            if (propertyParameter != null && !propertyParameter.isEmpty())
-            {
-                String parameterValue = ConfigResolver
-                        .resolve(propertyParameter)
-                        .withCurrentProjectStage(projectStageAware)
-                        .getValue();
-
-                if (parameterValue != null && !parameterValue.isEmpty())
-                {
-                    this.parameterValue = parameterValue;
-                }
-            }
-
-            return this;
-        }
-
-        @Override
-        public TypedResolver<T> withCurrentProjectStage(boolean with)
-        {
-            this.projectStageAware = with;
-            return this;
-        }
-
-        @Override
-        public TypedResolver<T> strictly(boolean strictly)
-        {
-            this.strictly = strictly;
-            return this;
-        }
-
-        @Override
-        public TypedResolver<T> evaluateVariables(boolean evaluateVariables)
-        {
-            this.evaluateVariables = evaluateVariables;
-            return this;
-        }
-
-        @Override
-        public TypedResolver<T> logChanges(boolean logChanges)
-        {
-            this.logChanges = logChanges;
-            return this;
-        }
-
-        @Override
-        public T getValue()
-        {
-            long now = -1;
-            if (cacheTimeMs > 0)
-            {
-                now = System.currentTimeMillis();
-                if (now <= reloadAfter)
-                {
-                    return lastValue;
-                }
-            }
-
-            String valueStr = resolveStringValue();
-            T value;
-            if (isList)
-            {
-                value = splitAndConvertListValue(valueStr);
-            }
-            else
-            {
-                value = convert(valueStr);
-            }
-
-            if (withDefault)
-            {
-                ConfigResolverContext configResolverContext = new ConfigResolverContext()
-                        .setEvaluateVariables(evaluateVariables)
-                        .setProjectStageAware(projectStageAware);
-                value = fallbackToDefaultIfEmpty(keyResolved, value, defaultValue, configResolverContext);
-                if (isList && String.class.isInstance(value))
-                {
-                    value = splitAndConvertListValue(String.class.cast(value));
-                }
-            }
-
-            if (logChanges && (value != null && !value.equals(lastValue) || (value == null && lastValue != null)) )
-            {
-                LOG.log(Level.INFO, "New value {0} for key {1}.",
-                    new Object[]{filterConfigValueForLog(keyOriginal, valueStr), keyOriginal});
-            }
-
-            lastValue = value;
-
-            if (cacheTimeMs > 0)
-            {
-                reloadAfter = now + cacheTimeMs;
-            }
-
-            return value;
-        }
-
-        private T splitAndConvertListValue(String valueStr)
-        {
-            if (valueStr == null)
-            {
-                return null;
-            }
-
-            List list = new ArrayList();
-            StringBuilder currentValue = new StringBuilder();
-            int length = valueStr.length();
-            for (int i = 0; i < length; i++)
-            {
-                char c = valueStr.charAt(i);
-                if (c == '\\')
-                {
-                    if (i < length - 1)
-                    {
-                        char nextC = valueStr.charAt(i + 1);
-                        currentValue.append(nextC);
-                        i++;
-                    }
-                }
-                else if (c == ',')
-                {
-                    String trimedVal = currentValue.toString().trim();
-                    if (trimedVal.length() > 0)
-                    {
-                        list.add(convert(trimedVal));
-                    }
-
-                    currentValue.setLength(0);
-                }
-                else
-                {
-                    currentValue.append(c);
-                }
-            }
-
-            String trimedVal = currentValue.toString().trim();
-            if (trimedVal.length() > 0)
-            {
-                list.add(convert(trimedVal));
-            }
-
-            return (T) list;
-        }
-
-        @Override
-        public String getKey()
-        {
-            return keyOriginal;
-        }
-
-        @Override
-        public String getResolvedKey()
-        {
-            return keyResolved;
-        }
-
-        @Override
-        public T getDefaultValue()
-        {
-            return defaultValue;
-        }
-
-        /**
-         * Performs the resolution cascade
-         */
-        private String resolveStringValue()
-        {
-            ProjectStage ps = null;
-            String value = null;
-            keyResolved = keyOriginal;
-            int keySuffices = 0;
-
-            // make the longest key
-            // first, try appending resolved parameter
-            if (propertyParameter != null && !propertyParameter.isEmpty())
-            {
-                if (parameterValue != null && !parameterValue.isEmpty())
-                {
-                    keyResolved += "." + parameterValue;
-                    keySuffices++;
-                }
-                // if parameter value can't be resolved and strictly
-                else if (strictly)
-                {
-                    return null;
-                }
-            }
-
-            // try appending projectstage
-            if (projectStageAware)
-            {
-                ps = getProjectStage();
-                keyResolved += "." + ps;
-                keySuffices++;
-            }
-
-            // make initial resolution of longest key
-            value = getPropertyValue(keyResolved, evaluateVariables);
-
-            // try fallbacks if not strictly
-            if (value == null && !strictly)
-            {
-
-                // by the length of the longest resolved key already tried
-                // breaks are left out intentionally
-                switch (keySuffices)
-                {
-
-                    case 2:
-                        // try base.param
-                        keyResolved = keyOriginal + "." + parameterValue;
-                        value = getPropertyValue(keyResolved, null, evaluateVariables);
-
-                        if (value != null)
-                        {
-                            return value;
-                        }
-
-                        // try base.ps
-                        ps = getProjectStage();
-                        keyResolved = keyOriginal + "." + ps;
-                        value = getPropertyValue(keyResolved, null, evaluateVariables);
-
-                        if (value != null)
-                        {
-                            return value;
-                        }
-
-                    case 1:
-                        // try base
-                        keyResolved = keyOriginal;
-                        value = getPropertyValue(keyResolved, null, evaluateVariables);
-                        return value;
-
-                    default:
-                        // the longest key was the base, no fallback
-                        return null;
-                }
-            }
-
-            return value;
-        }
-
-        /**
-         * If a converter was provided for this builder, it takes precedence over the built-in converters.
-         */
-        private T convert(String value)
-        {
-            if (value == null)
-            {
-                return null;
-            }
-
-            Object result = null;
-
-            if (this.converter != null)
-            {
-                try
-                {
-                    result = converter.convert(value);
-                }
-                catch (Exception e)
-                {
-                    throw ExceptionUtils.throwAsRuntimeException(e);
-                }
-            }
-            else if (String.class.equals(configEntryType))
-            {
-                result = value;
-            }
-            else if (Class.class.equals(configEntryType))
-            {
-                result = ClassUtils.tryToLoadClassForName(value);
-            }
-            else if (Boolean.class.equals(configEntryType))
-            {
-                Boolean isTrue = "TRUE".equalsIgnoreCase(value);
-                isTrue |= "1".equalsIgnoreCase(value);
-                isTrue |= "YES".equalsIgnoreCase(value);
-                isTrue |= "Y".equalsIgnoreCase(value);
-                isTrue |= "JA".equalsIgnoreCase(value);
-                isTrue |= "J".equalsIgnoreCase(value);
-                isTrue |= "OUI".equalsIgnoreCase(value);
-
-                result = isTrue;
-            }
-            else if (Integer.class.equals(configEntryType))
-            {
-                result = Integer.parseInt(value);
-            }
-            else if (Long.class.equals(configEntryType))
-            {
-                result = Long.parseLong(value);
-            }
-            else if (Float.class.equals(configEntryType))
-            {
-                result = Float.parseFloat(value);
-            }
-            else if (Double.class.equals(configEntryType))
-            {
-                result = Double.parseDouble(value);
-            }
-
-            return (T) result;
-        }
-
+        return getConfigProvider().getConfig().resolve(name);
     }
 
 

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/5b07e197/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolverContext.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolverContext.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolverContext.java
deleted file mode 100644
index 223932f..0000000
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolverContext.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.deltaspike.core.api.config;
-
-class ConfigResolverContext
-{
-    static final ConfigResolverContext NONE = new ConfigResolverContext();
-
-    static final ConfigResolverContext EVAL_VARIABLES = new ConfigResolverContext().setEvaluateVariables(true);
-
-    static final ConfigResolverContext PROJECTSTAGE = new ConfigResolverContext().setProjectStageAware(true);
-
-    static final ConfigResolverContext PROJECTSTAGE_EVAL_VARIABLES = new ConfigResolverContext()
-                                                                            .setProjectStageAware(true)
-                                                                            .setEvaluateVariables(true);
-
-    private boolean projectStageAware;
-    private boolean evaluateVariables;
-    private boolean propertyAware;
-
-    public ConfigResolverContext()
-    {
-    }
-    
-    public ConfigResolverContext setEvaluateVariables(final boolean evaluateVariables)
-    {
-        this.evaluateVariables = evaluateVariables;
-        return this;
-    }   
-    
-    public boolean isEvaluateVariables()
-    {
-        return evaluateVariables;
-    }
-
-    public ConfigResolverContext setProjectStageAware(final boolean projectStageAware)
-    {
-        this.projectStageAware = projectStageAware;
-        return this;
-    }
-    
-    public boolean isProjectStageAware()
-    {
-        return projectStageAware;
-    }
-
-    public ConfigResolverContext setPropertyAware(final boolean propertyAware)
-    {
-        this.propertyAware = propertyAware;
-        return this;
-    }
-    
-    public boolean isPropertyAware()
-    {
-        return propertyAware;
-    }
-}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/5b07e197/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java
index 54c1ca9..6f60dda 100644
--- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java
@@ -1,156 +1,164 @@
-/*
- * 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.deltaspike.core.impl.config;
-
-import org.apache.deltaspike.core.api.config.Config;
-import org.apache.deltaspike.core.spi.config.ConfigFilter;
-import org.apache.deltaspike.core.spi.config.ConfigSource;
-import org.apache.deltaspike.core.spi.config.ConfigSourceProvider;
-import org.apache.deltaspike.core.util.ServiceUtils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * The internal implementation of the Config interface
- */
-public class ConfigImpl implements Config
-{
-    private static final Logger LOG = Logger.getLogger(ConfigImpl.class.getName());
-
-    private final ClassLoader classLoader;
-
-    private ConfigSource[] configSources;
-    private List<ConfigFilter> configFilters;
-
-    public ConfigImpl(ClassLoader classLoader)
-    {
-        this.classLoader = classLoader;
-    }
-
-    /**
-     * Performs all the initialisation of the default
-     * ConfigSources, ConfigFilters, etc
-     */
-    void init()
-    {
-        List<ConfigSource> appConfigSources
-            = ServiceUtils.loadServiceImplementations(ConfigSource.class, false, classLoader);
-
-        List<ConfigSourceProvider> configSourceProviderServiceLoader
-            = ServiceUtils.loadServiceImplementations(ConfigSourceProvider.class, false, classLoader);
-
-        for (ConfigSourceProvider configSourceProvider : configSourceProviderServiceLoader)
-        {
-            appConfigSources.addAll(configSourceProvider.getConfigSources());
-        }
-        addConfigSources(appConfigSources);
-
-        if (LOG.isLoggable(Level.FINE))
-        {
-            for (ConfigSource cs : appConfigSources)
-            {
-                LOG.log(Level.FINE, "Adding ordinal {0} ConfigSource {1}",
-                        new Object[]{cs.getOrdinal(), cs.getConfigName()});
-            }
-        }
-
-        List<ConfigFilter> configFilters
-            = ServiceUtils.loadServiceImplementations(ConfigFilter.class, false, classLoader);
-        this.configFilters = new CopyOnWriteArrayList<>(configFilters);
-    }
-
-
-    @Override
-    public ConfigSource[] getConfigSources()
-    {
-        return configSources;
-    }
-
-    @Override
-    public void addConfigSources(List<ConfigSource> configSourcesToAdd)
-    {
-        List<ConfigSource> allConfigSources = new ArrayList<>();
-        if (this.configSources != null)
-        {
-            for (ConfigSource configSource : this.configSources)
-            {
-                allConfigSources.add(configSource);
-            }
-        }
-
-        allConfigSources.addAll(configSourcesToAdd);
-
-        this.configSources = sortDescending(allConfigSources);
-    }
-
-    @Override
-    public List<ConfigFilter> getConfigFilters()
-    {
-        return Collections.unmodifiableList(configFilters);
-    }
-
-    @Override
-    public void addConfigFilter(ConfigFilter configFilter)
-    {
-        configFilters.add(configFilter);
-    }
-
-    @Override
-    public String filterConfigValue(String key, String value, boolean forLog)
-    {
-        String filteredValue = value;
-
-        for (ConfigFilter filter : configFilters)
-        {
-            filteredValue = forLog ?
-                    filter.filterValueForLog(key, filteredValue) :
-                    filter.filterValue(key, filteredValue);
-        }
-        return filteredValue;
-    }
-
-    private ConfigSource[] sortDescending(List<ConfigSource> configSources)
-    {
-        Collections.sort(configSources, new Comparator<ConfigSource>()
-        {
-            /**
-             * {@inheritDoc}
-             */
-            @Override
-            public int compare(ConfigSource configSource1, ConfigSource configSource2)
-            {
-                int o1 = configSource1.getOrdinal();
-                int o2 = configSource2.getOrdinal();
-                if (o1 == o2)
-                {
-                    return configSource1.getConfigName().compareTo(configSource2.getConfigName());
-                }
-                return (o1 > o2) ? -1 : 1;
-            }
-        });
-        return configSources.toArray(new ConfigSource[configSources.size()]);
-    }
-
-}
+/*
+ * 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.deltaspike.core.impl.config;
+
+import org.apache.deltaspike.core.api.config.Config;
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+import org.apache.deltaspike.core.spi.config.ConfigFilter;
+import org.apache.deltaspike.core.spi.config.ConfigSource;
+import org.apache.deltaspike.core.spi.config.ConfigSourceProvider;
+import org.apache.deltaspike.core.util.ServiceUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * The internal implementation of the Config interface
+ */
+public class ConfigImpl implements Config
+{
+    private static final Logger LOG = Logger.getLogger(ConfigImpl.class.getName());
+
+    private final ClassLoader classLoader;
+
+    private ConfigSource[] configSources;
+    private List<ConfigFilter> configFilters;
+
+    public ConfigImpl(ClassLoader classLoader)
+    {
+        this.classLoader = classLoader;
+    }
+
+    /**
+     * Performs all the initialisation of the default
+     * ConfigSources, ConfigFilters, etc
+     */
+    void init()
+    {
+        List<ConfigSource> appConfigSources
+            = ServiceUtils.loadServiceImplementations(ConfigSource.class, false, classLoader);
+
+        List<ConfigSourceProvider> configSourceProviderServiceLoader
+            = ServiceUtils.loadServiceImplementations(ConfigSourceProvider.class, false, classLoader);
+
+        for (ConfigSourceProvider configSourceProvider : configSourceProviderServiceLoader)
+        {
+            appConfigSources.addAll(configSourceProvider.getConfigSources());
+        }
+        addConfigSources(appConfigSources);
+
+        if (LOG.isLoggable(Level.FINE))
+        {
+            for (ConfigSource cs : appConfigSources)
+            {
+                LOG.log(Level.FINE, "Adding ordinal {0} ConfigSource {1}",
+                        new Object[]{cs.getOrdinal(), cs.getConfigName()});
+            }
+        }
+
+        List<ConfigFilter> configFilters
+            = ServiceUtils.loadServiceImplementations(ConfigFilter.class, false, classLoader);
+        this.configFilters = new CopyOnWriteArrayList<>(configFilters);
+    }
+
+
+    @Override
+    public ConfigSource[] getConfigSources()
+    {
+        return configSources;
+    }
+
+    @Override
+    public void addConfigSources(List<ConfigSource> configSourcesToAdd)
+    {
+        List<ConfigSource> allConfigSources = new ArrayList<>();
+        if (this.configSources != null)
+        {
+            for (ConfigSource configSource : this.configSources)
+            {
+                allConfigSources.add(configSource);
+            }
+        }
+
+        allConfigSources.addAll(configSourcesToAdd);
+
+        this.configSources = sortDescending(allConfigSources);
+    }
+
+    @Override
+    public List<ConfigFilter> getConfigFilters()
+    {
+        return Collections.unmodifiableList(configFilters);
+    }
+
+    @Override
+    public void addConfigFilter(ConfigFilter configFilter)
+    {
+        configFilters.add(configFilter);
+    }
+
+    @Override
+    public String filterConfigValue(String key, String value, boolean forLog)
+    {
+        String filteredValue = value;
+
+        for (ConfigFilter filter : configFilters)
+        {
+            filteredValue = forLog ?
+                    filter.filterValueForLog(key, filteredValue) :
+                    filter.filterValue(key, filteredValue);
+        }
+        return filteredValue;
+    }
+
+
+    @Override
+    public ConfigResolver.UntypedResolver<String> resolve(String name)
+    {
+        return new TypedResolverImpl(this, name);
+    }
+
+    private ConfigSource[] sortDescending(List<ConfigSource> configSources)
+    {
+        Collections.sort(configSources, new Comparator<ConfigSource>()
+        {
+            /**
+             * {@inheritDoc}
+             */
+            @Override
+            public int compare(ConfigSource configSource1, ConfigSource configSource2)
+            {
+                int o1 = configSource1.getOrdinal();
+                int o2 = configSource2.getOrdinal();
+                if (o1 == o2)
+                {
+                    return configSource1.getConfigName().compareTo(configSource2.getConfigName());
+                }
+                return (o1 > o2) ? -1 : 1;
+            }
+        });
+        return configSources.toArray(new ConfigSource[configSources.size()]);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/5b07e197/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigResolverContext.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigResolverContext.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigResolverContext.java
new file mode 100644
index 0000000..4f3997c
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigResolverContext.java
@@ -0,0 +1,73 @@
+/*
+ * 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.deltaspike.core.impl.config;
+
+class ConfigResolverContext
+{
+    static final ConfigResolverContext NONE = new ConfigResolverContext();
+
+    static final ConfigResolverContext EVAL_VARIABLES = new ConfigResolverContext().setEvaluateVariables(true);
+
+    static final ConfigResolverContext PROJECTSTAGE = new ConfigResolverContext().setProjectStageAware(true);
+
+    static final ConfigResolverContext PROJECTSTAGE_EVAL_VARIABLES = new ConfigResolverContext()
+                                                                            .setProjectStageAware(true)
+                                                                            .setEvaluateVariables(true);
+
+    private boolean projectStageAware;
+    private boolean evaluateVariables;
+    private boolean propertyAware;
+
+    public ConfigResolverContext()
+    {
+    }
+    
+    public ConfigResolverContext setEvaluateVariables(final boolean evaluateVariables)
+    {
+        this.evaluateVariables = evaluateVariables;
+        return this;
+    }   
+    
+    public boolean isEvaluateVariables()
+    {
+        return evaluateVariables;
+    }
+
+    public ConfigResolverContext setProjectStageAware(final boolean projectStageAware)
+    {
+        this.projectStageAware = projectStageAware;
+        return this;
+    }
+    
+    public boolean isProjectStageAware()
+    {
+        return projectStageAware;
+    }
+
+    public ConfigResolverContext setPropertyAware(final boolean propertyAware)
+    {
+        this.propertyAware = propertyAware;
+        return this;
+    }
+    
+    public boolean isPropertyAware()
+    {
+        return propertyAware;
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/5b07e197/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/TypedResolverImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/TypedResolverImpl.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/TypedResolverImpl.java
new file mode 100644
index 0000000..df36054
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/TypedResolverImpl.java
@@ -0,0 +1,565 @@
+/*
+ * 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.deltaspike.core.impl.config;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+import org.apache.deltaspike.core.api.projectstage.ProjectStage;
+import org.apache.deltaspike.core.spi.config.ConfigSource;
+import org.apache.deltaspike.core.util.ClassUtils;
+import org.apache.deltaspike.core.util.ExceptionUtils;
+import org.apache.deltaspike.core.util.ProjectStageProducer;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+
+public class TypedResolverImpl<T> implements ConfigResolver.UntypedResolver<T>
+{
+    private static final Logger LOG = Logger.getLogger(TypedResolverImpl.class.getName());
+
+    private final ConfigImpl config;
+
+    private String keyOriginal;
+
+    private String keyResolved;
+
+    private Type configEntryType = String.class;
+
+    private boolean withDefault = false;
+    private T defaultValue;
+
+    private boolean projectStageAware = true;
+
+    private String propertyParameter;
+
+    private String parameterValue;
+
+    private boolean strictly = false;
+
+    private boolean isList = false;
+
+    private ConfigResolver.Converter<?> converter;
+
+    private boolean evaluateVariables = false;
+    private boolean logChanges = false;
+
+    private long cacheTimeMs = -1;
+    private volatile long reloadAfter = -1;
+    private T lastValue = null;
+
+
+    public TypedResolverImpl(ConfigImpl config, String propertyName)
+    {
+        this.config = config;
+        this.keyOriginal = propertyName;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <N> ConfigResolver.TypedResolver<N> as(Class<N> clazz)
+    {
+        configEntryType = clazz;
+        return (ConfigResolver.TypedResolver<N>) this;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public ConfigResolver.TypedResolver<List<T>> asList()
+    {
+        isList = true;
+        ConfigResolver.TypedResolver<List<T>> listTypedResolver = (ConfigResolver.TypedResolver<List<T>>) this;
+
+        if (defaultValue == null)
+        {
+            // the default for lists is an empty list instead of null
+            return listTypedResolver.withDefault(Collections.<T>emptyList());
+        }
+
+        return listTypedResolver;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <N> ConfigResolver.TypedResolver<N> as(Class<N> clazz, ConfigResolver.Converter<N> converter)
+    {
+        configEntryType = clazz;
+        this.converter = converter;
+
+        return (ConfigResolver.TypedResolver<N>) this;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <N> ConfigResolver.TypedResolver<N> as(Type clazz, ConfigResolver.Converter<N> converter)
+    {
+        configEntryType = clazz;
+        this.converter = converter;
+
+        return (ConfigResolver.TypedResolver<N>) this;
+    }
+
+    @Override
+    public ConfigResolver.TypedResolver<T> withDefault(T value)
+    {
+        defaultValue = value;
+        withDefault = true;
+        return this;
+    }
+
+    @Override
+    public ConfigResolver.TypedResolver<T> withStringDefault(String value)
+    {
+        if (value == null || value.isEmpty())
+        {
+            throw new RuntimeException("Empty String or null supplied as string-default value for property "
+                    + keyOriginal);
+        }
+
+        if (isList)
+        {
+            defaultValue = splitAndConvertListValue(value);
+        }
+        else
+        {
+            defaultValue = convert(value);
+        }
+        withDefault = true;
+        return this;
+    }
+
+    @Override
+    public ConfigResolver.TypedResolver<T> cacheFor(TimeUnit timeUnit, long value)
+    {
+        this.cacheTimeMs = timeUnit.toMillis(value);
+        return this;
+    }
+
+    @Override
+    public ConfigResolver.TypedResolver<T> parameterizedBy(String propertyName)
+    {
+        this.propertyParameter = propertyName;
+
+        if (propertyParameter != null && !propertyParameter.isEmpty())
+        {
+            String parameterValue = ConfigResolver
+                    .resolve(propertyParameter)
+                    .withCurrentProjectStage(projectStageAware)
+                    .getValue();
+
+            if (parameterValue != null && !parameterValue.isEmpty())
+            {
+                this.parameterValue = parameterValue;
+            }
+        }
+
+        return this;
+    }
+
+    @Override
+    public ConfigResolver.TypedResolver<T> withCurrentProjectStage(boolean with)
+    {
+        this.projectStageAware = with;
+        return this;
+    }
+
+    @Override
+    public ConfigResolver.TypedResolver<T> strictly(boolean strictly)
+    {
+        this.strictly = strictly;
+        return this;
+    }
+
+    @Override
+    public ConfigResolver.TypedResolver<T> evaluateVariables(boolean evaluateVariables)
+    {
+        this.evaluateVariables = evaluateVariables;
+        return this;
+    }
+
+    @Override
+    public ConfigResolver.TypedResolver<T> logChanges(boolean logChanges)
+    {
+        this.logChanges = logChanges;
+        return this;
+    }
+
+    @Override
+    public T getValue()
+    {
+        long now = -1;
+        if (cacheTimeMs > 0)
+        {
+            now = System.currentTimeMillis();
+            if (now <= reloadAfter)
+            {
+                return lastValue;
+            }
+        }
+
+        String valueStr = resolveStringValue();
+        T value;
+        if (isList)
+        {
+            value = splitAndConvertListValue(valueStr);
+        }
+        else
+        {
+            value = convert(valueStr);
+        }
+
+        if (withDefault)
+        {
+            ConfigResolverContext configResolverContext = new ConfigResolverContext()
+                    .setEvaluateVariables(evaluateVariables)
+                    .setProjectStageAware(projectStageAware);
+            value = fallbackToDefaultIfEmpty(keyResolved, value, defaultValue, configResolverContext);
+            if (isList && String.class.isInstance(value))
+            {
+                value = splitAndConvertListValue(String.class.cast(value));
+            }
+        }
+
+        if (logChanges && (value != null && !value.equals(lastValue) || (value == null && lastValue != null)))
+        {
+            LOG.log(Level.INFO, "New value {0} for key {1}.",
+                    new Object[]{ConfigResolver.filterConfigValueForLog(keyOriginal, valueStr), keyOriginal});
+        }
+
+        lastValue = value;
+
+        if (cacheTimeMs > 0)
+        {
+            reloadAfter = now + cacheTimeMs;
+        }
+
+        return value;
+    }
+
+    private T splitAndConvertListValue(String valueStr)
+    {
+        if (valueStr == null)
+        {
+            return null;
+        }
+
+        List list = new ArrayList();
+        StringBuilder currentValue = new StringBuilder();
+        int length = valueStr.length();
+        for (int i = 0; i < length; i++)
+        {
+            char c = valueStr.charAt(i);
+            if (c == '\\')
+            {
+                if (i < length - 1)
+                {
+                    char nextC = valueStr.charAt(i + 1);
+                    currentValue.append(nextC);
+                    i++;
+                }
+            }
+            else if (c == ',')
+            {
+                String trimedVal = currentValue.toString().trim();
+                if (trimedVal.length() > 0)
+                {
+                    list.add(convert(trimedVal));
+                }
+
+                currentValue.setLength(0);
+            }
+            else
+            {
+                currentValue.append(c);
+            }
+        }
+
+        String trimedVal = currentValue.toString().trim();
+        if (trimedVal.length() > 0)
+        {
+            list.add(convert(trimedVal));
+        }
+
+        return (T) list;
+    }
+
+    @Override
+    public String getKey()
+    {
+        return keyOriginal;
+    }
+
+    @Override
+    public String getResolvedKey()
+    {
+        return keyResolved;
+    }
+
+    @Override
+    public T getDefaultValue()
+    {
+        return defaultValue;
+    }
+
+    /**
+     * Performs the resolution cascade
+     */
+    private String resolveStringValue()
+    {
+        ProjectStage ps = null;
+        String value = null;
+        keyResolved = keyOriginal;
+        int keySuffices = 0;
+
+        // make the longest key
+        // first, try appending resolved parameter
+        if (propertyParameter != null && !propertyParameter.isEmpty())
+        {
+            if (parameterValue != null && !parameterValue.isEmpty())
+            {
+                keyResolved += "." + parameterValue;
+                keySuffices++;
+            }
+            // if parameter value can't be resolved and strictly
+            else if (strictly)
+            {
+                return null;
+            }
+        }
+
+        // try appending projectstage
+        if (projectStageAware)
+        {
+            ps = getProjectStage();
+            keyResolved += "." + ps;
+            keySuffices++;
+        }
+
+        // make initial resolution of longest key
+        value = getPropertyValue(keyResolved);
+
+        // try fallbacks if not strictly
+        if (value == null && !strictly)
+        {
+
+            // by the length of the longest resolved key already tried
+            // breaks are left out intentionally
+            switch (keySuffices)
+            {
+
+                case 2:
+                    // try base.param
+                    keyResolved = keyOriginal + "." + parameterValue;
+                    value = getPropertyValue(keyResolved);
+
+                    if (value != null)
+                    {
+                        return value;
+                    }
+
+                    // try base.ps
+                    ps = getProjectStage();
+                    keyResolved = keyOriginal + "." + ps;
+                    value = getPropertyValue(keyResolved);
+
+                    if (value != null)
+                    {
+                        return value;
+                    }
+
+                case 1:
+                    // try base
+                    keyResolved = keyOriginal;
+                    value = getPropertyValue(keyResolved);
+                    return value;
+
+                default:
+                    // the longest key was the base, no fallback
+                    return null;
+            }
+        }
+
+        return value;
+    }
+
+    /**
+     * If a converter was provided for this builder, it takes precedence over the built-in converters.
+     */
+    private T convert(String value)
+    {
+        if (value == null)
+        {
+            return null;
+        }
+
+        Object result = null;
+
+        if (this.converter != null)
+        {
+            try
+            {
+                result = converter.convert(value);
+            }
+            catch (Exception e)
+            {
+                throw ExceptionUtils.throwAsRuntimeException(e);
+            }
+        }
+        else if (String.class.equals(configEntryType))
+        {
+            result = value;
+        }
+        else if (Class.class.equals(configEntryType))
+        {
+            result = ClassUtils.tryToLoadClassForName(value);
+        }
+        else if (Boolean.class.equals(configEntryType))
+        {
+            Boolean isTrue = "TRUE".equalsIgnoreCase(value);
+            isTrue |= "1".equalsIgnoreCase(value);
+            isTrue |= "YES".equalsIgnoreCase(value);
+            isTrue |= "Y".equalsIgnoreCase(value);
+            isTrue |= "JA".equalsIgnoreCase(value);
+            isTrue |= "J".equalsIgnoreCase(value);
+            isTrue |= "OUI".equalsIgnoreCase(value);
+
+            result = isTrue;
+        }
+        else if (Integer.class.equals(configEntryType))
+        {
+            result = Integer.parseInt(value);
+        }
+        else if (Long.class.equals(configEntryType))
+        {
+            result = Long.parseLong(value);
+        }
+        else if (Float.class.equals(configEntryType))
+        {
+            result = Float.parseFloat(value);
+        }
+        else if (Double.class.equals(configEntryType))
+        {
+            result = Double.parseDouble(value);
+        }
+
+        return (T) result;
+    }
+
+    private <T> T fallbackToDefaultIfEmpty(String key, T value, T defaultValue,
+                                           ConfigResolverContext configResolverContext)
+    {
+        if (value == null || (value instanceof String && ((String)value).isEmpty()))
+        {
+            if (configResolverContext != null && defaultValue instanceof String
+                    && configResolverContext.isEvaluateVariables())
+            {
+                defaultValue = (T) resolveVariables((String) defaultValue);
+            }
+
+            if (LOG.isLoggable(Level.FINE))
+            {
+                LOG.log(Level.FINE, "no configured value found for key {0}, using default value {1}.",
+                        new Object[]{key, defaultValue});
+            }
+
+            return defaultValue;
+        }
+
+        return value;
+    }
+
+    /**
+     * recursively resolve any ${varName} in the value
+     */
+    private String resolveVariables(String value)
+    {
+        int startVar = 0;
+        while ((startVar = value.indexOf("${", startVar)) >= 0)
+        {
+            int endVar = value.indexOf("}", startVar);
+            if (endVar <= 0)
+            {
+                break;
+            }
+            String varName = value.substring(startVar + 2, endVar);
+            if (varName.isEmpty())
+            {
+                break;
+            }
+
+            String variableValue = new TypedResolverImpl<String>(this.config, varName)
+                    .withCurrentProjectStage(this.projectStageAware)
+                    .evaluateVariables(true)
+                    .getValue();
+
+            if (variableValue != null)
+            {
+                value = value.replace("${" + varName + "}", variableValue);
+            }
+            startVar++;
+        }
+        return value;
+    }
+
+    private ProjectStage getProjectStage()
+    {
+        return ProjectStageProducer.getInstance().getProjectStage();
+    }
+
+    private String getPropertyValue(String key)
+    {
+        String value;
+        for (ConfigSource configSource : config.getConfigSources())
+        {
+            value = configSource.getPropertyValue(key);
+
+            if (value != null)
+            {
+                if (LOG.isLoggable(Level.FINE))
+                {
+                    LOG.log(Level.FINE, "found value {0} for key {1} in ConfigSource {2}.",
+                            new Object[]{config.filterConfigValue(key, value, true),
+                                key, configSource.getConfigName()});
+                }
+
+                if (this.evaluateVariables)
+                {
+                    value = resolveVariables(value);
+                }
+
+                return config.filterConfigValue(key, value, false);
+            }
+
+            if (LOG.isLoggable(Level.FINE))
+            {
+                LOG.log(Level.FINER, "NO value found for key {0} in ConfigSource {1}.",
+                        new Object[]{key, configSource.getConfigName()});
+            }
+        }
+
+        return null;
+    }
+
+
+}


[2/4] deltaspike git commit: DELTASPIKE-1322 move config internas to impl

Posted by st...@apache.org.
DELTASPIKE-1322 move config internas to impl


Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/f56845c4
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/f56845c4
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/f56845c4

Branch: refs/heads/master
Commit: f56845c4ff08be03e61d293e54d7bcae72dccf30
Parents: ca6b722
Author: Mark Struberg <st...@apache.org>
Authored: Mon Mar 5 12:29:35 2018 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Mon Mar 5 12:29:35 2018 +0100

----------------------------------------------------------------------
 .../deltaspike/core/api/config/Config.java      |  68 ++++
 .../core/api/config/ConfigResolver.java         |  56 +++-
 .../deltaspike/core/util/ServiceUtils.java      |  17 +-
 .../activation/EditableTestDeactivator.java     |  47 ---
 ...jectStageDependentClassDeactivationTest.java | 111 -------
 .../test/api/config/ConfigResolverTest.java     | 333 -------------------
 .../test/api/config/TestConfigSource.java       | 141 --------
 .../api/config/TestConfigSourceProvider.java    | 115 -------
 .../test/api/config/TypedResolverTest.java      | 235 -------------
 ...ache.deltaspike.core.spi.config.ConfigSource |  20 --
 ...taspike.core.spi.config.ConfigSourceProvider |  20 --
 .../deltaspike/core/impl/config/ConfigImpl.java | 156 +++++++++
 .../core/impl/config/ConfigProviderImpl.java    |  96 ++++++
 ...ore.api.config.ConfigResolver.ConfigProvider |  20 ++
 .../core/api/config/ConfigResolverTest.java     | 333 +++++++++++++++++++
 .../test/core/api/config/TestConfigSource.java  | 142 ++++++++
 .../api/config/TestConfigSourceProvider.java    | 115 +++++++
 .../test/core/api/config/TypedResolverTest.java | 235 +++++++++++++
 .../activation/EditableTestDeactivator.java     |  47 +++
 ...jectStageDependentClassDeactivationTest.java | 111 +++++++
 ...ache.deltaspike.core.spi.config.ConfigSource |  20 ++
 ...taspike.core.spi.config.ConfigSourceProvider |  20 ++
 22 files changed, 1434 insertions(+), 1024 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/Config.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/Config.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/Config.java
new file mode 100644
index 0000000..2422c7b
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/Config.java
@@ -0,0 +1,68 @@
+/*
+ * 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.deltaspike.core.api.config;
+
+import org.apache.deltaspike.core.spi.config.ConfigFilter;
+import org.apache.deltaspike.core.spi.config.ConfigSource;
+
+import java.util.List;
+
+/**
+ * The Configuration for an application/ClassLoader.
+ */
+public interface Config
+{
+
+    /**
+     * @return all the current ConfigSources for this Config
+     */
+    ConfigSource[] getConfigSources();
+
+    /**
+     * This method can be used for programmatically adding {@link ConfigSource}s.
+     * It is not needed for normal 'usage' by end users, but only for Extension Developers!
+     *
+     * @param configSourcesToAdd the ConfigSources to add
+     */
+    void addConfigSources(List<ConfigSource> configSourcesToAdd);
+
+    /**
+     * @return the {@link ConfigFilter}s for the current application.
+     */
+    List<ConfigFilter> getConfigFilters();
+
+    /**
+     * Add a {@link ConfigFilter} to the ConfigResolver. This will only affect the current WebApp (or more precisely the
+     * current ClassLoader and it's children).
+     *
+     * @param configFilter
+     */
+    void addConfigFilter(ConfigFilter configFilter);
+
+    /**
+     * Filter the configured value.
+     * This can e.g. be used for decryption.
+     * @param key the key of the config property
+     * @param value to be filtered
+     * @param forLog whether the value is intended to be presented to some humans somehow.
+     *               If filtered for logging, then secrets might get starred out '*****'.
+     * @return the filtered value
+     */
+    String filterConfigValue(String key, String value, boolean forLog);
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
index 9082584..4339cca 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
@@ -24,8 +24,10 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.ServiceLoader;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.TimeUnit;
@@ -92,12 +94,24 @@ public final class ConfigResolver
     private static Map<ClassLoader, List<ConfigFilter>> configFilters
         = new ConcurrentHashMap<ClassLoader, List<ConfigFilter>>();
 
+    private static ConfigProvider configProvider;
 
     private ConfigResolver()
     {
         // this is a utility class which doesn't get instantiated.
     }
 
+    public static Config getConfig()
+    {
+        ClassLoader cl = ClassUtils.getClassLoader(null);
+        return getConfig(cl);
+    }
+
+    public static Config getConfig(ClassLoader cl)
+    {
+        return getConfigProvider().getConfig(cl);
+    }
+
     /**
      * This method can be used for programmatically adding {@link ConfigSource}s.
      * It is not needed for normal 'usage' by end users, but only for Extension Developers!
@@ -356,9 +370,14 @@ public final class ConfigResolver
     
     private static String getPropertyValue(String key, ConfigResolverContext configResolverContext)
     {
-        ConfigSource[] appConfigSources = getConfigSources();
+        if (key == null)
+        {
+            return null;
+        }
 
+        ConfigSource[] appConfigSources = getConfigSources();
         String value;
+
         for (ConfigSource configSource : appConfigSources)
         {
             value = configSource.getPropertyValue(key);
@@ -1246,4 +1265,39 @@ public final class ConfigResolver
 
     }
 
+
+    private static ConfigProvider getConfigProvider()
+    {
+        if (configProvider == null)
+        {
+            synchronized (ConfigResolver.class)
+            {
+                if (configProvider == null)
+                {
+                    Iterator<ConfigProvider> configProviders = ServiceLoader.load(ConfigProvider.class).iterator();
+                    if (!configProviders.hasNext())
+                    {
+                        throw new RuntimeException("Could not load ConfigProvider");
+                    }
+                    configProvider = configProviders.next();
+
+                    if (configProviders.hasNext())
+                    {
+                        throw new RuntimeException("Found more than one ConfigProvider");
+                    }
+                }
+            }
+        }
+        return configProvider;
+    }
+
+
+    public interface ConfigProvider
+    {
+        Config getConfig();
+
+        Config getConfig(ClassLoader cl);
+
+        void releaseConfig(ClassLoader cl);
+    }
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ServiceUtils.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ServiceUtils.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ServiceUtils.java
index 92fa6c4..c6b7952 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ServiceUtils.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ServiceUtils.java
@@ -49,9 +49,24 @@ public abstract class ServiceUtils
     public static <T> List<T> loadServiceImplementations(Class<T> serviceType,
                                                          boolean ignoreServicesWithMissingDependencies)
     {
+        return loadServiceImplementations(serviceType, ignoreServicesWithMissingDependencies, null);
+    }
+
+    public static <T> List<T> loadServiceImplementations(Class<T> serviceType,
+                                                         boolean ignoreServicesWithMissingDependencies,
+                                                         ClassLoader classLoader)
+    {
         List<T> result = new ArrayList<T>();
 
-        Iterator<T> servicesIterator = ServiceLoader.load(serviceType).iterator();
+        Iterator<T> servicesIterator;
+        if (classLoader != null)
+        {
+            servicesIterator = ServiceLoader.load(serviceType, classLoader).iterator();
+        }
+        else
+        {
+            servicesIterator = ServiceLoader.load(serviceType).iterator();
+        }
 
         if (!servicesIterator.hasNext())
         {

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/EditableTestDeactivator.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/EditableTestDeactivator.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/EditableTestDeactivator.java
deleted file mode 100644
index cd06855..0000000
--- a/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/EditableTestDeactivator.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 org.apache.deltaspike.core.util.activation;
-
-import org.apache.deltaspike.core.spi.activation.ClassDeactivator;
-import org.apache.deltaspike.core.spi.activation.Deactivatable;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class EditableTestDeactivator implements ClassDeactivator
-{
-    private static Map<Class<? extends Deactivatable>, Boolean> result = new HashMap<Class<? extends Deactivatable>, Boolean>();
-
-    @Override
-    public Boolean isActivated(Class<? extends Deactivatable> targetClass)
-    {
-        return result.get(targetClass);
-    }
-
-    public static void activate(Class<? extends Deactivatable> classToActivate)
-    {
-        result.put(classToActivate, true);
-    }
-
-    public static void deactivate(Class<? extends Deactivatable> classToActivate)
-    {
-        result.put(classToActivate, false);
-    }
-}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/ProjectStageDependentClassDeactivationTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/ProjectStageDependentClassDeactivationTest.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/ProjectStageDependentClassDeactivationTest.java
deleted file mode 100644
index 6ca2a93..0000000
--- a/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/ProjectStageDependentClassDeactivationTest.java
+++ /dev/null
@@ -1,111 +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.deltaspike.core.util.activation;
-
-import org.apache.deltaspike.core.api.projectstage.ProjectStage;
-import org.apache.deltaspike.core.spi.activation.Deactivatable;
-import org.apache.deltaspike.core.util.ClassDeactivationUtils;
-import org.apache.deltaspike.core.util.ProjectStageProducer;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ProjectStageDependentClassDeactivationTest
-{
-    @Test
-    public void deactivationResultInProjectStageUnitTest()
-    {
-        ProjectStageProducer.setProjectStage(ProjectStage.UnitTest);
-
-        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
-        EditableTestDeactivator.activate(classToCheck);
-        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
-
-        EditableTestDeactivator.deactivate(classToCheck);
-        Assert.assertEquals(false, ClassDeactivationUtils.isActivated(classToCheck));
-    }
-
-    @Test
-    public void deactivationResultInProjectStageDevelopment()
-    {
-        ProjectStageProducer.setProjectStage(ProjectStage.Development);
-
-        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
-        EditableTestDeactivator.activate(classToCheck);
-        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
-
-        EditableTestDeactivator.deactivate(classToCheck);
-        Assert.assertEquals(false, ClassDeactivationUtils.isActivated(classToCheck));
-    }
-
-    @Test
-    public void deactivationResultInProjectStageProduction()
-    {
-        ProjectStageProducer.setProjectStage(ProjectStage.Production);
-
-        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
-        EditableTestDeactivator.activate(classToCheck);
-        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
-
-        EditableTestDeactivator.deactivate(classToCheck);
-        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result
-    }
-
-    @Test
-    public void deactivationResultInProjectStageIntegrationTest()
-    {
-        ProjectStageProducer.setProjectStage(ProjectStage.IntegrationTest);
-
-        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
-        EditableTestDeactivator.activate(classToCheck);
-        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
-
-        EditableTestDeactivator.deactivate(classToCheck);
-        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result
-    }
-
-    @Test
-    public void deactivationResultInProjectStageStaging()
-    {
-        ProjectStageProducer.setProjectStage(ProjectStage.Staging);
-
-        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
-        EditableTestDeactivator.activate(classToCheck);
-        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
-
-        EditableTestDeactivator.deactivate(classToCheck);
-        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result
-    }
-
-    @Test
-    public void deactivationResultInProjectStageSystemTest()
-    {
-        ProjectStageProducer.setProjectStage(ProjectStage.SystemTest);
-
-        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
-        EditableTestDeactivator.activate(classToCheck);
-        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
-
-        EditableTestDeactivator.deactivate(classToCheck);
-        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result
-    }
-
-    private static class TestDeactivatable implements Deactivatable
-    {
-    }
-}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/ConfigResolverTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/ConfigResolverTest.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/ConfigResolverTest.java
deleted file mode 100644
index c8b8c99..0000000
--- a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/ConfigResolverTest.java
+++ /dev/null
@@ -1,333 +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.deltaspike.test.api.config;
-
-import org.apache.deltaspike.core.api.config.ConfigResolver;
-import org.apache.deltaspike.core.api.projectstage.ProjectStage;
-import org.apache.deltaspike.core.spi.config.ConfigFilter;
-import org.apache.deltaspike.core.spi.config.ConfigSource;
-import org.apache.deltaspike.core.util.ProjectStageProducer;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.List;
-
-@SuppressWarnings("Duplicates")
-public class ConfigResolverTest
-{
-    private static final String DEFAULT_VALUE = "defaultValue";
-
-    @Before
-    public void init()
-    {
-        ProjectStageProducer.setProjectStage(ProjectStage.UnitTest);
-    }
-
-    @Test
-    public void testOverruledValue()
-    {
-        String result = ConfigResolver.getPropertyValue("test");
-
-        Assert.assertEquals("test2", result);
-    }
-
-    @Test
-    public void testOrderOfAllValues()
-    {
-        List<String> result = ConfigResolver.getAllPropertyValues("test");
-
-        Assert.assertEquals(2, result.size());
-        Assert.assertEquals("test1", result.get(0));
-        Assert.assertEquals("test2", result.get(1));
-    }
-
-    @Test
-    public void testStandaloneConfigSource()
-    {
-        Assert.assertNull(ConfigResolver.getPropertyValue("notexisting"));
-        Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey"));
-    }
-
-    @Test
-    public void testGetProjectStageAwarePropertyValue()
-    {
-        ProjectStageProducer.setProjectStage(ProjectStage.UnitTest);
-        Assert.assertNull(ConfigResolver.getProjectStageAwarePropertyValue("notexisting", null));
-
-        Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey"));
-        Assert.assertEquals("unittestvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey"));
-        Assert.assertEquals("unittestvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey", null));
-
-        Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey2"));
-        Assert.assertEquals("testvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey2"));
-        Assert.assertEquals("testvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey2", null));
-
-        Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey3"));
-        Assert.assertEquals("", ConfigResolver.getProjectStageAwarePropertyValue("testkey3"));
-        Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getProjectStageAwarePropertyValue("testkey3", DEFAULT_VALUE));
-
-        Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getProjectStageAwarePropertyValue("deltaspike.test.projectstagefallback", DEFAULT_VALUE));
-        Assert.assertEquals("", ConfigResolver.getProjectStageAwarePropertyValue("deltaspike.test.projectstagefallback"));
-
-        Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.resolve("deltaspike.test.projectstagefallback").as(String.class).withDefault(DEFAULT_VALUE).withCurrentProjectStage(true).getValue());
-        Assert.assertEquals("", ConfigResolver.resolve("deltaspike.test.projectstagefallback").as(String.class).withCurrentProjectStage(true).getValue());
-    }
-
-    @Test
-    public void testGetPropertyAwarePropertyValue()
-    {
-        ProjectStageProducer.setProjectStage(ProjectStage.UnitTest);
-
-        Assert.assertNull(ConfigResolver.getPropertyAwarePropertyValue("notexisting", null));
-
-        Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey"));
-        Assert.assertEquals("unittestvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey", "dbvendor"));
-        Assert.assertEquals("unittestvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey", "dbvendor", null));
-
-        Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey2"));
-        Assert.assertEquals("testvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey2", "dbvendor"));
-        Assert.assertEquals("testvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey2", "dbvendor", null));
-
-        Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey3"));
-        Assert.assertEquals("", ConfigResolver.getPropertyAwarePropertyValue("testkey3", "dbvendor"));
-        Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getPropertyAwarePropertyValue("testkey3", "dbvendor", DEFAULT_VALUE));
-
-        Assert.assertEquals("TestDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendor"));
-        Assert.assertEquals("PostgreDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendor2"));
-        Assert.assertEquals("UnitTestDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendorX"));
-
-        Assert.assertEquals("TestDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendor", null));
-        Assert.assertEquals("PostgreDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendor2", null));
-        Assert.assertEquals("UnitTestDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendorX", null));
-        Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getPropertyAwarePropertyValue("dataSourceX", "dbvendorX", DEFAULT_VALUE));
-    }
-
-    @Test
-    public void testConfigFilter()
-    {
-        ConfigFilter configFilter = new TestConfigFilter();
-
-        Assert.assertEquals("shouldGetDecrypted: value", configFilter.filterValue("somekey.encrypted", "value"));
-        Assert.assertEquals("**********", configFilter.filterValueForLog("somekey.password", "value"));
-
-        ConfigResolver.addConfigFilter(configFilter);
-
-        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getPropertyValue("testkey4.encrypted"));
-        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getProjectStageAwarePropertyValue("testkey4.encrypted"));
-        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getProjectStageAwarePropertyValue("testkey4.encrypted", null));
-        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getPropertyAwarePropertyValue("testkey4.encrypted", "dbvendor"));
-        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getPropertyAwarePropertyValue("testkey4.encrypted", "dbvendor", null));
-
-        List<String> allPropertyValues = ConfigResolver.getAllPropertyValues("testkey4.encrypted");
-        Assert.assertNotNull(allPropertyValues);
-        Assert.assertEquals(1, allPropertyValues.size());
-        Assert.assertEquals("shouldGetDecrypted: value", allPropertyValues.get(0));
-
-    }
-
-    @Test
-    public void testConfigVariableReplacement()
-    {
-        {
-            String url = ConfigResolver.getPropertyValue("deltaspike.test.someapp.soap.endpoint", "", true);
-            Assert.assertEquals("http://localhost:12345/someservice/myendpoint", url);
-        }
-
-        {
-            String url = ConfigResolver.getPropertyValue("deltaspike.test.someapp.soap.endpoint", true);
-            Assert.assertEquals("http://localhost:12345/someservice/myendpoint", url);
-        }
-    }
-
-    @Test
-    public void testConfigVariableReplacementInDefault()
-    {
-        {
-            String url = ConfigResolver.getPropertyValue("deltaspike.test.notexisting",
-                    "url: ${deltaspike.test.host.url}", true);
-            Assert.assertEquals("url: http://localhost:12345", url);
-        }
-
-        {
-            String url = ConfigResolver.getPropertyValue("deltaspike.test.someapp.soap.endpoint", true);
-            Assert.assertEquals("http://localhost:12345/someservice/myendpoint", url);
-        }
-    }
-
-    @Test
-    public void testConfigVariableNotExisting()
-    {
-        {
-            String url = ConfigResolver.getPropertyValue("deltaspike.test.nonexisting.variable", "", true);
-            Assert.assertEquals("${does.not.exist}/someservice/myendpoint", url);
-        }
-        {
-            String url = ConfigResolver.getPropertyValue("deltaspike.test.nonexisting.variable", true);
-            Assert.assertEquals("${does.not.exist}/someservice/myendpoint", url);
-        }
-    }
-
-    @Test
-    public void testConfigVariableRecursiveDeclaration()
-    {
-        String url = ConfigResolver.getPropertyValue("deltaspike.test.recursive.variable1", "", true);
-        Assert.assertEquals("pre-crazy-post/ohgosh/crazy", url);
-
-        ConfigResolver.TypedResolver<String> tr = ConfigResolver.resolve("deltaspike.test.recursive.variable1")
-            .evaluateVariables(true).logChanges(true);
-        Assert.assertEquals("pre-crazy-post/ohgosh/crazy", tr.getValue());
-    }
-
-    @Test
-    public void testTypedResolver_NonExistingValue()
-    {
-        final String key = "non.existing.key";
-
-        ConfigResolver.TypedResolver<String> resolver = ConfigResolver.resolve(key)
-            .logChanges(true);
-
-        Assert.assertNull(resolver.getValue());
-
-        setTestConfigSourceValue(key, "somevalue");
-        Assert.assertEquals("somevalue", resolver.getValue());
-
-        setTestConfigSourceValue(key, null);
-        Assert.assertNull(resolver.getValue());
-    }
-    
-    @Test
-    public void testProjectStageAwarePropertyValueReference_1() {
-        final String expectedFooUrl =
-                "http://bar-dev/services";
-
-        final String actualFooUrl =
-                ConfigResolver.getProjectStageAwarePropertyValue(
-                "foo.url");
-
-        Assert.assertEquals(expectedFooUrl, actualFooUrl);
-    }
-
-    @Test
-    public void testProjectStageAwarePropertyValueReference_2() {
-        final String expected =
-                "projectStageAware-exampleEntry-1-is-tomato-UnitTest";
-
-        final String projectStageAwareExampleEntry1 =
-                ConfigResolver.getProjectStageAwarePropertyValue(
-                "deltaspike.test.exampleEntry-2", 
-                "");
-
-        Assert.assertEquals(expected, projectStageAwareExampleEntry1);
-    }
-
-    @Test
-    public void testConfiguredListValues_WithWhitespace() {
-        List<String> emails = ConfigResolver.resolve("test.list.value.emails").asList().getValue();
-        Assert.assertNotNull(emails);
-        Assert.assertEquals(3, emails.size());
-        Assert.assertTrue(emails.contains("test1@apache.org"));
-        Assert.assertTrue(emails.contains("test2@apache.org"));
-        Assert.assertTrue(emails.contains("test3@apache.org"));
-    }
-
-    @Test
-    public void testConfiguredListValues_WithEscaping() {
-        List<String> escapedValues = ConfigResolver.resolve("test.list.value.escaped.list").asList().getValue();
-        Assert.assertNotNull(escapedValues);
-        Assert.assertEquals(3, escapedValues.size());
-        Assert.assertTrue(escapedValues.contains("val,ue1"));
-        Assert.assertTrue(escapedValues.contains("value2"));
-        Assert.assertTrue(escapedValues.contains("val\\ue3"));
-    }
-
-    @Test
-    public void testConfiguredListValues_OtherType() {
-        List<Integer> intValues = ConfigResolver.resolve("test.list.intvalues").as(Integer.class).asList().getValue();
-        Assert.assertNotNull(intValues);
-        Assert.assertEquals(4, intValues.size());
-        Assert.assertTrue(intValues.contains(3));
-        Assert.assertTrue(intValues.contains(7));
-        Assert.assertTrue(intValues.contains(11));
-        Assert.assertTrue(intValues.contains(17));
-    }
-
-    @Test
-    public void testConfiguredListValues_NotExisting() {
-        List<Integer> intValues = ConfigResolver.resolve("test.list.not_existing").as(Integer.class).asList().getValue();
-        Assert.assertNotNull(intValues);
-        Assert.assertEquals(0, intValues.size());
-    }
-
-    @Test
-    public void testConfiguredListValues_WithDefault() {
-        List<Integer> intValues = ConfigResolver.resolve("test.list.not_existing").as(Integer.class).asList().withDefault(Arrays.asList(99, 88, 77)).getValue();
-        Assert.assertNotNull(intValues);
-        Assert.assertEquals(3, intValues.size());
-        Assert.assertTrue(intValues.contains(99));
-        Assert.assertTrue(intValues.contains(88));
-        Assert.assertTrue(intValues.contains(77));
-    }
-
-    private void setTestConfigSourceValue(String key, String value)
-    {
-        ConfigSource[] configSources = ConfigResolver.getConfigSources();
-        for (ConfigSource configSource : configSources)
-        {
-            if (configSource instanceof TestConfigSource)
-            {
-                if (value == null)
-                {
-                    configSource.getProperties().remove(key);
-                }
-                else
-                {
-                    configSource.getProperties().put(key, value);
-                }
-
-                break;
-            }
-        }
-    }
-
-    public static class TestConfigFilter implements ConfigFilter
-    {
-        @Override
-        public String filterValue(String key, String value)
-        {
-            if (key.contains("encrypted"))
-            {
-                return "shouldGetDecrypted: " + value;
-            }
-            return value;
-        }
-
-        @Override
-        public String filterValueForLog(String key, String value)
-        {
-            if (key.contains("password"))
-            {
-                return "**********";
-            }
-            return value;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
deleted file mode 100644
index f18f7d5..0000000
--- a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
+++ /dev/null
@@ -1,141 +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.deltaspike.test.api.config;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.deltaspike.core.spi.config.ConfigSource;
-
-/**
- * Test ConfigSource
- *
- * It statically returns 'testvalue' for the key 'testkey'
- */
-public class TestConfigSource implements ConfigSource
-{
-
-    private int ordinal = 700;
-
-    private Map<String, String> props = new HashMap<String, String>();
-
-
-    public TestConfigSource()
-    {
-        // a ProjectStage overloaded value
-        props.put("testkey", "testvalue");
-        props.put("testkey.UnitTest", "unittestvalue");
-
-        // a value without any overloading
-        props.put("testkey2", "testvalue");
-
-        // a value which got ProjectStage overloaded to an empty value
-        props.put("testkey3", "testvalue");
-        props.put("testkey3.UnitTest", "");
-
-        // now for the PropertyAware tests
-        props.put("dbvendor.UnitTest", "mysql");
-        props.put("dbvendor", "postgresql");
-
-        props.put("dataSource.mysql.Production", "java:/comp/env/MyDs");
-        props.put("dataSource.mysql.UnitTest", "TestDataSource");
-        props.put("dataSource.postgresql", "PostgreDataSource");
-        props.put("dataSource.UnitTest", "UnitTestDataSource");
-        props.put("dataSource", "DefaultDataSource");
-
-        // another one
-        props.put("dbvendor2.Production", "mysql");
-        props.put("dbvendor2", "postgresql");
-
-        props.put("dbvendor3", "h2");
-
-        props.put("testkey4.encrypted", "value");
-        props.put("testkey4.password", "mysecretvalue");
-
-        props.put("deltaspike.test.string-value", "configured");
-        props.put("deltaspike.test.integer-value", "5");
-        props.put("deltaspike.test.long-value", "8589934592");
-        props.put("deltaspike.test.float-value", "-1.1");
-        props.put("deltaspike.test.double-value", "4e40");
-        props.put("deltaspike.test.boolean-value", Boolean.FALSE.toString());
-        props.put("deltaspike.test.class-value", "org.apache.deltaspike.test.api.config.TestConfigSource");
-        props.put("deltaspike.test.date-value", "2014-12-24");
-        props.put("deltaspike.test.invalid-value", "wrong");
-        props.put("org.apache.deltaspike.core.spi.activation.ClassDeactivator","org.apache.deltaspike.core.util.activation.EditableTestDeactivator");
-
-        // test for variable replacement
-        props.put("deltaspike.test.host.url", "http://localhost:12345");
-        props.put("deltaspike.test.someapp.soap.endpoint", "${deltaspike.test.host.url}/someservice/myendpoint");
-
-        props.put("deltaspike.test.nonexisting.variable", "${does.not.exist}/someservice/myendpoint");
-
-        props.put("deltaspike.test.recursive.variable1", "${deltaspike.test.recursive.variable2}/ohgosh/${deltaspike.test.recursive.variable3}");
-        props.put("deltaspike.test.recursive.variable2", "pre-${deltaspike.test.recursive.variable3}-post");
-        props.put("deltaspike.test.recursive.variable3", "crazy");
-
-        props.put("deltaspike.test.projectstagefallback.UnitTest", "");
-        props.put("deltaspike.test.projectstagefallback", "Value without ProjectStage");
-        
-        // ProjectStage aware property value with resolved reference
-        props.put("foo.url", "${bar.url}/services");
-        props.put("bar.url", "undefined");
-        props.put("bar.url.UnitTest", "http://bar-dev");
-        props.put("bar.url.Production", "http://bar-prod");
-
-        props.put("deltaspike.test.exampleEntry-1", "tomato");
-        props.put("deltaspike.test.exampleEntry-1.UnitTest", "tomato-UnitTest");
-        props.put("deltaspike.test.exampleEntry-2", "default-exampleEntry-1-is-${deltaspike.test.exampleEntry-1}");
-        props.put("deltaspike.test.exampleEntry-2.UnitTest", "projectStageAware-exampleEntry-1-is-${deltaspike.test.exampleEntry-1}");
-
-        // values for testing the list handling
-        props.put("test.list.value.emails", "test1@apache.org, test2@apache.org, \n  test3@apache.org");
-        props.put("test.list.value.escaped.list","val\\,ue1,value2, val\\\\ue3");
-        props.put("test.list.intvalues","3,7, 11 ,\t 17\n");
-    }
-
-    @Override
-    public String getConfigName()
-    {
-        return "testConfig";
-    }
-
-    @Override
-    public int getOrdinal()
-    {
-        return ordinal;
-    }
-
-    @Override
-    public String getPropertyValue(String key)
-    {
-        return props.get(key);
-    }
-
-    @Override
-    public Map<String, String> getProperties()
-    {
-        return props;
-    }
-
-	@Override
-	public boolean isScannable() {
-		return true;
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSourceProvider.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSourceProvider.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSourceProvider.java
deleted file mode 100644
index 098b37b..0000000
--- a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSourceProvider.java
+++ /dev/null
@@ -1,115 +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.deltaspike.test.api.config;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.deltaspike.core.spi.config.ConfigSource;
-import org.apache.deltaspike.core.spi.config.ConfigSourceProvider;
-
-/**
- * ConfigSourceProvider for basic unit-test
- */
-public class TestConfigSourceProvider implements ConfigSourceProvider
-{
-    @Override
-    public List<ConfigSource> getConfigSources()
-    {
-        return Arrays.asList(new TestConfigSource1(), new TestConfigSource2());
-    }
-
-    private static class TestConfigSource1 implements ConfigSource
-    {
-        @Override
-        public int getOrdinal()
-        {
-            return 1;
-        }
-
-        @Override
-        public String getPropertyValue(String key)
-        {
-            if ("test".equals(key))
-            {
-                return "test1";
-            }
-            return null;
-        }
-
-        @Override
-        public Map<String, String> getProperties()
-        {
-            Map<String, String> map = new HashMap<String, String>();
-            map.put("test", "test1");
-            return map;
-        }
-
-        @Override
-        public String getConfigName()
-        {
-            return TestConfigSourceProvider.class.getName();
-        }
-
-		@Override
-		public boolean isScannable() {
-			return true;
-		}
-    }
-
-    private static class TestConfigSource2 implements ConfigSource
-    {
-        @Override
-        public int getOrdinal()
-        {
-            return 2;
-        }
-
-        @Override
-        public String getPropertyValue(String key)
-        {
-            if ("test".equals(key))
-            {
-                return "test2";
-            }
-            return null;
-        }
-
-        @Override
-        public Map<String, String> getProperties()
-        {
-            Map<String, String> map = new HashMap<String, String>();
-            map.put("test", "test2");
-            return map;
-        }
-
-        @Override
-        public String getConfigName()
-        {
-            return TestConfigSourceProvider.class.getName();
-        }
-
-		@Override
-		public boolean isScannable() {
-			return false;
-		}
-    }
-}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TypedResolverTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TypedResolverTest.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TypedResolverTest.java
deleted file mode 100644
index 3a8c144..0000000
--- a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TypedResolverTest.java
+++ /dev/null
@@ -1,235 +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.deltaspike.test.api.config;
-
-import org.apache.deltaspike.core.api.config.ConfigResolver;
-import org.apache.deltaspike.core.api.projectstage.ProjectStage;
-import org.apache.deltaspike.core.util.ProjectStageProducer;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.concurrent.TimeUnit;
-
-public class TypedResolverTest
-{
-    @Before
-    public void init()
-    {
-        ProjectStageProducer.setProjectStage(ProjectStage.UnitTest);
-    }
-
-    @Test
-    public void testValidTypes()
-    {
-        Assert.assertEquals("configured", ConfigResolver.resolve("deltaspike.test.string-value").getValue());
-
-        Assert.assertEquals(Boolean.FALSE, ConfigResolver.resolve("deltaspike.test.boolean-value").as(Boolean.class)
-                .getValue());
-
-        Assert.assertEquals(TestConfigSource.class, ConfigResolver.resolve("deltaspike.test.class-value").as(Class
-                .class).getValue());
-
-        Assert.assertEquals(5l, (int) ConfigResolver.resolve("deltaspike.test.integer-value").as(Integer.class)
-                .getValue());
-
-        Assert.assertEquals(8589934592l, (long) ConfigResolver.resolve("deltaspike.test.long-value").as(Long.class)
-                .getValue());
-
-        Assert.assertEquals(-1.1f, (float) ConfigResolver.resolve("deltaspike.test.float-value").as(Float.class)
-                .getValue(), 0);
-
-        Assert.assertEquals(4e40d, (double) ConfigResolver.resolve("deltaspike.test.double-value").as(Double.class)
-                .getValue(), 0);
-    }
-
-    @Test
-    public void testConverter()
-    {
-        Assert.assertEquals(new GregorianCalendar(2014, 12, 24).getTime(),
-                ConfigResolver.resolve("deltaspike.test.date-value")
-                        .as(Date.class, new TestDateConverter()).getValue());
-
-        // test fallback to default
-        Assert.assertEquals(new GregorianCalendar(2015, 01, 01).getTime(),
-                ConfigResolver.resolve("deltaspike.test.INVALID-date-value")
-                        .as(Date.class, new TestDateConverter())
-                        .withDefault(new GregorianCalendar(2015, 01, 01).getTime())
-                        .getValue());
-    }
-
-    @Test
-    public void testProjectStageAware()
-    {
-        Assert.assertEquals("unittestvalue",
-                ConfigResolver.resolve("testkey")
-                        .withCurrentProjectStage(true)
-                        .getValue());
-
-        Assert.assertEquals("testvalue",
-                ConfigResolver.resolve("testkey")
-                        .withCurrentProjectStage(false)
-                        .getValue());
-
-        // property without PS, with PS-aware
-        Assert.assertEquals("testvalue",
-                ConfigResolver.resolve("testkey2")
-                        .withCurrentProjectStage(true)
-                        .getValue());
-    }
-
-    @Test
-    public void testParameterized()
-    {
-        // param OK, ps OK
-        Assert.assertEquals("TestDataSource",
-                ConfigResolver.resolve("dataSource")
-                        .withCurrentProjectStage(true)
-                        .parameterizedBy("dbvendor")
-                        .getValue());
-
-        // param OK, NO ps
-        Assert.assertEquals("PostgreDataSource",
-                ConfigResolver.resolve("dataSource")
-                        .withCurrentProjectStage(false)
-                        .parameterizedBy("dbvendor")
-                        .getValue());
-
-        // param doesn't resolve, ps OK
-        Assert.assertEquals("UnitTestDataSource",
-                ConfigResolver.resolve("dataSource")
-                        .withCurrentProjectStage(true)
-                        .parameterizedBy("INVALIDPARAMETER")
-                        .getValue());
-
-        // param OK, ps OK, NO base.param.ps, NO base.param, fall back to base.ps
-        Assert.assertEquals("UnitTestDataSource",
-                ConfigResolver.resolve("dataSource")
-                        .withCurrentProjectStage(true)
-                        .parameterizedBy("dbvendor3")
-                        .getValue());
-
-        // param OK, NO ps, base.param undefined, fall back to base
-        Assert.assertEquals("DefaultDataSource",
-                ConfigResolver.resolve("dataSource")
-                        .withCurrentProjectStage(false)
-                        .parameterizedBy("dbvendor3")
-                        .getValue());
-    }
-
-    @Test
-    public void testDefault()
-    {
-        Assert.assertEquals(10l,
-                (long) ConfigResolver.resolve("INVALIDKEY")
-                .as(Long.class)
-                .withDefault(10l).getValue());
-
-        // string default
-        Assert.assertEquals(10l,
-                (long) ConfigResolver.resolve("INVALIDKEY")
-                        .as(Long.class)
-                        .withStringDefault("10").getValue());
-    }
-
-    @Test
-    public void testStrict()
-    {
-        Assert.assertEquals("TestDataSource",
-                ConfigResolver.resolve("dataSource")
-                        .withCurrentProjectStage(true)
-                        .parameterizedBy("dbvendor")
-                        .strictly(true)
-                        .getValue());
-
-        // no base.param, no value for base.param.ps
-        Assert.assertEquals(null,
-                ConfigResolver.resolve("dataSource")
-                        .withCurrentProjectStage(true)
-                        .parameterizedBy("dbvendor3")
-                        .strictly(true)
-                        .getValue());
-
-        // valid base.param, but no base.param.ps
-        Assert.assertEquals(null,
-                ConfigResolver.resolve("dataSource")
-                        .withCurrentProjectStage(true)
-                        .parameterizedBy("dbvendor2")
-                        .strictly(true)
-                        .getValue());
-    }
-
-    @Test
-    public void testGets()
-    {
-        ConfigResolver.TypedResolver<String> resolver = ConfigResolver.resolve("dataSource")
-                .withCurrentProjectStage(true)
-                .parameterizedBy("dbvendor")
-                .withDefault("TESTDEFAULT");
-
-        Assert.assertEquals("TestDataSource", resolver.getValue());
-        Assert.assertEquals("dataSource", resolver.getKey());
-        Assert.assertEquals("TESTDEFAULT", resolver.getDefaultValue());
-        Assert.assertEquals("dataSource.mysql.UnitTest", resolver.getResolvedKey());
-
-
-        ConfigResolver.TypedResolver<String> resolver2 = ConfigResolver.resolve("testkey2")
-                .withCurrentProjectStage(true)
-                .parameterizedBy("INVALIDPARAMETER");
-
-
-        Assert.assertEquals("testvalue", resolver2.getValue());
-        Assert.assertEquals("testkey2", resolver2.getResolvedKey());
-    }
-
-    @Test
-    public void testWithCacheTime() throws Exception
-    {
-        ConfigResolver.TypedResolver<String> resolver = ConfigResolver.resolve("dataSource")
-            .withCurrentProjectStage(true)
-            .parameterizedBy("dbvendor")
-            .cacheFor(TimeUnit.MILLISECONDS, 5)
-            .withDefault("TESTDEFAULT");
-
-        Assert.assertEquals("TestDataSource", resolver.getValue());
-        Assert.assertEquals("TestDataSource", resolver.getValue());
-        Assert.assertEquals("dataSource", resolver.getKey());
-        Assert.assertEquals("TESTDEFAULT", resolver.getDefaultValue());
-        Assert.assertEquals("dataSource.mysql.UnitTest", resolver.getResolvedKey());
-
-        // because the clock steps in certain OS is only 16ms
-        Thread.sleep(35L);
-        Assert.assertEquals("TestDataSource", resolver.getValue());
-    }
-
-    public static class TestDateConverter implements ConfigResolver.Converter<Date> {
-
-        @Override
-        public Date convert(String value)
-        {
-            String[] parts = value.split("-");
-            return new GregorianCalendar(Integer.valueOf(parts[0]), Integer.valueOf(parts[1]),
-                    Integer.valueOf(parts[2])).getTime();
-        }
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/api/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource b/deltaspike/core/api/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource
deleted file mode 100644
index 84d5875..0000000
--- a/deltaspike/core/api/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource
+++ /dev/null
@@ -1,20 +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.
-#####################################################################################
-
-org.apache.deltaspike.test.api.config.TestConfigSource

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/api/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider b/deltaspike/core/api/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider
deleted file mode 100644
index 14674cd..0000000
--- a/deltaspike/core/api/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider
+++ /dev/null
@@ -1,20 +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.
-#
-
-org.apache.deltaspike.test.api.config.TestConfigSourceProvider

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java
new file mode 100644
index 0000000..54c1ca9
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java
@@ -0,0 +1,156 @@
+/*
+ * 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.deltaspike.core.impl.config;
+
+import org.apache.deltaspike.core.api.config.Config;
+import org.apache.deltaspike.core.spi.config.ConfigFilter;
+import org.apache.deltaspike.core.spi.config.ConfigSource;
+import org.apache.deltaspike.core.spi.config.ConfigSourceProvider;
+import org.apache.deltaspike.core.util.ServiceUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * The internal implementation of the Config interface
+ */
+public class ConfigImpl implements Config
+{
+    private static final Logger LOG = Logger.getLogger(ConfigImpl.class.getName());
+
+    private final ClassLoader classLoader;
+
+    private ConfigSource[] configSources;
+    private List<ConfigFilter> configFilters;
+
+    public ConfigImpl(ClassLoader classLoader)
+    {
+        this.classLoader = classLoader;
+    }
+
+    /**
+     * Performs all the initialisation of the default
+     * ConfigSources, ConfigFilters, etc
+     */
+    void init()
+    {
+        List<ConfigSource> appConfigSources
+            = ServiceUtils.loadServiceImplementations(ConfigSource.class, false, classLoader);
+
+        List<ConfigSourceProvider> configSourceProviderServiceLoader
+            = ServiceUtils.loadServiceImplementations(ConfigSourceProvider.class, false, classLoader);
+
+        for (ConfigSourceProvider configSourceProvider : configSourceProviderServiceLoader)
+        {
+            appConfigSources.addAll(configSourceProvider.getConfigSources());
+        }
+        addConfigSources(appConfigSources);
+
+        if (LOG.isLoggable(Level.FINE))
+        {
+            for (ConfigSource cs : appConfigSources)
+            {
+                LOG.log(Level.FINE, "Adding ordinal {0} ConfigSource {1}",
+                        new Object[]{cs.getOrdinal(), cs.getConfigName()});
+            }
+        }
+
+        List<ConfigFilter> configFilters
+            = ServiceUtils.loadServiceImplementations(ConfigFilter.class, false, classLoader);
+        this.configFilters = new CopyOnWriteArrayList<>(configFilters);
+    }
+
+
+    @Override
+    public ConfigSource[] getConfigSources()
+    {
+        return configSources;
+    }
+
+    @Override
+    public void addConfigSources(List<ConfigSource> configSourcesToAdd)
+    {
+        List<ConfigSource> allConfigSources = new ArrayList<>();
+        if (this.configSources != null)
+        {
+            for (ConfigSource configSource : this.configSources)
+            {
+                allConfigSources.add(configSource);
+            }
+        }
+
+        allConfigSources.addAll(configSourcesToAdd);
+
+        this.configSources = sortDescending(allConfigSources);
+    }
+
+    @Override
+    public List<ConfigFilter> getConfigFilters()
+    {
+        return Collections.unmodifiableList(configFilters);
+    }
+
+    @Override
+    public void addConfigFilter(ConfigFilter configFilter)
+    {
+        configFilters.add(configFilter);
+    }
+
+    @Override
+    public String filterConfigValue(String key, String value, boolean forLog)
+    {
+        String filteredValue = value;
+
+        for (ConfigFilter filter : configFilters)
+        {
+            filteredValue = forLog ?
+                    filter.filterValueForLog(key, filteredValue) :
+                    filter.filterValue(key, filteredValue);
+        }
+        return filteredValue;
+    }
+
+    private ConfigSource[] sortDescending(List<ConfigSource> configSources)
+    {
+        Collections.sort(configSources, new Comparator<ConfigSource>()
+        {
+            /**
+             * {@inheritDoc}
+             */
+            @Override
+            public int compare(ConfigSource configSource1, ConfigSource configSource2)
+            {
+                int o1 = configSource1.getOrdinal();
+                int o2 = configSource2.getOrdinal();
+                if (o1 == o2)
+                {
+                    return configSource1.getConfigName().compareTo(configSource2.getConfigName());
+                }
+                return (o1 > o2) ? -1 : 1;
+            }
+        });
+        return configSources.toArray(new ConfigSource[configSources.size()]);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigProviderImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigProviderImpl.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigProviderImpl.java
new file mode 100644
index 0000000..e788f8d
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigProviderImpl.java
@@ -0,0 +1,96 @@
+/*
+ * 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.deltaspike.core.impl.config;
+
+import org.apache.deltaspike.core.api.config.Config;
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+import org.apache.deltaspike.core.util.ClassUtils;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ */
+public class ConfigProviderImpl implements ConfigResolver.ConfigProvider
+{
+    /**
+     * The content of this map will get lazily initiated and will hold the
+     * Configs for each WebApp/EAR, etc (thus the ClassLoader).
+     */
+    private static Map<ClassLoader, ConfigImpl> configs = new ConcurrentHashMap<>();
+
+    @Override
+    public Config getConfig()
+    {
+        ClassLoader cl = ClassUtils.getClassLoader(null);
+        return getConfig(cl);
+    }
+
+    @Override
+    public Config getConfig(ClassLoader cl)
+    {
+        ConfigImpl config = configs.get(cl);
+        if (config == null)
+        {
+            config = new ConfigImpl(cl);
+            config.init();
+            ConfigImpl oldConfig = configs.put(cl, config);
+            if (oldConfig != null)
+            {
+                config = oldConfig;
+            }
+        }
+        return config;
+    }
+
+    @Override
+    public void releaseConfig(ClassLoader cl)
+    {
+        configs.remove(cl);
+
+        // And remove all the children as well.
+        // This will e.g happen in EAR scenarios
+        Iterator<Map.Entry<ClassLoader, ConfigImpl>> it = configs.entrySet().iterator();
+        while (it.hasNext())
+        {
+            Map.Entry<ClassLoader, ConfigImpl> cfgEntry = it.next();
+            if (isChildClassLoader(cl, cfgEntry.getKey()))
+            {
+                it.remove();
+            }
+        }
+    }
+
+    private boolean isChildClassLoader(ClassLoader configClassLoader, ClassLoader suspect)
+    {
+        ClassLoader suspectParentCl = suspect.getParent();
+        if (suspectParentCl == null)
+        {
+            return false;
+        }
+
+        if (suspectParentCl == configClassLoader)
+        {
+            return true;
+        }
+
+        return isChildClassLoader(configClassLoader, suspectParentCl);
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.api.config.ConfigResolver.ConfigProvider
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.api.config.ConfigResolver.ConfigProvider b/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.api.config.ConfigResolver.ConfigProvider
new file mode 100644
index 0000000..117643b
--- /dev/null
+++ b/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.api.config.ConfigResolver.ConfigProvider
@@ -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 of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+org.apache.deltaspike.core.impl.config.ConfigProviderImpl
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/ConfigResolverTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/ConfigResolverTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/ConfigResolverTest.java
new file mode 100644
index 0000000..44eea3f
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/ConfigResolverTest.java
@@ -0,0 +1,333 @@
+/*
+ * 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.deltaspike.test.core.api.config;
+
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+import org.apache.deltaspike.core.api.projectstage.ProjectStage;
+import org.apache.deltaspike.core.spi.config.ConfigFilter;
+import org.apache.deltaspike.core.spi.config.ConfigSource;
+import org.apache.deltaspike.core.util.ProjectStageProducer;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+@SuppressWarnings("Duplicates")
+public class ConfigResolverTest
+{
+    private static final String DEFAULT_VALUE = "defaultValue";
+
+    @Before
+    public void init()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.UnitTest);
+    }
+
+    @Test
+    public void testOverruledValue()
+    {
+        String result = ConfigResolver.getPropertyValue("test");
+
+        Assert.assertEquals("test2", result);
+    }
+
+    @Test
+    public void testOrderOfAllValues()
+    {
+        List<String> result = ConfigResolver.getAllPropertyValues("test");
+
+        Assert.assertEquals(2, result.size());
+        Assert.assertEquals("test1", result.get(0));
+        Assert.assertEquals("test2", result.get(1));
+    }
+
+    @Test
+    public void testStandaloneConfigSource()
+    {
+        Assert.assertNull(ConfigResolver.getPropertyValue("notexisting"));
+        Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey"));
+    }
+
+    @Test
+    public void testGetProjectStageAwarePropertyValue()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.UnitTest);
+        Assert.assertNull(ConfigResolver.getProjectStageAwarePropertyValue("notexisting", null));
+
+        Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey"));
+        Assert.assertEquals("unittestvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey"));
+        Assert.assertEquals("unittestvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey", null));
+
+        Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey2"));
+        Assert.assertEquals("testvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey2"));
+        Assert.assertEquals("testvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey2", null));
+
+        Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey3"));
+        Assert.assertEquals("", ConfigResolver.getProjectStageAwarePropertyValue("testkey3"));
+        Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getProjectStageAwarePropertyValue("testkey3", DEFAULT_VALUE));
+
+        Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getProjectStageAwarePropertyValue("deltaspike.test.projectstagefallback", DEFAULT_VALUE));
+        Assert.assertEquals("", ConfigResolver.getProjectStageAwarePropertyValue("deltaspike.test.projectstagefallback"));
+
+        Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.resolve("deltaspike.test.projectstagefallback").as(String.class).withDefault(DEFAULT_VALUE).withCurrentProjectStage(true).getValue());
+        Assert.assertEquals("", ConfigResolver.resolve("deltaspike.test.projectstagefallback").as(String.class).withCurrentProjectStage(true).getValue());
+    }
+
+    @Test
+    public void testGetPropertyAwarePropertyValue()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.UnitTest);
+
+        Assert.assertNull(ConfigResolver.getPropertyAwarePropertyValue("notexisting", null));
+
+        Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey"));
+        Assert.assertEquals("unittestvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey", "dbvendor"));
+        Assert.assertEquals("unittestvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey", "dbvendor", null));
+
+        Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey2"));
+        Assert.assertEquals("testvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey2", "dbvendor"));
+        Assert.assertEquals("testvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey2", "dbvendor", null));
+
+        Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey3"));
+        Assert.assertEquals("", ConfigResolver.getPropertyAwarePropertyValue("testkey3", "dbvendor"));
+        Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getPropertyAwarePropertyValue("testkey3", "dbvendor", DEFAULT_VALUE));
+
+        Assert.assertEquals("TestDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendor"));
+        Assert.assertEquals("PostgreDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendor2"));
+        Assert.assertEquals("UnitTestDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendorX"));
+
+        Assert.assertEquals("TestDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendor", null));
+        Assert.assertEquals("PostgreDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendor2", null));
+        Assert.assertEquals("UnitTestDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendorX", null));
+        Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getPropertyAwarePropertyValue("dataSourceX", "dbvendorX", DEFAULT_VALUE));
+    }
+
+    @Test
+    public void testConfigFilter()
+    {
+        ConfigFilter configFilter = new TestConfigFilter();
+
+        Assert.assertEquals("shouldGetDecrypted: value", configFilter.filterValue("somekey.encrypted", "value"));
+        Assert.assertEquals("**********", configFilter.filterValueForLog("somekey.password", "value"));
+
+        ConfigResolver.addConfigFilter(configFilter);
+
+        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getPropertyValue("testkey4.encrypted"));
+        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getProjectStageAwarePropertyValue("testkey4.encrypted"));
+        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getProjectStageAwarePropertyValue("testkey4.encrypted", null));
+        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getPropertyAwarePropertyValue("testkey4.encrypted", "dbvendor"));
+        Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getPropertyAwarePropertyValue("testkey4.encrypted", "dbvendor", null));
+
+        List<String> allPropertyValues = ConfigResolver.getAllPropertyValues("testkey4.encrypted");
+        Assert.assertNotNull(allPropertyValues);
+        Assert.assertEquals(1, allPropertyValues.size());
+        Assert.assertEquals("shouldGetDecrypted: value", allPropertyValues.get(0));
+
+    }
+
+    @Test
+    public void testConfigVariableReplacement()
+    {
+        {
+            String url = ConfigResolver.getPropertyValue("deltaspike.test.someapp.soap.endpoint", "", true);
+            Assert.assertEquals("http://localhost:12345/someservice/myendpoint", url);
+        }
+
+        {
+            String url = ConfigResolver.getPropertyValue("deltaspike.test.someapp.soap.endpoint", true);
+            Assert.assertEquals("http://localhost:12345/someservice/myendpoint", url);
+        }
+    }
+
+    @Test
+    public void testConfigVariableReplacementInDefault()
+    {
+        {
+            String url = ConfigResolver.getPropertyValue("deltaspike.test.notexisting",
+                    "url: ${deltaspike.test.host.url}", true);
+            Assert.assertEquals("url: http://localhost:12345", url);
+        }
+
+        {
+            String url = ConfigResolver.getPropertyValue("deltaspike.test.someapp.soap.endpoint", true);
+            Assert.assertEquals("http://localhost:12345/someservice/myendpoint", url);
+        }
+    }
+
+    @Test
+    public void testConfigVariableNotExisting()
+    {
+        {
+            String url = ConfigResolver.getPropertyValue("deltaspike.test.nonexisting.variable", "", true);
+            Assert.assertEquals("${does.not.exist}/someservice/myendpoint", url);
+        }
+        {
+            String url = ConfigResolver.getPropertyValue("deltaspike.test.nonexisting.variable", true);
+            Assert.assertEquals("${does.not.exist}/someservice/myendpoint", url);
+        }
+    }
+
+    @Test
+    public void testConfigVariableRecursiveDeclaration()
+    {
+        String url = ConfigResolver.getPropertyValue("deltaspike.test.recursive.variable1", "", true);
+        Assert.assertEquals("pre-crazy-post/ohgosh/crazy", url);
+
+        ConfigResolver.TypedResolver<String> tr = ConfigResolver.resolve("deltaspike.test.recursive.variable1")
+            .evaluateVariables(true).logChanges(true);
+        Assert.assertEquals("pre-crazy-post/ohgosh/crazy", tr.getValue());
+    }
+
+    @Test
+    public void testTypedResolver_NonExistingValue()
+    {
+        final String key = "non.existing.key";
+
+        ConfigResolver.TypedResolver<String> resolver = ConfigResolver.resolve(key)
+            .logChanges(true);
+
+        Assert.assertNull(resolver.getValue());
+
+        setTestConfigSourceValue(key, "somevalue");
+        Assert.assertEquals("somevalue", resolver.getValue());
+
+        setTestConfigSourceValue(key, null);
+        Assert.assertNull(resolver.getValue());
+    }
+    
+    @Test
+    public void testProjectStageAwarePropertyValueReference_1() {
+        final String expectedFooUrl =
+                "http://bar-dev/services";
+
+        final String actualFooUrl =
+                ConfigResolver.getProjectStageAwarePropertyValue(
+                "foo.url");
+
+        Assert.assertEquals(expectedFooUrl, actualFooUrl);
+    }
+
+    @Test
+    public void testProjectStageAwarePropertyValueReference_2() {
+        final String expected =
+                "projectStageAware-exampleEntry-1-is-tomato-UnitTest";
+
+        final String projectStageAwareExampleEntry1 =
+                ConfigResolver.getProjectStageAwarePropertyValue(
+                "deltaspike.test.exampleEntry-2", 
+                "");
+
+        Assert.assertEquals(expected, projectStageAwareExampleEntry1);
+    }
+
+    @Test
+    public void testConfiguredListValues_WithWhitespace() {
+        List<String> emails = ConfigResolver.resolve("test.list.value.emails").asList().getValue();
+        Assert.assertNotNull(emails);
+        Assert.assertEquals(3, emails.size());
+        Assert.assertTrue(emails.contains("test1@apache.org"));
+        Assert.assertTrue(emails.contains("test2@apache.org"));
+        Assert.assertTrue(emails.contains("test3@apache.org"));
+    }
+
+    @Test
+    public void testConfiguredListValues_WithEscaping() {
+        List<String> escapedValues = ConfigResolver.resolve("test.list.value.escaped.list").asList().getValue();
+        Assert.assertNotNull(escapedValues);
+        Assert.assertEquals(3, escapedValues.size());
+        Assert.assertTrue(escapedValues.contains("val,ue1"));
+        Assert.assertTrue(escapedValues.contains("value2"));
+        Assert.assertTrue(escapedValues.contains("val\\ue3"));
+    }
+
+    @Test
+    public void testConfiguredListValues_OtherType() {
+        List<Integer> intValues = ConfigResolver.resolve("test.list.intvalues").as(Integer.class).asList().getValue();
+        Assert.assertNotNull(intValues);
+        Assert.assertEquals(4, intValues.size());
+        Assert.assertTrue(intValues.contains(3));
+        Assert.assertTrue(intValues.contains(7));
+        Assert.assertTrue(intValues.contains(11));
+        Assert.assertTrue(intValues.contains(17));
+    }
+
+    @Test
+    public void testConfiguredListValues_NotExisting() {
+        List<Integer> intValues = ConfigResolver.resolve("test.list.not_existing").as(Integer.class).asList().getValue();
+        Assert.assertNotNull(intValues);
+        Assert.assertEquals(0, intValues.size());
+    }
+
+    @Test
+    public void testConfiguredListValues_WithDefault() {
+        List<Integer> intValues = ConfigResolver.resolve("test.list.not_existing").as(Integer.class).asList().withDefault(Arrays.asList(99, 88, 77)).getValue();
+        Assert.assertNotNull(intValues);
+        Assert.assertEquals(3, intValues.size());
+        Assert.assertTrue(intValues.contains(99));
+        Assert.assertTrue(intValues.contains(88));
+        Assert.assertTrue(intValues.contains(77));
+    }
+
+    private void setTestConfigSourceValue(String key, String value)
+    {
+        ConfigSource[] configSources = ConfigResolver.getConfigSources();
+        for (ConfigSource configSource : configSources)
+        {
+            if (configSource instanceof TestConfigSource)
+            {
+                if (value == null)
+                {
+                    configSource.getProperties().remove(key);
+                }
+                else
+                {
+                    configSource.getProperties().put(key, value);
+                }
+
+                break;
+            }
+        }
+    }
+
+    public static class TestConfigFilter implements ConfigFilter
+    {
+        @Override
+        public String filterValue(String key, String value)
+        {
+            if (key.contains("encrypted"))
+            {
+                return "shouldGetDecrypted: " + value;
+            }
+            return value;
+        }
+
+        @Override
+        public String filterValueForLog(String key, String value)
+        {
+            if (key.contains("password"))
+            {
+                return "**********";
+            }
+            return value;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/f56845c4/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TestConfigSource.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TestConfigSource.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TestConfigSource.java
new file mode 100644
index 0000000..44a8808
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TestConfigSource.java
@@ -0,0 +1,142 @@
+/*
+ * 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.deltaspike.test.core.api.config;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.deltaspike.core.spi.config.ConfigSource;
+import org.apache.deltaspike.test.util.activation.EditableTestDeactivator;
+
+/**
+ * Test ConfigSource
+ *
+ * It statically returns 'testvalue' for the key 'testkey'
+ */
+public class TestConfigSource implements ConfigSource
+{
+
+    private int ordinal = 700;
+
+    private Map<String, String> props = new HashMap<String, String>();
+
+
+    public TestConfigSource()
+    {
+        // a ProjectStage overloaded value
+        props.put("testkey", "testvalue");
+        props.put("testkey.UnitTest", "unittestvalue");
+
+        // a value without any overloading
+        props.put("testkey2", "testvalue");
+
+        // a value which got ProjectStage overloaded to an empty value
+        props.put("testkey3", "testvalue");
+        props.put("testkey3.UnitTest", "");
+
+        // now for the PropertyAware tests
+        props.put("dbvendor.UnitTest", "mysql");
+        props.put("dbvendor", "postgresql");
+
+        props.put("dataSource.mysql.Production", "java:/comp/env/MyDs");
+        props.put("dataSource.mysql.UnitTest", "TestDataSource");
+        props.put("dataSource.postgresql", "PostgreDataSource");
+        props.put("dataSource.UnitTest", "UnitTestDataSource");
+        props.put("dataSource", "DefaultDataSource");
+
+        // another one
+        props.put("dbvendor2.Production", "mysql");
+        props.put("dbvendor2", "postgresql");
+
+        props.put("dbvendor3", "h2");
+
+        props.put("testkey4.encrypted", "value");
+        props.put("testkey4.password", "mysecretvalue");
+
+        props.put("deltaspike.test.string-value", "configured");
+        props.put("deltaspike.test.integer-value", "5");
+        props.put("deltaspike.test.long-value", "8589934592");
+        props.put("deltaspike.test.float-value", "-1.1");
+        props.put("deltaspike.test.double-value", "4e40");
+        props.put("deltaspike.test.boolean-value", Boolean.FALSE.toString());
+        props.put("deltaspike.test.class-value", TestConfigSource.class.getName());
+        props.put("deltaspike.test.date-value", "2014-12-24");
+        props.put("deltaspike.test.invalid-value", "wrong");
+        props.put("org.apache.deltaspike.core.spi.activation.ClassDeactivator",EditableTestDeactivator.class.getName());
+
+        // test for variable replacement
+        props.put("deltaspike.test.host.url", "http://localhost:12345");
+        props.put("deltaspike.test.someapp.soap.endpoint", "${deltaspike.test.host.url}/someservice/myendpoint");
+
+        props.put("deltaspike.test.nonexisting.variable", "${does.not.exist}/someservice/myendpoint");
+
+        props.put("deltaspike.test.recursive.variable1", "${deltaspike.test.recursive.variable2}/ohgosh/${deltaspike.test.recursive.variable3}");
+        props.put("deltaspike.test.recursive.variable2", "pre-${deltaspike.test.recursive.variable3}-post");
+        props.put("deltaspike.test.recursive.variable3", "crazy");
+
+        props.put("deltaspike.test.projectstagefallback.UnitTest", "");
+        props.put("deltaspike.test.projectstagefallback", "Value without ProjectStage");
+        
+        // ProjectStage aware property value with resolved reference
+        props.put("foo.url", "${bar.url}/services");
+        props.put("bar.url", "undefined");
+        props.put("bar.url.UnitTest", "http://bar-dev");
+        props.put("bar.url.Production", "http://bar-prod");
+
+        props.put("deltaspike.test.exampleEntry-1", "tomato");
+        props.put("deltaspike.test.exampleEntry-1.UnitTest", "tomato-UnitTest");
+        props.put("deltaspike.test.exampleEntry-2", "default-exampleEntry-1-is-${deltaspike.test.exampleEntry-1}");
+        props.put("deltaspike.test.exampleEntry-2.UnitTest", "projectStageAware-exampleEntry-1-is-${deltaspike.test.exampleEntry-1}");
+
+        // values for testing the list handling
+        props.put("test.list.value.emails", "test1@apache.org, test2@apache.org, \n  test3@apache.org");
+        props.put("test.list.value.escaped.list","val\\,ue1,value2, val\\\\ue3");
+        props.put("test.list.intvalues","3,7, 11 ,\t 17\n");
+    }
+
+    @Override
+    public String getConfigName()
+    {
+        return "testConfig";
+    }
+
+    @Override
+    public int getOrdinal()
+    {
+        return ordinal;
+    }
+
+    @Override
+    public String getPropertyValue(String key)
+    {
+        return props.get(key);
+    }
+
+    @Override
+    public Map<String, String> getProperties()
+    {
+        return props;
+    }
+
+	@Override
+	public boolean isScannable() {
+		return true;
+	}
+
+}


[3/4] deltaspike git commit: DELTASPIKE-1322 switch ConfigSources over

Posted by st...@apache.org.
DELTASPIKE-1322 switch ConfigSources over

anything which contains state is now getting moved over
from ConfigResolver to Config


Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/bd638aae
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/bd638aae
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/bd638aae

Branch: refs/heads/master
Commit: bd638aae11d6723b17c7b533e3e21c2106dd581a
Parents: f56845c
Author: Mark Struberg <st...@apache.org>
Authored: Mon Mar 5 12:45:27 2018 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Mon Mar 5 12:45:27 2018 +0100

----------------------------------------------------------------------
 .../core/api/config/ConfigResolver.java         | 142 ++-----------------
 ...ore.api.config.ConfigResolver$ConfigProvider |  20 +++
 ...ore.api.config.ConfigResolver.ConfigProvider |  20 ---
 deltaspike/modules/partial-bean/impl/pom.xml    |   5 +
 deltaspike/modules/proxy/impl-asm/pom.xml       |   5 +
 5 files changed, 42 insertions(+), 150 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bd638aae/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
index 4339cca..fa280ef 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
@@ -28,8 +28,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.ServiceLoader;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.TimeUnit;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -39,11 +37,9 @@ import javax.enterprise.inject.Typed;
 import org.apache.deltaspike.core.api.projectstage.ProjectStage;
 import org.apache.deltaspike.core.spi.config.ConfigFilter;
 import org.apache.deltaspike.core.spi.config.ConfigSource;
-import org.apache.deltaspike.core.spi.config.ConfigSourceProvider;
 import org.apache.deltaspike.core.util.ClassUtils;
 import org.apache.deltaspike.core.util.ExceptionUtils;
 import org.apache.deltaspike.core.util.ProjectStageProducer;
-import org.apache.deltaspike.core.util.ServiceUtils;
 
 /**
  * The main entry point to the DeltaSpike configuration mechanism.
@@ -54,7 +50,7 @@ import org.apache.deltaspike.core.util.ServiceUtils;
  *
  * <p>
  * You can provide your own lookup paths by implementing and registering additional {@link PropertyFileConfig} or
- * {@link ConfigSource} or {@link ConfigSourceProvider} implementations.</p>
+ * {@link ConfigSource} or {@link org.apache.deltaspike.core.spi.config.ConfigSourceProvider} implementations.</p>
  *
  * <p>
  * The resolved configuration is also accessible by simple injection using the {@link ConfigProperty} qualifier.</p>
@@ -79,21 +75,6 @@ public final class ConfigResolver
 
     private static final Logger LOG = Logger.getLogger(ConfigResolver.class.getName());
 
-    /**
-     * The content of this map will get lazily initiated and will hold the
-     * sorted List of ConfigSources for each WebApp/EAR, etc (thus the
-     * ClassLoader).
-     */
-    private static Map<ClassLoader, ConfigSource[]> configSources
-        = new ConcurrentHashMap<ClassLoader, ConfigSource[]>();
-
-    /**
-     * The content of this map will hold the List of ConfigFilters
-     * for each WebApp/EAR, etc (thus the ClassLoader).
-     */
-    private static Map<ClassLoader, List<ConfigFilter>> configFilters
-        = new ConcurrentHashMap<ClassLoader, List<ConfigFilter>>();
-
     private static ConfigProvider configProvider;
 
     private ConfigResolver()
@@ -120,19 +101,7 @@ public final class ConfigResolver
      */
     public static synchronized void addConfigSources(List<ConfigSource> configSourcesToAdd)
     {
-        // we first pickup all pre-configured ConfigSources...
-        getConfigSources();
-
-        // and now we can easily add our own
-        ClassLoader currentClassLoader = ClassUtils.getClassLoader(null);
-        ConfigSource[] configuredConfigSources = configSources.get(currentClassLoader);
-
-        List<ConfigSource> allConfigSources = new ArrayList<ConfigSource>();
-        allConfigSources.addAll(Arrays.asList(configuredConfigSources));
-        allConfigSources.addAll(configSourcesToAdd);
-
-        // finally put all the configSources back into the map
-        configSources.put(currentClassLoader, sortDescending(allConfigSources));
+        getConfigProvider().getConfig().addConfigSources(configSourcesToAdd);
     }
 
     /**
@@ -141,9 +110,11 @@ public final class ConfigResolver
      */
     public static synchronized void freeConfigSources()
     {
-        ClassLoader classLoader = ClassUtils.getClassLoader(null);
-        configSources.remove(classLoader);
-        configFilters.remove(classLoader);
+        if (configProvider != null)
+        {
+            ClassLoader cl = ClassUtils.getClassLoader(null);
+            configProvider.releaseConfig(cl);
+        }
     }
 
     /**
@@ -154,8 +125,7 @@ public final class ConfigResolver
      */
     public static void addConfigFilter(ConfigFilter configFilter)
     {
-        List<ConfigFilter> currentConfigFilters = getInternalConfigFilters();
-        currentConfigFilters.add(configFilter);
+        getConfigProvider().getConfig().addConfigFilter(configFilter);
     }
 
     /**
@@ -163,24 +133,9 @@ public final class ConfigResolver
      */
     public static List<ConfigFilter> getConfigFilters()
     {
-        return Collections.unmodifiableList(getInternalConfigFilters());
+        return getConfigProvider().getConfig().getConfigFilters();
     }
 
-    /**
-     * @return the {@link ConfigFilter}s for the current application.
-     */
-    private static List<ConfigFilter> getInternalConfigFilters()
-    {
-        ClassLoader cl = ClassUtils.getClassLoader(null);
-        List<ConfigFilter> currentConfigFilters = configFilters.get(cl);
-        if (currentConfigFilters == null)
-        {
-            currentConfigFilters = new CopyOnWriteArrayList<ConfigFilter>();
-            configFilters.put(cl, currentConfigFilters);
-        }
-
-        return currentConfigFilters;
-    }
 
     /**
      * {@link #getPropertyValue(java.lang.String)} which returns the provided default value if no configured value can
@@ -500,64 +455,7 @@ public final class ConfigResolver
 
     public static synchronized ConfigSource[] getConfigSources()
     {
-        ClassLoader currentClassLoader = ClassUtils.getClassLoader(null);
-
-        ConfigSource[] appConfigSources = configSources.get(currentClassLoader);
-
-        if (appConfigSources == null)
-        {
-            appConfigSources = sortDescending(resolveConfigSources());
-
-            if (LOG.isLoggable(Level.FINE))
-            {
-                for (ConfigSource cs : appConfigSources)
-                {
-                    LOG.log(Level.FINE, "Adding ordinal {0} ConfigSource {1}",
-                            new Object[]{cs.getOrdinal(), cs.getConfigName()});
-                }
-            }
-
-            configSources.put(currentClassLoader, appConfigSources);
-        }
-
-        return appConfigSources;
-    }
-
-    private static List<ConfigSource> resolveConfigSources()
-    {
-        List<ConfigSource> appConfigSources = ServiceUtils.loadServiceImplementations(ConfigSource.class);
-
-        List<ConfigSourceProvider> configSourceProviderServiceLoader =
-            ServiceUtils.loadServiceImplementations(ConfigSourceProvider.class);
-
-        for (ConfigSourceProvider configSourceProvider : configSourceProviderServiceLoader)
-        {
-            appConfigSources.addAll(configSourceProvider.getConfigSources());
-        }
-
-        List<? extends ConfigFilter> configFilters = ServiceUtils.loadServiceImplementations(ConfigFilter.class);
-        for (ConfigFilter configFilter : configFilters)
-        {
-            addConfigFilter(configFilter);
-        }
-
-        return appConfigSources;
-    }
-
-    private static ConfigSource[] sortDescending(List<ConfigSource> configSources)
-    {
-        Collections.sort(configSources, new Comparator<ConfigSource>()
-        {
-            /**
-             * {@inheritDoc}
-             */
-            @Override
-            public int compare(ConfigSource configSource1, ConfigSource configSource2)
-            {
-                return (configSource1.getOrdinal() > configSource2.getOrdinal()) ? -1 : 1;
-            }
-        });
-        return configSources.toArray(new ConfigSource[configSources.size()]);
+        return getConfigProvider().getConfig().getConfigSources();
     }
 
     private static List<ConfigSource> sortAscending(List<ConfigSource> configSources)
@@ -607,15 +505,7 @@ public final class ConfigResolver
      */
     public static String filterConfigValue(String key, String value)
     {
-        List<ConfigFilter> currentConfigFilters = getInternalConfigFilters();
-
-        String filteredValue = value;
-
-        for (ConfigFilter filter : currentConfigFilters)
-        {
-            filteredValue = filter.filterValue(key, filteredValue);
-        }
-        return filteredValue;
+        return getConfigProvider().getConfig().filterConfigValue(key, value, false);
     }
 
     /**
@@ -625,15 +515,7 @@ public final class ConfigResolver
      */
     public static String filterConfigValueForLog(String key, String value)
     {
-        List<ConfigFilter> currentConfigFilters = getInternalConfigFilters();
-
-        String logValue = value;
-
-        for (ConfigFilter filter : currentConfigFilters)
-        {
-            logValue = filter.filterValueForLog(key, logValue);
-        }
-        return logValue;
+        return getConfigProvider().getConfig().filterConfigValue(key, value, true);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bd638aae/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.api.config.ConfigResolver$ConfigProvider
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.api.config.ConfigResolver$ConfigProvider b/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.api.config.ConfigResolver$ConfigProvider
new file mode 100644
index 0000000..117643b
--- /dev/null
+++ b/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.api.config.ConfigResolver$ConfigProvider
@@ -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 of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+org.apache.deltaspike.core.impl.config.ConfigProviderImpl
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bd638aae/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.api.config.ConfigResolver.ConfigProvider
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.api.config.ConfigResolver.ConfigProvider b/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.api.config.ConfigResolver.ConfigProvider
deleted file mode 100644
index 117643b..0000000
--- a/deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.api.config.ConfigResolver.ConfigProvider
+++ /dev/null
@@ -1,20 +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.
-#
-
-org.apache.deltaspike.core.impl.config.ConfigProviderImpl
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bd638aae/deltaspike/modules/partial-bean/impl/pom.xml
----------------------------------------------------------------------
diff --git a/deltaspike/modules/partial-bean/impl/pom.xml b/deltaspike/modules/partial-bean/impl/pom.xml
index 94238b7..a8d6a3c 100644
--- a/deltaspike/modules/partial-bean/impl/pom.xml
+++ b/deltaspike/modules/partial-bean/impl/pom.xml
@@ -54,6 +54,11 @@
             <groupId>org.apache.deltaspike.core</groupId>
             <artifactId>deltaspike-core-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.deltaspike.core</groupId>
+            <artifactId>deltaspike-core-impl</artifactId>
+            <scope>runtime</scope>
+        </dependency>
 
         <dependency>
             <groupId>org.apache.deltaspike.modules</groupId>

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/bd638aae/deltaspike/modules/proxy/impl-asm/pom.xml
----------------------------------------------------------------------
diff --git a/deltaspike/modules/proxy/impl-asm/pom.xml b/deltaspike/modules/proxy/impl-asm/pom.xml
index d196d5b..ad472b3 100644
--- a/deltaspike/modules/proxy/impl-asm/pom.xml
+++ b/deltaspike/modules/proxy/impl-asm/pom.xml
@@ -90,6 +90,11 @@
             <groupId>org.apache.deltaspike.core</groupId>
             <artifactId>deltaspike-core-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.deltaspike.core</groupId>
+            <artifactId>deltaspike-core-impl</artifactId>
+            <scope>runtime</scope>
+        </dependency>
 
         <dependency>
             <groupId>org.apache.deltaspike.modules</groupId>