tamaya-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anat...@apache.org
Subject [05/12] incubator-tamaya git commit: TAMAYA-318 Moved spi-support as API base implementation package to remove code duplicates.
Date Tue, 14 Nov 2017 09:25:46 GMT
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/test/java/org/apache/tamaya/core/propertysource/CLIPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/propertysource/CLIPropertySourceTest.java b/code/core/src/test/java/org/apache/tamaya/core/propertysource/CLIPropertySourceTest.java
deleted file mode 100644
index bd6468b..0000000
--- a/code/core/src/test/java/org/apache/tamaya/core/propertysource/CLIPropertySourceTest.java
+++ /dev/null
@@ -1,58 +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.tamaya.core.propertysource;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Tests for PropertySource for reading main arguments as configuration.
- */
-public class CLIPropertySourceTest {
-
-    @Test
-    public void setCLIProps() throws Exception {
-        System.clearProperty("main.args");
-        CLIPropertySource ps = new CLIPropertySource();
-        assertTrue(ps.getProperties().isEmpty());
-        CLIPropertySource.initMainArgs("-a", "b");
-        assertFalse(ps.getProperties().isEmpty());
-        assertEquals(ps.getProperties().get("a").getValue(), "b");
-        CLIPropertySource.initMainArgs("--c");
-        assertFalse(ps.getProperties().isEmpty());
-        assertEquals(ps.getProperties().get("c").getValue(), "c");
-        CLIPropertySource.initMainArgs("sss");
-        assertFalse(ps.getProperties().isEmpty());
-        assertEquals("sss", ps.getProperties().get("sss").getValue());
-        CLIPropertySource.initMainArgs("-a", "b", "--c", "sss", "--val=vvv");
-        assertFalse(ps.getProperties().isEmpty());
-        assertEquals("b", ps.getProperties().get("a").getValue());
-        assertEquals("c", ps.getProperties().get("c").getValue());
-        assertEquals("sss", ps.getProperties().get("sss").getValue());
-    // getProperties() throws Exception {
-        System.setProperty("main.args", "-a b\t--c sss  ");
-        ps = new CLIPropertySource();
-        assertFalse(ps.getProperties().isEmpty());
-        System.clearProperty("main.args");
-        assertEquals("b", ps.getProperties().get("a").getValue());
-        assertEquals("c", ps.getProperties().get("c").getValue());
-        assertEquals("sss", ps.getProperties().get("sss").getValue());
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/test/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySourceTest.java b/code/core/src/test/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySourceTest.java
deleted file mode 100644
index 477ffb2..0000000
--- a/code/core/src/test/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySourceTest.java
+++ /dev/null
@@ -1,180 +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.tamaya.core.propertysource;
-
-import org.apache.tamaya.spi.PropertyValue;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static java.lang.Boolean.TRUE;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-/**
- * Tests for {@link org.apache.tamaya.core.propertysource.EnvironmentPropertySource}.
- */
-public class EnvironmentPropertySourceTest {
-    private EnvironmentPropertySource envPropertySource;
-
-    @Before
-    public void setOUT() {
-        envPropertySource = new EnvironmentPropertySource();
-    }
-
-    @Test
-    public void testGetOrdinal() throws Exception {
-        assertEquals(EnvironmentPropertySource.DEFAULT_ORDINAL, envPropertySource.getOrdinal());
-    }
-
-    @Test
-    public void testGetName() throws Exception {
-        assertEquals("environment-properties", envPropertySource.getName());
-    }
-
-    @Test
-    public void testGet() throws Exception {
-        for (Map.Entry<String, String> envEntry : System.getenv().entrySet()) {
-            assertEquals(envPropertySource.get(envEntry.getKey()).getValue(), envEntry.getValue());
-        }
-    }
-
-    @Test
-    public void testGetProperties() throws Exception {
-        Map<String, PropertyValue> props = envPropertySource.getProperties();
-        for(Map.Entry<String,PropertyValue> en: props.entrySet()){
-            if(!en.getKey().startsWith("_")){
-                assertEquals(System.getenv(en.getKey()), en.getValue().getValue());
-            }
-        }
-    }
-
-    @Test
-    public void testIsScannable() throws Exception {
-        assertTrue(envPropertySource.isScannable());
-    }
-
-    @Test
-    public void ifPrefixHasBeenConfiguredLookedUpEnvVarNameIsPrefixAndKeyName() {
-        EnvironmentPropertySource.SystemPropertiesProvider provider =
-            mock(EnvironmentPropertySource.SystemPropertiesProvider.class);
-
-        when(provider.getEnvPropsPrefix()).thenReturn("zzz");
-        when(provider.getenv("zzz.VARIABLE")).thenReturn("value");
-
-        envPropertySource.setPropertiesProvider(provider);
-
-        assertThat(envPropertySource.get("VARIABLE").getValue()).isEqualTo("value");
-    }
-
-    @Test
-    public void ifPrefixHasNotBeenConfiguredLookedUpEnvVarNameIsKeyName() {
-        EnvironmentPropertySource.SystemPropertiesProvider provider =
-            mock(EnvironmentPropertySource.SystemPropertiesProvider.class);
-
-        when(provider.getEnvPropsPrefix()).thenReturn(null);
-        when(provider.getenv("VARIABLE")).thenReturn("value");
-
-        envPropertySource.setPropertiesProvider(provider);
-
-        assertThat(envPropertySource.get("VARIABLE").getValue()).isEqualTo("value");
-    }
-
-    @Test
-    public void ifPrefixHasBeenSetAllEnvVarsWithPrefixWillBeReturnedByGetProperties() {
-        EnvironmentPropertySource.SystemPropertiesProvider provider =
-            mock(EnvironmentPropertySource.SystemPropertiesProvider.class);
-
-        when(provider.getEnvPropsPrefix()).thenReturn("zzz");
-        HashMap<String, String> configuredValues = new HashMap<String, String>();
-        configuredValues.put("zzz.A", "aaa");
-        configuredValues.put("zzz.B", "bbb");
-        configuredValues.put("C", "ccc");
-        configuredValues.put("D", "ddd");
-
-        when(provider.getenv()).thenReturn(configuredValues);
-
-        envPropertySource.setPropertiesProvider(provider);
-
-        assertThat(envPropertySource.getProperties()).hasSize(2);
-
-        Map<String, PropertyValue> properties = envPropertySource.getProperties();
-
-        assertThat(properties.keySet()).containsOnly("A", "B");
-        assertThat(properties.get("A").getValue()).isEqualTo("aaa");
-        assertThat(properties.get("B").getValue()).isEqualTo("bbb");
-    }
-
-    @Test
-    public void canBeDisableBySystemPropertyTamayaDefaultsDisable() {
-        EnvironmentPropertySource.SystemPropertiesProvider provider =
-            mock(EnvironmentPropertySource.SystemPropertiesProvider.class);
-
-        when(provider.getDefaultsDisable()).thenReturn(TRUE.toString());
-        when(provider.getenv("VARIABLE")).thenReturn("value");
-
-        envPropertySource.setPropertiesProvider(provider);
-
-        assertThat(envPropertySource.get("VARIABLE")).isNull();
-    }
-
-    @Test
-    public void canBeDisableBySystemPropertyTamayaEnvpropsDisable() {
-        EnvironmentPropertySource.SystemPropertiesProvider provider =
-            mock(EnvironmentPropertySource.SystemPropertiesProvider.class);
-
-        when(provider.getEnvPropsDisable()).thenReturn(TRUE.toString());
-        when(provider.getenv("VARIABLE")).thenReturn("value");
-
-        envPropertySource.setPropertiesProvider(provider);
-
-        assertThat(envPropertySource.get("VARIABLE")).isNull();
-    }
-
-    @Test
-    public void isDisabledIfEvenIsDefaultsDisableIsFalse() throws Exception {
-        EnvironmentPropertySource.SystemPropertiesProvider provider =
-            mock(EnvironmentPropertySource.SystemPropertiesProvider.class);
-
-        when(provider.getDefaultsDisable()).thenReturn("false");
-        when(provider.getEnvPropsDisable()).thenReturn("true");
-
-        envPropertySource.setPropertiesProvider(provider);
-
-        assertThat(envPropertySource.isDisabled()).isTrue();
-    }
-
-    @Test
-    public void isDisabledIfEvenIsEnvPropsDisableIsFalse() throws Exception {
-        EnvironmentPropertySource.SystemPropertiesProvider provider =
-            mock(EnvironmentPropertySource.SystemPropertiesProvider.class);
-
-        when(provider.getDefaultsDisable()).thenReturn("true");
-        when(provider.getEnvPropsDisable()).thenReturn("false");
-
-        envPropertySource.setPropertiesProvider(provider);
-
-        assertThat(envPropertySource.isDisabled()).isTrue();
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/test/java/org/apache/tamaya/core/propertysource/PropertiesFilePropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/propertysource/PropertiesFilePropertySourceTest.java b/code/core/src/test/java/org/apache/tamaya/core/propertysource/PropertiesFilePropertySourceTest.java
deleted file mode 100644
index d11b48e..0000000
--- a/code/core/src/test/java/org/apache/tamaya/core/propertysource/PropertiesFilePropertySourceTest.java
+++ /dev/null
@@ -1,59 +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.tamaya.core.propertysource;
-
-import org.apache.tamaya.spi.PropertySource;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class PropertiesFilePropertySourceTest {
-
-    private final SimplePropertySource testfilePropertySource = new SimplePropertySource(Thread.currentThread()
-            .getContextClassLoader().getResource("testfile.properties"));
-    private final SimplePropertySource overrideOrdinalPropertySource = new SimplePropertySource(
-            Thread.currentThread().getContextClassLoader().getResource("overrideOrdinal.properties"));
-
-
-    @Test
-    public void testGetOrdinal() {
-        Assert.assertEquals(0, testfilePropertySource.getOrdinal());
-        Assert.assertEquals(Integer.parseInt(overrideOrdinalPropertySource.get(PropertySource.TAMAYA_ORDINAL)
-                .getValue()),
-                overrideOrdinalPropertySource.getOrdinal());
-    }
-
-
-    @Test
-    public void testGet() {
-        Assert.assertEquals("val3", testfilePropertySource.get("key3").getValue());
-        Assert.assertEquals("myval5", overrideOrdinalPropertySource.get("mykey5").getValue());
-        Assert.assertNull(testfilePropertySource.get("nonpresentkey"));
-    }
-
-
-    @Test
-    public void testGetProperties() throws Exception {
-        Assert.assertEquals(5, testfilePropertySource.getProperties().size()); // double the size for .source values.
-        Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key1"));
-        Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key2"));
-        Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key3"));
-        Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key4"));
-        Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key5"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/test/java/org/apache/tamaya/core/propertysource/SimplePropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/propertysource/SimplePropertySourceTest.java b/code/core/src/test/java/org/apache/tamaya/core/propertysource/SimplePropertySourceTest.java
deleted file mode 100644
index 2edc466..0000000
--- a/code/core/src/test/java/org/apache/tamaya/core/propertysource/SimplePropertySourceTest.java
+++ /dev/null
@@ -1,89 +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.tamaya.core.propertysource;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.spi.PropertyValue;
-import org.junit.Test;
-
-import java.net.URL;
-
-import static org.hamcrest.CoreMatchers.allOf;
-import static org.hamcrest.CoreMatchers.endsWith;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.CoreMatchers.startsWith;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.aMapWithSize;
-import static org.hamcrest.Matchers.hasEntry;
-
-public class SimplePropertySourceTest {
-    @Test
-    public void successfulCreationWithPropertiesFromXMLPropertiesFile() {
-        URL resource = getClass().getResource("/valid-properties.xml");
-
-        SimplePropertySource source = new SimplePropertySource(resource);
-
-        assertThat(source, notNullValue());
-        assertThat(source.getProperties(), aMapWithSize(2)); // double the size for .source values.
-        assertThat(source.getProperties(), hasEntry("a", PropertyValue.of("a", "b", resource.toString())));
-        assertThat(source.getProperties(), hasEntry("b", PropertyValue.of("b", "1", resource.toString())));
-
-    }
-
-    @Test
-    public void failsToCreateFromNonXMLPropertiesXMLFile() {
-        URL resource = getClass().getResource("/non-xml-properties.xml");
-        ConfigException catchedException = null;
-
-        try {
-            new SimplePropertySource(resource);
-        } catch (ConfigException ce) {
-            catchedException = ce;
-        }
-
-        assertThat(catchedException.getMessage(), allOf(startsWith("Error loading properties from"),
-                                                        endsWith("non-xml-properties.xml")));
-    }
-
-    @Test
-    public void failsToCreateFromInvalidPropertiesXMLFile() {
-        URL resource = getClass().getResource("/invalid-properties.xml");
-        ConfigException catchedException = null;
-
-        try {
-            new SimplePropertySource(resource);
-        } catch (ConfigException ce) {
-            catchedException = ce;
-        }
-
-        assertThat(catchedException.getMessage(), allOf(startsWith("Error loading properties from"),
-                                                        endsWith("invalid-properties.xml")));
-    }
-
-
-    @Test
-    public void successfulCreationWithPropertiesFromSimplePropertiesFile() {
-        URL resource = getClass().getResource("/testfile.properties");
-
-        SimplePropertySource source = new SimplePropertySource(resource);
-
-        assertThat(source, notNullValue());
-        assertThat(source.getProperties(), aMapWithSize(5)); // double the size for .source values.
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/test/java/org/apache/tamaya/core/propertysource/SystemPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/propertysource/SystemPropertySourceTest.java b/code/core/src/test/java/org/apache/tamaya/core/propertysource/SystemPropertySourceTest.java
deleted file mode 100644
index 2b2b61e..0000000
--- a/code/core/src/test/java/org/apache/tamaya/core/propertysource/SystemPropertySourceTest.java
+++ /dev/null
@@ -1,91 +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.tamaya.core.propertysource;
-
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertyValue;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.Map;
-import java.util.Properties;
-
-public class SystemPropertySourceTest {
-
-    private final SystemPropertySource testPropertySource = new SystemPropertySource();
-
-
-    @Test
-    public void testGetOrdinal() throws Exception {
-
-        // test the default ordinal
-        Assert.assertEquals(SystemPropertySource.DEFAULT_ORDINAL, testPropertySource.getOrdinal());
-
-        // set the ordinal to 1001
-        System.setProperty(PropertySource.TAMAYA_ORDINAL, "1001");
-        Assert.assertEquals(1001, new SystemPropertySource().getOrdinal());
-        // currently its not possible to change ordinal at runtime
-
-        // reset it to not destroy other tests!!
-        System.clearProperty(PropertySource.TAMAYA_ORDINAL);
-    }
-
-    @Test
-    public void testGetName() throws Exception {
-        Assert.assertEquals("system-properties", testPropertySource.getName());
-    }
-
-    @Test
-    public void testGet() throws Exception {
-        String propertyKeyToCheck = System.getProperties().stringPropertyNames().iterator().next();
-
-        PropertyValue property = testPropertySource.get(propertyKeyToCheck);
-        Assert.assertNotNull("Property '" + propertyKeyToCheck + "' is not present in " +
-                SystemPropertySource.class.getSimpleName(), property);
-        Assert.assertEquals(System.getProperty(propertyKeyToCheck), property.getValue());
-    }
-
-    @Test
-    public void testGetProperties() throws Exception {
-        checkWithSystemProperties(testPropertySource.getProperties());
-
-        // modify system properties
-        System.setProperty("test", "myTestVal");
-
-        checkWithSystemProperties(testPropertySource.getProperties());
-
-        // cleanup
-        System.clearProperty("test");
-    }
-
-    private void checkWithSystemProperties(Map<String,PropertyValue> toCheck) {
-        Properties systemEntries = System.getProperties();
-        int num = 0;
-        for (PropertyValue propertySourceEntry : toCheck.values()) {
-            if(propertySourceEntry.getKey().startsWith("_")){
-                continue; // meta entry
-            }
-            num ++;
-            Assert.assertEquals("Entry values for key '" + propertySourceEntry.getKey() + "' do not match",
-                                systemEntries.getProperty(propertySourceEntry.getKey()), propertySourceEntry.getValue());
-        }
-        Assert.assertEquals("size of System.getProperties().entrySet() must be the same as SystemPropertySrouce.getProperties().entrySet()",
-                systemEntries.size(), num);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSource.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSource.java b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSource.java
index 09d86f1..c315ff6 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSource.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSource.java
@@ -18,7 +18,7 @@
  */
 package org.apache.tamaya.core.testdata;
 
-import org.apache.tamaya.core.propertysource.BasePropertySource;
+import org.apache.tamaya.spisupport.propertysource.BasePropertySource;
 import org.apache.tamaya.spi.PropertyValue;
 
 import java.util.Collections;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
index b93be17..5a427e0 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
@@ -18,7 +18,7 @@
  */
 package org.apache.tamaya.core.testdata;
 
-import org.apache.tamaya.core.propertysource.BasePropertySource;
+import org.apache.tamaya.spisupport.propertysource.BasePropertySource;
 import org.apache.tamaya.spi.PropertySource;
 import org.apache.tamaya.spi.PropertySourceProvider;
 import org.apache.tamaya.spi.PropertyValue;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
----------------------------------------------------------------------
diff --git a/code/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource b/code/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
index 409c9cb..14e0c24 100644
--- a/code/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
+++ b/code/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
@@ -17,6 +17,6 @@
 # under the License.
 #
 org.apache.tamaya.core.testdata.TestPropertyDefaultSource
-org.apache.tamaya.core.propertysource.SystemPropertySource
-org.apache.tamaya.core.propertysource.EnvironmentPropertySource
+org.apache.tamaya.spisupport.propertysource.SystemPropertySource
+org.apache.tamaya.spisupport.propertysource.EnvironmentPropertySource
 org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/pom.xml
----------------------------------------------------------------------
diff --git a/code/pom.xml b/code/pom.xml
index aba365b..719d498 100644
--- a/code/pom.xml
+++ b/code/pom.xml
@@ -34,6 +34,7 @@ under the License.
 
     <modules>
         <module>api</module>
+        <module>spi-support</module>
         <module>core</module>
     </modules>
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/pom.xml
----------------------------------------------------------------------
diff --git a/code/spi-support/pom.xml b/code/spi-support/pom.xml
new file mode 100644
index 0000000..bbefa89
--- /dev/null
+++ b/code/spi-support/pom.xml
@@ -0,0 +1,81 @@
+<!-- 
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy current the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.tamaya</groupId>
+        <artifactId>tamaya-code</artifactId>
+        <version>0.4-incubating-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>tamaya-spisupport</artifactId>
+    <name>Apache Tamaya Common Support Classes</name>
+    <description>Apache Tamaya Support Classes useful when implementing the Tamaya SPI or code independent of the core RI
+        implementation.</description>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>java-hamcrest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <!--
+                 ! See https://issues.apache.org/jira/browse/TAMAYA-318
+                 !-->
+                <groupId>org.pitest</groupId>
+                <artifactId>pitest-maven</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/main/java/org/apache/tamaya/spisupport/ConfigValueEvaluator.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/ConfigValueEvaluator.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/ConfigValueEvaluator.java
new file mode 100644
index 0000000..92fd614
--- /dev/null
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/ConfigValueEvaluator.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.Map;
+
+
+/**
+ * Component SPI which encapsulates the evaluation of a single or full <b>raw</b>value
+ * for a {@link ConfigurationContext}.
+ */
+public interface ConfigValueEvaluator {
+
+    /**
+     * Evaluates single value using a {@link ConfigurationContext}.
+     * @param key the config key, not null.
+     * @param context the context, not null.
+     * @return the value, or null.
+     */
+    PropertyValue evaluteRawValue(String key, ConfigurationContext context);
+
+    /**
+     * Evaluates all property values from a {@link ConfigurationContext}.
+     * @param context the context, not null.
+     * @return the value, or null.
+     */
+    Map<String, PropertyValue> evaluateRawValues(ConfigurationContext context);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/main/java/org/apache/tamaya/spisupport/ConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/ConfigurationBuilder.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/ConfigurationBuilder.java
new file mode 100644
index 0000000..b764ed6
--- /dev/null
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/ConfigurationBuilder.java
@@ -0,0 +1,334 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.*;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A builder for creating new or adapting instances of {@link Configuration}.
+ * Builders can be obtained in exactly two ways:
+ * <ol>
+ *     <li>By accessing a preinitialized builder from an existing {@link Configuration},
+ *     by calling {@link org.apache.tamaya.Configuration#toBuilder()}.</li>
+ *     <li>By accessing an empty builder instance from
+ *     {@link org.apache.tamaya.ConfigurationProvider#getConfigurationBuilder()}.</li>
+ * </ol>
+ */
+public interface ConfigurationBuilder {
+
+    /**
+     * Init this builder instance with the given {@link ConfigurationContext} instance. This
+     * method will use any existing property sources, filters, converters and the combination
+     * policy of the given {@link ConfigurationContext} and initialize the current builder
+     * with them.
+     *
+     * @param context the {@link ConfigurationContext} instance to be used, not {@code null}.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder setContext(ConfigurationContext context);
+
+    /**
+     * This method can be used for adding {@link PropertySource}s.
+     * Hereby the property source is added to the tail of property sources with
+     * lowest priority  regardless of its current ordinal value. To sort the property
+     * sources based on their ordinals call {@link #sortPropertySources}.
+     *
+     * @param propertySources the PropertySources to add
+     * @return this builder, for chaining, never null.
+     * @throws IllegalArgumentException If a property source with a given name already
+     * exists.
+     */
+    ConfigurationBuilder addPropertySources(PropertySource... propertySources);
+
+    /**
+     * This method can be used for programmatically adding {@link PropertySource}s.
+     * Hereby the property source is added to the tail of property sources with
+     * lowest priority regardless of its current ordinal value. To sort the property
+     * sources based on their ordinals call {@link #sortPropertySources}.
+     *
+     * @param propertySources the PropertySources to add
+     * @return this builder, for chaining, never null.
+     * @throws IllegalArgumentException If a property source with a given name already
+     * exists.
+     */
+    ConfigurationBuilder addPropertySources(Collection<PropertySource> propertySources);
+
+    /**
+     * Add all registered (default) property sources to the context built. The sources are ordered
+     * based on their ordinal values and added to the chain of property sources with
+     * higher priority.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder addDefaultPropertySources();
+
+    /**
+     * Removes the given property sources, if existing. The existing order of property
+     * sources is preserved.
+     *
+     * @param propertySources the property sources to remove, not {@code null}.
+     * @return the builder for chaining.
+     */
+    ConfigurationBuilder removePropertySources(PropertySource... propertySources);
+
+    /**
+     * Removes the given property sources, if existing. The existing order of property
+     * sources is preserved.
+     *
+     * @param propertySources the property sources to remove, not {@code null}.
+     * @return the builder for chaining.
+     */
+    ConfigurationBuilder removePropertySources(Collection<PropertySource> propertySources);
+
+    /**
+     * Access the current chain of property sources. Items at the end of the list have
+     * precedence/more significance.
+     *
+     * @return the property source chain, never {@code null}.
+     */
+    List<PropertySource> getPropertySources();
+
+    /**
+     * Access the current chain of property filters. Items at the end of the list have
+     * precedence/more significance.
+     *
+     * @return the property source chain, never {@code null}.
+     */
+    List<PropertyFilter> getPropertyFilters();
+
+    /**
+     * Access the current registered property converters.
+     *
+     * @return the current registered property converters.
+     */
+    Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> getPropertyConverter();
+
+    /**
+     * Increases the priority of the given property source, by moving it towards the end
+     * of the chain of property sources. If the property source given is already at the end
+     * this method has no effect. This operation does not change any ordinal values.
+     *
+     * @param propertySource the property source to be incresed regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    ConfigurationBuilder increasePriority(PropertySource propertySource);
+
+    /**
+     * Decreases the priority of the given property source, by moving it towards the start
+     * of the chain of property sources. If the property source given is already the first
+     * this method has no effect. This operation does not change any ordinal values.
+     *
+     * @param propertySource the property source to be decresed regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    ConfigurationBuilder decreasePriority(PropertySource propertySource);
+
+    /**
+     * Increases the priority of the given property source to be maximal, by moving it to
+     * the tail of the of property source chain. If the property source given is
+     * already the last item this method has no effect. This operation does not change
+     * any ordinal values.
+     *
+     * @param propertySource the property source to be maximized regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    ConfigurationBuilder highestPriority(PropertySource propertySource);
+
+    /**
+     * Decreases the priority of the given property source to be minimal, by moving it to
+     * the start of the chain of property source chain. If the property source given is
+     * already the first item this method has no effect. This operation does not change
+     * any ordinal values.
+     *
+     * @param propertySource the property source to be minimized regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    ConfigurationBuilder lowestPriority(PropertySource propertySource);
+
+    /**
+     * Adds the given PropertyFilter instances, hereby the instances are added
+     * to the end of the list with highest priority. The ordering of existing
+     * property filters remains unchanged. To sort the property
+     * filters call {@link #sortPropertyFilter}.
+     *
+     * @param filters the filters to add
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder addPropertyFilters(PropertyFilter... filters);
+
+    /**
+     * Adds the given PropertyFilter instances, hereby the instances are added
+     * to the end of the list with highest priority. The ordering of existing
+     * property filters remains unchanged. To sort the property
+     * filters call {@link #sortPropertyFilter}.
+     *
+     * @param filters the filters to add
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder addPropertyFilters(Collection<PropertyFilter> filters);
+
+    /**
+     * Add all registered (default) property filters to the context built.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder addDefaultPropertyFilters();
+
+
+    /**
+     * Removes the given PropertyFilter instances, if existing. The order of the remaining
+     * filters is preserved.
+     *
+     * @param filters the filter to remove
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder removePropertyFilters(PropertyFilter... filters);
+
+    /**
+     * Removes the given PropertyFilter instances, if existing. The order of the remaining
+     * filters is preserved.
+     *
+     * @param filters the filter to remove
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder removePropertyFilters(Collection<PropertyFilter> filters);
+
+    /**
+     * This method can be used for adding {@link PropertyConverter}s.
+     * Converters are added at the end after any existing converters.
+     * For converters already registered for the current target type the
+     * method has no effect.
+     *
+     * @param typeToConvert     the type for which the converters is for
+     * @param propertyConverters the PropertyConverters to add for this type
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationBuilder addPropertyConverters(TypeLiteral<T> typeToConvert,
+                                                                                PropertyConverter<T>... propertyConverters);
+
+    /**
+     * This method can be used for adding {@link PropertyConverter}s.
+     * Converters are added at the end after any existing converters.
+     * For converters already registered for the current target type the
+     * method has no effect.
+     *
+     * @param typeToConvert     the type for which the converters is for
+     * @param propertyConverters the PropertyConverters to add for this type
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationBuilder addPropertyConverters(TypeLiteral<T> typeToConvert,
+                                                                                Collection<PropertyConverter<T>> propertyConverters);
+
+    /**
+     * Add all registered (default) property converters to the context built.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder addDefaultPropertyConverters();
+
+    /**
+     * Removes the given PropertyConverter instances for the given type,
+     * if existing.
+     *
+     * @param typeToConvert the type which the converters is for
+     * @param propertyConverters    the converters to remove
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                                                   PropertyConverter<T>... propertyConverters);
+
+    /**
+     * Removes the given PropertyConverter instances for the given type,
+     * if existing.
+     *
+     * @param typeToConvert the type which the converters is for
+     * @param propertyConverters    the converters to remove
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                                                   Collection<PropertyConverter<T>> propertyConverters);
+
+    /**
+     * Removes all converters for the given type, which actually renders a given type
+     * unsupported for type conversion.
+     *
+     * @param typeToConvert the type which the converters is for
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder removePropertyConverters(TypeLiteral<?> typeToConvert);
+
+    /**
+     * Sorts the current registered property sources using the given comparator.
+     *
+     * NOTE: property sources at the beginning have minimal significance.
+     *
+     * @param comparator the comparator to be used, not {@code null}.
+     * @return this instance for chaining.
+     */
+    ConfigurationBuilder sortPropertySources(Comparator<PropertySource> comparator);
+
+    /**
+     * Sorts the current registered property filters using the given comparator.
+     *
+     * NOTE: property filters at the beginning have minimal significance.
+     *
+     * @param comparator the comparator to be used, not {@code null}.
+     * @return this instance for chaining.
+     */
+    ConfigurationBuilder sortPropertyFilter(Comparator<PropertyFilter> comparator);
+
+    /**
+     * Sets the {@link PropertyValueCombinationPolicy} used to evaluate the final
+     * property values.
+     *
+     * @param policy the {@link PropertyValueCombinationPolicy} used, not {@code null}.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy);
+
+    /**
+     * Builds a new {@link Configuration} based on the data in this builder. The ordering of property
+     * sources and property filters is not changed, regardless of their ordinals. For ensure a certain
+     * ordering/significance call {@link #sortPropertyFilter(Comparator)} and/or {@link #sortPropertySources(Comparator)}
+     * before building the context.
+     *
+     * @return the final configuration.
+     */
+    Configuration build();
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigValueEvaluator.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigValueEvaluator.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigValueEvaluator.java
new file mode 100644
index 0000000..d50ed7d
--- /dev/null
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigValueEvaluator.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Implementation of the Configuration API. This class uses the current {@link ConfigurationContext} to evaluate the
+ * chain of {@link PropertySource} and {@link PropertyFilter}
+ * instance to evaluate the current Configuration.
+ */
+public class DefaultConfigValueEvaluator implements ConfigValueEvaluator{
+
+    @Override
+    public PropertyValue evaluteRawValue(String key, ConfigurationContext context) {
+        PropertyValue unfilteredValue = null;
+        for (PropertySource propertySource : context.getPropertySources()) {
+            unfilteredValue = context.getPropertyValueCombinationPolicy().
+                    collect(unfilteredValue, key, propertySource);
+        }
+        if(unfilteredValue==null || unfilteredValue.getValue()==null){
+            return null;
+        }
+        return unfilteredValue;
+    }
+
+    @Override
+    public Map<String, PropertyValue> evaluateRawValues(ConfigurationContext context) {
+        Map<String, PropertyValue> result = new HashMap<>();
+        for (PropertySource propertySource : context.getPropertySources()) {
+            for (Map.Entry<String,PropertyValue> propEntry: propertySource.getProperties().entrySet()) {
+                PropertyValue unfilteredValue = result.get(propEntry.getKey());
+                unfilteredValue = context.getPropertyValueCombinationPolicy().
+                        collect(unfilteredValue, propEntry.getKey(), propertySource);
+                if(unfilteredValue!=null){
+                    result.put(unfilteredValue.getKey(), unfilteredValue);
+                }
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "DefaultConfigEvaluator{}";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java
new file mode 100644
index 0000000..227c9ab
--- /dev/null
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java
@@ -0,0 +1,268 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.ConfigOperator;
+import org.apache.tamaya.ConfigQuery;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of the Configuration API. This class uses the current {@link ConfigurationContext} to evaluate the
+ * chain of {@link PropertySource} and {@link org.apache.tamaya.spi.PropertyFilter}
+ * instance to evaluate the current Configuration.
+ */
+public class DefaultConfiguration implements Configuration {
+    /**
+     * The logger.
+     */
+    private static final Logger LOG = Logger.getLogger(DefaultConfiguration.class.getName());
+
+    /**
+     * The current {@link ConfigurationContext} of the current instance.
+     */
+    private final ConfigurationContext configurationContext;
+
+    /**
+     * EvaluationStrategy
+     */
+    private ConfigValueEvaluator configEvaluator = loadConfigValueEvaluator();
+
+    private ConfigValueEvaluator loadConfigValueEvaluator() {
+        ConfigValueEvaluator eval = null;
+        try{
+            eval = ServiceContextManager.getServiceContext()
+                    .getService(ConfigValueEvaluator.class);
+        }catch(Exception e){
+            LOG.log(Level.WARNING, "Failed to load ConfigValueEvaluator from ServiceContext, using default.", e);
+        }
+        if(eval==null){
+            eval = new DefaultConfigValueEvaluator();
+        }
+        return eval;
+    }
+
+
+    /**
+     * Constructor.
+     * @param configurationContext The configuration Context to be used.
+     */
+    public DefaultConfiguration(ConfigurationContext configurationContext){
+        this.configurationContext = Objects.requireNonNull(configurationContext);
+    }
+
+    /**
+     * Get a given value, filtered with the context's filters as needed.
+     * @param key the property's key, not null.
+     * @return the filtered value, or null.
+     */
+    @Override
+    public String get(String key) {
+        Objects.requireNonNull(key, "Key must not be null.");
+
+        PropertyValue value = configEvaluator.evaluteRawValue(key, configurationContext);
+        if(value==null || value.getValue()==null){
+            return null;
+        }
+        value = PropertyFiltering.applyFilter(value, configurationContext);
+        if(value!=null){
+            return value.getValue();
+        }
+        return null;
+    }
+
+    /**
+     * Evaluates the raw value using the context's PropertyValueCombinationPolicy.
+     * @param key the key, not null.
+     * @return the value, before filtering is applied.
+     */
+    protected PropertyValue evaluteRawValue(String key) {
+        List<PropertySource> propertySources = configurationContext.getPropertySources();
+        PropertyValue filteredValue = null;
+        PropertyValueCombinationPolicy combinationPolicy = this.configurationContext
+                .getPropertyValueCombinationPolicy();
+        for (PropertySource propertySource : propertySources) {
+            filteredValue = combinationPolicy.collect(filteredValue, key, propertySource);
+        }
+        return filteredValue;
+    }
+
+
+    @Override
+    public String getOrDefault(String key, String defaultValue) {
+        Objects.requireNonNull(key, "Key must not be null.");
+        Objects.requireNonNull(defaultValue, "Default value must not be null");
+
+        String val = get(key);
+        if(val==null){
+            return defaultValue;
+        }
+        return val;
+    }
+
+    @Override
+    public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
+        Objects.requireNonNull(key, "Key must not be null.");
+        Objects.requireNonNull(type, "Target type must not be null");
+        Objects.requireNonNull(defaultValue, "Default value must not be null");
+
+        T val = get(key, type);
+        if(val==null){
+            return defaultValue;
+        }
+        return val;
+    }
+
+    /**
+     * Get the current properties, composed by the loaded {@link PropertySource} and filtered
+     * by registered {@link org.apache.tamaya.spi.PropertyFilter}.
+     *
+     * @return the final properties.
+     */
+    @Override
+    public Map<String, String> getProperties() {
+        Map<String, PropertyValue> filtered = PropertyFiltering.applyFilters(
+                configEvaluator.evaluateRawValues(configurationContext),
+                configurationContext);
+        Map<String,String> result = new HashMap<>();
+        for(PropertyValue val:filtered.values()){
+            if(val.getValue()!=null) {
+                result.put(val.getKey(), val.getValue());
+                // TODO: Discuss metadata handling...
+                result.putAll(val.getMetaEntries());
+            }
+        }
+        return result;
+    }
+
+
+    /**
+     * Accesses the current String value for the given key and tries to convert it
+     * using the {@link PropertyConverter} instances provided by the current
+     * {@link ConfigurationContext}.
+     *
+     * @param key  the property's absolute, or relative path, e.g. @code
+     *             a/b/c/d.myProperty}, never {@code null}.
+     * @param type The target type required, not {@code null}.
+     * @param <T>  the value type
+     * @return the converted value, never {@code null}.
+     */
+    @Override
+    public <T> T get(String key, Class<T> type) {
+        return get(key, (TypeLiteral<T>)TypeLiteral.of(type));
+    }
+
+    /**
+     * Accesses the current String value for the given key and tries to convert it
+     * using the {@link PropertyConverter} instances provided by the current
+     * {@link ConfigurationContext}.
+     *
+     * @param key  the property's absolute, or relative path, e.g. @code
+     *             a/b/c/d.myProperty}.
+     * @param type The target type required, not null.
+     * @param <T>  the value type
+     * @return the converted value, never null.
+     */
+    @Override
+    public <T> T get(String key, TypeLiteral<T> type) {
+        Objects.requireNonNull(key, "Key must not be null.");
+        Objects.requireNonNull(type, "Target type must not be null");
+
+        return convertValue(key, get(key), type);
+    }
+
+    @SuppressWarnings("unchecked")
+	protected <T> T convertValue(String key, String value, TypeLiteral<T> type) {
+        if (value != null) {
+            List<PropertyConverter<T>> converters = configurationContext.getPropertyConverters(type);
+            ConversionContext context = new ConversionContext.Builder(this, this.configurationContext, key, type)
+                    .build();
+            for (PropertyConverter<T> converter : converters) {
+                try {
+                    T t = converter.convert(value, context);
+                    if (t != null) {
+                        return t;
+                    }
+                } catch (Exception e) {
+                    LOG.log(Level.FINEST, "PropertyConverter: " + converter + " failed to convert value: " + value, e);
+                }
+            }
+            // if the target type is a String, we can return the value, no conversion required.
+            if(type.equals(TypeLiteral.of(String.class))){
+                return (T)value;
+            }
+            // unsupported type, throw an exception
+            throw new ConfigException("Unparseable config value for type: " + type.getRawType().getName() + ": " + key +
+                    ", supported formats: " + context.getSupportedFormats());
+        }
+        return null;
+    }
+
+    @Override
+    public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) {
+        Objects.requireNonNull(key);
+        Objects.requireNonNull(type);
+        Objects.requireNonNull(defaultValue);
+
+        T val = get(key, type);
+        if(val==null){
+            return defaultValue;
+        }
+        return val;
+    }
+
+    @Override
+    public Configuration with(ConfigOperator operator) {
+        return operator.operate(this);
+    }
+
+    @Override
+    public <T> T query(ConfigQuery<T> query) {
+        return query.query(this);
+    }
+
+    @Override
+    public ConfigurationContext getContext() {
+        return this.configurationContext;
+    }
+
+    @Override
+    public String toString() {
+        return "Configuration{\n " +
+                configurationContext +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java
new file mode 100644
index 0000000..f1c0f46
--- /dev/null
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.*;
+
+import java.util.*;
+
+/**
+ * Default implementation of {@link ConfigurationContextBuilder}.
+ */
+public class DefaultConfigurationBuilder implements ConfigurationBuilder {
+
+    private final ConfigurationContextBuilder contextBuilder;
+
+    /**
+     * Creates a new builder instance.
+     */
+    public DefaultConfigurationBuilder(ConfigurationContextBuilder contextBuilder) {
+        this.contextBuilder = Objects.requireNonNull(contextBuilder);
+    }
+
+    /**
+     * Creates a new builder instance initializing it with the given context.
+     * @param configuration the configuration to be used, not null.
+     */
+    public DefaultConfigurationBuilder(Configuration configuration) {
+        this.contextBuilder = configuration.getContext().toBuilder();
+    }
+
+    /**
+     * Allows to set configuration context during unit tests.
+     */
+    ConfigurationBuilder setConfiguration(Configuration configuration) {
+        this.contextBuilder.setContext(configuration.getContext());
+        return this;
+    }
+
+
+    @Override
+    public ConfigurationBuilder setContext(ConfigurationContext context) {
+        this.contextBuilder.setContext(context);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder addPropertySources(PropertySource... sources){
+        this.contextBuilder.addPropertySources(sources);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder addPropertySources(Collection<PropertySource> sources){
+        this.contextBuilder.addPropertySources(sources);
+        return this;
+    }
+
+    public ConfigurationBuilder addDefaultPropertyFilters() {
+        this.contextBuilder.addDefaultPropertyFilters();
+        return this;
+    }
+
+    public ConfigurationBuilder addDefaultPropertySources() {
+        this.contextBuilder.addDefaultPropertySources();
+        return this;
+    }
+
+    public ConfigurationBuilder addDefaultPropertyConverters() {
+        this.contextBuilder.addDefaultPropertyConverters();
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder removePropertySources(PropertySource... propertySources) {
+        this.contextBuilder.removePropertySources(propertySources);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder removePropertySources(Collection<PropertySource> propertySources) {
+        this.contextBuilder.removePropertySources(propertySources);
+        return this;
+    }
+
+    @Override
+    public List<PropertySource> getPropertySources() {
+        return this.contextBuilder.getPropertySources();
+    }
+
+    @Override
+    public ConfigurationBuilder increasePriority(PropertySource propertySource) {
+        this.contextBuilder.increasePriority(propertySource);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder decreasePriority(PropertySource propertySource) {
+        this.contextBuilder.decreasePriority(propertySource);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder highestPriority(PropertySource propertySource) {
+        this.contextBuilder.highestPriority(propertySource);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder lowestPriority(PropertySource propertySource) {
+        this.contextBuilder.lowestPriority(propertySource);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder addPropertyFilters(PropertyFilter... filters){
+        this.contextBuilder.addPropertyFilters(filters);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder addPropertyFilters(Collection<PropertyFilter> filters){
+        this.contextBuilder.addPropertyFilters(filters);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder removePropertyFilters(PropertyFilter... filters) {
+        this.contextBuilder.removePropertyFilters(filters);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder removePropertyFilters(Collection<PropertyFilter> filters) {
+        this.contextBuilder.removePropertyFilters(filters);
+        return this;
+    }
+
+
+    @Override
+    public <T> ConfigurationBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                                    PropertyConverter<T>... converters) {
+        this.contextBuilder.removePropertyConverters(typeToConvert, converters);
+        return this;
+    }
+
+    @Override
+    public <T> ConfigurationBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                                    Collection<PropertyConverter<T>> converters) {
+        this.contextBuilder.removePropertyConverters(typeToConvert, converters);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder removePropertyConverters(TypeLiteral<?> typeToConvert) {
+        this.contextBuilder.removePropertyConverters(typeToConvert);
+        return this;
+    }
+
+
+    @Override
+    public ConfigurationBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy combinationPolicy){
+        this.contextBuilder.setPropertyValueCombinationPolicy(combinationPolicy);
+        return this;
+    }
+
+
+    @Override
+    public <T> ConfigurationBuilder addPropertyConverters(TypeLiteral<T> type, PropertyConverter<T>... propertyConverters){
+        this.contextBuilder.addPropertyConverters(type, propertyConverters);
+        return this;
+    }
+
+    @Override
+    public <T> ConfigurationBuilder addPropertyConverters(TypeLiteral<T> type, Collection<PropertyConverter<T>> propertyConverters){
+        this.contextBuilder.addPropertyConverters(type, propertyConverters);
+        return this;
+    }
+
+    /**
+     * Builds a new configuration based on the configuration of this builder instance.
+     *
+     * @return a new {@link org.apache.tamaya.Configuration configuration instance},
+     *         never {@code null}.
+     */
+    @Override
+    public Configuration build() {
+        return new DefaultConfiguration(this.contextBuilder.build());
+    }
+
+    @Override
+    public ConfigurationBuilder sortPropertyFilter(Comparator<PropertyFilter> comparator) {
+        this.contextBuilder.sortPropertyFilter(comparator);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder sortPropertySources(Comparator<PropertySource> comparator) {
+        this.contextBuilder.sortPropertySources(comparator);
+        return this;
+    }
+
+    @Override
+    public List<PropertyFilter> getPropertyFilters() {
+        return this.contextBuilder.getPropertyFilters();
+    }
+
+    @Override
+    public Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> getPropertyConverter() {
+        return this.contextBuilder.getPropertyConverter();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java
new file mode 100644
index 0000000..61819f9
--- /dev/null
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultServiceContext.java
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.ServiceContext;
+
+import javax.annotation.Priority;
+import java.io.IOException;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class implements the (default) {@link ServiceContext} interface and hereby uses the JDK
+ * {@link ServiceLoader} to load the services required.
+ */
+public final class DefaultServiceContext implements ServiceContext {
+    private static final Logger LOG = Logger.getLogger(DefaultServiceContext.class.getName());
+    /**
+     * List current services loaded, per class.
+     */
+    private final ConcurrentHashMap<Class<?>, List<Object>> servicesLoaded = new ConcurrentHashMap<>();
+    /**
+     * Singletons.
+     */
+    private final Map<Class<?>, Object> singletons = new ConcurrentHashMap<>();
+    @SuppressWarnings("rawtypes")
+	private Map<Class, Class> factoryTypes = new ConcurrentHashMap<>();
+
+    @Override
+    public <T> T getService(Class<T> serviceType) {
+        Object cached = singletons.get(serviceType);
+        if (cached == null) {
+            cached = create(serviceType);
+            if(cached!=null) {
+                singletons.put(serviceType, cached);
+            }
+        }
+        return serviceType.cast(cached);
+    }
+
+    @Override
+    public <T> T create(Class<T> serviceType) {
+        @SuppressWarnings("unchecked")
+		Class<? extends T> implType = factoryTypes.get(serviceType);
+        if(implType==null) {
+            Collection<T> services = getServices(serviceType);
+            if (services.isEmpty()) {
+                return null;
+            } else {
+                return getServiceWithHighestPriority(services, serviceType);
+            }
+        }
+        try {
+            return implType.newInstance();
+        } catch (Exception e) {
+            LOG.log(Level.SEVERE, "Failed to create instance of " + implType.getName(), e);
+            return  null;
+        }
+    }
+
+    /**
+     * Loads and registers services.
+     *
+     * @param <T>         the concrete type.
+     * @param serviceType The service type.
+     * @return the items found, never {@code null}.
+     */
+    @Override
+    public <T> List<T> getServices(final Class<T> serviceType) {
+        @SuppressWarnings("unchecked")
+		List<T> found = (List<T>) servicesLoaded.get(serviceType);
+        if (found != null) {
+            return found;
+        }
+        List<T> services = new ArrayList<>();
+        try {
+            for (T t : ServiceLoader.load(serviceType)) {
+                services.add(t);
+            }
+            if(services.isEmpty()) {
+                for (T t : ServiceLoader.load(serviceType, serviceType.getClassLoader())) {
+                    services.add(t);
+                }
+            }
+            Collections.sort(services, PriorityServiceComparator.getInstance());
+            services = Collections.unmodifiableList(services);
+        } catch (ServiceConfigurationError e) {
+            LOG.log(Level.WARNING,
+                    "Error loading services current type " + serviceType, e);
+            if(services==null){
+                services = Collections.emptyList();
+            }
+        }
+        @SuppressWarnings("unchecked")
+		final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>) services));
+        return previousServices != null ? previousServices : services;
+    }
+
+    /**
+     * Checks the given instance for a @Priority annotation. If present the annotation's value is evaluated. If no such
+     * annotation is present, a default priority of {@code 1} is returned.
+     * @param o the instance, not {@code null}.
+     * @return a priority, by default 1.
+     */
+    public static int getPriority(Object o){
+        int prio = 1; //X TODO discuss default priority
+        Priority priority = o.getClass().getAnnotation(Priority.class);
+        if (priority != null) {
+            prio = priority.value();
+        }
+        return prio;
+    }
+
+    /**
+     * @param services to scan
+     * @param <T>      type of the service
+     *
+     * @return the service with the highest {@link Priority#value()}
+     *
+     * @throws ConfigException if there are multiple service implementations with the maximum priority
+     */
+    private <T> T getServiceWithHighestPriority(Collection<T> services, Class<T> serviceType) {
+        T highestService = null;
+        // we do not need the priority stuff if the list contains only one element
+        if (services.size() == 1) {
+            highestService = services.iterator().next();
+            this.factoryTypes.put(serviceType, highestService.getClass());
+            return highestService;
+        }
+
+        Integer highestPriority = null;
+        int highestPriorityServiceCount = 0;
+
+        for (T service : services) {
+            int prio = getPriority(service);
+            if (highestPriority == null || highestPriority < prio) {
+                highestService = service;
+                highestPriorityServiceCount = 1;
+                highestPriority = prio;
+            } else if (highestPriority == prio) {
+                highestPriorityServiceCount++;
+            }
+        }
+
+        if (highestPriorityServiceCount > 1) {
+            throw new ConfigException(MessageFormat.format("Found {0} implementations for Service {1} with Priority {2}: {3}",
+                                                           highestPriorityServiceCount,
+                                                           serviceType.getName(),
+                                                           highestPriority,
+                                                           services));
+        }
+        this.factoryTypes.put(serviceType, highestService.getClass());
+        return highestService;
+    }
+
+    @Override
+    public int ordinal() {
+        return 1;
+    }
+
+    @Override
+    public Enumeration<URL> getResources(String resource, ClassLoader cl) throws IOException {
+        if(cl==null){
+            cl = Thread.currentThread().getContextClassLoader();
+        }
+        if(cl==null){
+            cl = getClass().getClassLoader();
+        }
+        return cl.getResources(resource);
+    }
+
+    @Override
+    public URL getResource(String resource, ClassLoader cl) {
+        if(cl==null){
+            cl = Thread.currentThread().getContextClassLoader();
+        }
+        if(cl==null){
+            cl = getClass().getClassLoader();
+        }
+        return cl.getResource(resource);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java
new file mode 100644
index 0000000..ed5214a
--- /dev/null
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.osgi.service.component.annotations.Component;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to tge given enum type.
+ */
+@Component(service = PropertyConverter.class)
+public class EnumConverter<T> implements PropertyConverter<T> {
+    private final Logger LOG = Logger.getLogger(EnumConverter.class.getName());
+    private Class<T> enumType;
+    private Method factory;
+
+    public EnumConverter(Class<T> enumType) {
+        if (!Enum.class.isAssignableFrom(enumType)) {
+            throw new IllegalArgumentException("Not an Enum: " + enumType.getName());
+        }
+        this.enumType = Objects.requireNonNull(enumType);
+        try {
+            this.factory = enumType.getMethod("valueOf", String.class);
+        } catch (NoSuchMethodException e) {
+            throw new ConfigException("Uncovertible enum type without valueOf method found, please provide a custom " +
+                    "PropertyConverter for: " + enumType.getName());
+        }
+    }
+
+    @Override
+    public T convert(String value, ConversionContext context) {
+        context.addSupportedFormats(getClass(),"<enumValue>");
+        try {
+            return (T) factory.invoke(null, value);
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + enumType.getName(), e);
+        }
+        try {
+            return (T) factory.invoke(null, value.toUpperCase(Locale.ENGLISH));
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + enumType.getName(), e);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof EnumConverter)) return false;
+        EnumConverter<?> that = (EnumConverter<?>) o;
+        return Objects.equals(enumType, that.enumType);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(enumType);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java
new file mode 100644
index 0000000..dbef51f
--- /dev/null
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import javax.annotation.Priority;
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * Comparator implementation for odering services loaded based on their increasing priority values.
+ */
+public class PriorityServiceComparator implements Comparator<Object>, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final PriorityServiceComparator INSTANCE = new PriorityServiceComparator();
+
+    /** Singleton constructor. */
+    private PriorityServiceComparator(){}
+
+    /**
+     * Get the shared instance of the comparator.
+     * @return the shared instance, never null.
+     */
+    public static PriorityServiceComparator getInstance(){
+        return INSTANCE;
+    }
+
+    @Override
+    public int compare(Object o1, Object o2) {
+        int prio = getPriority(o1) - getPriority(o2);
+        if (prio < 0) {
+            return 1;
+        } else if (prio > 0) {
+            return -1;
+        } else {
+            return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
+        }
+    }
+
+    /**
+     * Checks the given instance for a @Priority annotation. If present the annotation's value is evaluated. If no such
+     * annotation is present, a default priority {@code 1} is returned.
+     *
+     * @param o the instance, not {@code null}.
+     * @return a priority, by default 1.
+     */
+    public static int getPriority(Object o) {
+        return getPriority(o.getClass());
+    }
+
+    /**
+     * Checks the given type optionally annotated with a @Priority. If present the annotation's value is evaluated.
+     * If no such annotation is present, a default priority {@code 1} is returned.
+     *
+     * @param type the type, not {@code null}.
+     * @return a priority, by default 1.
+     */
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public static int getPriority(Class type) {
+        int prio = 1;
+		Priority priority = (Priority)type.getAnnotation(Priority.class);
+        if (priority != null) {
+            prio = priority.value();
+        }
+        return prio;
+    }
+}


Mime
View raw message