tamaya-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anat...@apache.org
Subject [17/21] incubator-tamaya git commit: TAMAYA-113: Remove Java 8 related parts - basic work done.
Date Tue, 29 Sep 2015 07:01:22 GMT
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/main/java/org/apache/tamaya/spi/PropertySource.java
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/main/java/org/apache/tamaya/spi/PropertySource.java b/attic/java8/api/src/main/java/org/apache/tamaya/spi/PropertySource.java
new file mode 100644
index 0000000..b4303a0
--- /dev/null
+++ b/attic/java8/api/src/main/java/org/apache/tamaya/spi/PropertySource.java
@@ -0,0 +1,153 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*   http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied.  See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+package org.apache.tamaya.spi;
+
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * This interface models a provider that serves configuration properties. The contained
+ * properties may be read fromMap single or several sources (composite).<br/>
+ * PropertySources are the building blocks of the final configuration.
+ * <p/>
+ * <h3>Implementation Requirements</h3>
+ * <p></p>Implementations current this interface must be
+ * <ul>
+ * <li>Thread safe.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * <p>A PropertySourceProvider will get picked up via the
+ * {@link java.util.ServiceLoader} mechanism and can be registered via
+ * META-INF/services/org.apache.tamaya.spi.PropertySource
+ * </p>
+ * <p>
+ * If you like to register multiple PropertySources at the same time
+ * you can use the {@link org.apache.tamaya.spi.PropertySourceProvider}
+ * interface.
+ * </p>
+ */
+public interface PropertySource {
+
+    /**
+     * property name to override default tamaya ordinals
+     */
+    static final String TAMAYA_ORDINAL = "tamaya.ordinal";
+
+
+    /**
+     * Lookup order:
+     * TODO rethink whole default PropertySources and ordering:
+     * TODO introduce default values or constants for ordinals
+     * <ol>
+     * <li>System properties (ordinal 400)</li>
+     * <li>Environment properties (ordinal 300)</li>
+     * <li>JNDI values (ordinal 200)</li>
+     * <li>Properties file values (/META-INF/applicationConfiguration.properties) (ordinal 100)</li>
+     * </ol>
+     * <p/>
+     * <p><b>Important Hints for custom implementations</b>:</p>
+     * <p>
+     * If a custom implementation should be invoked <b>before</b> the default implementations, use a value &gt; 400
+     * </p>
+     * <p>
+     * If a custom implementation should be invoked <b>after</b> the default implementations, use a value &lt; 100
+     * </p>
+     * <p/>
+     * <p>Reordering of the default order of the config-sources:</p>
+     * <p>Example: If the properties file/s should be used <b>before</b> the other implementations,
+     * you have to configure an ordinal &gt; 400. That means, you have to add e.g. deltaspike_ordinal=401 to
+     * /META-INF/apache-deltaspike.properties . Hint: In case of property files every file is handled as independent
+     * config-source, but all of them have ordinal 400 by default (and can be reordered in a fine-grained manner.</p>
+     *
+     * @return the 'importance' aka ordinal of the configured values. The higher, the more important.
+     */
+    default int getOrdinal(){
+        String configuredOrdinal = get(TAMAYA_ORDINAL);
+        if(configuredOrdinal!=null){
+            try{
+                return Integer.parseInt(configuredOrdinal);
+            } catch(Exception e){
+                Logger.getLogger(getClass().getName()).log(Level.WARNING, e,
+                        () -> "Configured Ordinal is not an int number: " + configuredOrdinal);
+            }
+        }
+        return getDefaultOrdinal();
+    }
+
+    /**
+     * Returns the  default ordinal used, when no ordinal is set, or the ordinal was not parseable to an int value.
+     * @return the  default ordinal used, by default 0.
+     */
+    default int getDefaultOrdinal(){
+        return 0;
+    }
+
+    /**
+     * Get the name of the property source. The name should be unique for the type of source, whereas multiple instances
+     * of the same type (and thus name) may exist in a system. Give a {@link ConfigurationContext}
+     * the name of a PropertySource is unique.
+     *
+     * @return the property source's name, never null.
+     */
+    String getName();
+
+    /**
+     * Access a property.
+     * <p>
+     * //X TODO discuss if the key can be null
+     *
+     * @param key the property's key, not null.
+     * @return the value assigned to the property or {@code null}. An empty String will kind of 'erase' previous values.
+     */
+    default String get(String key){
+        Objects.requireNonNull(key, "key must not be null");
+        return getProperties().get(key);
+    }
+
+    /**
+     * Access the current properties as Map. The resulting Map may not return all items accessible, e.g.
+     * when the underlying storage does not support iteration of its entries.
+     *
+     * @return the a corresponding map, never null.
+     * //X TODO or should we just do getPropertyKeys()? Think about security (key) vs easier merging (full map)?
+     */
+    Map<String, String> getProperties();
+
+    /**
+     * Determines if this config source could be scanned for its list of properties.
+     * <p>
+     * <p>
+     * PropertySources which are not scannable might not be able to find all the
+     * configured values to provide via {@link #getProperties()}. This can e.g. happen
+     * if the underlying storage doesn't support listing.
+     * </p>
+     *
+     * @return {@code true} if this PropertySource could be scanned for its list of properties,
+     * {@code false} if it should not be scanned.
+     */
+    default boolean isScannable() {
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java b/attic/java8/api/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java
new file mode 100644
index 0000000..81ddcdd
--- /dev/null
+++ b/attic/java8/api/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java
@@ -0,0 +1,43 @@
+/*
+ * 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.spi;
+
+import java.util.Collection;
+
+/**
+ * <p>Implement this interfaces to provide a PropertySource provider which
+ * is able to register multiple PropertySources. This is e.g. needed if
+ * there are multiple property files of a given config file name.</p>
+ * <p>
+ * <p>If a PropertySource like JNDI only exists once, then there is no need
+ * to implement it via the PropertySourceProvider but should directly
+ * expose a {@link PropertySource}.</p>
+ * <p>
+ * <p>A PropertySourceProvider will get picked up via the
+ * {@link java.util.ServiceLoader} mechanism and must get registered via
+ * META-INF/services/org.apache.tamaya.spi.PropertySourceProvider</p>
+ */
+public interface PropertySourceProvider {
+
+    /**
+     * @return For each e.g. property file, we return a single PropertySource
+     * or an empty list if no PropertySource exists.
+     */
+    Collection<PropertySource> getPropertySources();
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java b/attic/java8/api/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
new file mode 100644
index 0000000..3c5fb42
--- /dev/null
+++ b/attic/java8/api/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import java.util.Optional;
+
+/**
+ * Policy that determines how the final value of a configuration entry is evaluated. An instances of this
+ * interface can be registered to get control how multiple PropertySources are combined. This is useful in cases
+ * where the default overriding policy as implemented in {@link #DEFAULT_OVERRIDING_COLLECTOR} is not matching
+ * the need of the current application, e.g. then entries containing multiple values should be combined to new
+ * values instead of overridden.
+ */
+@FunctionalInterface
+public interface PropertyValueCombinationPolicy {
+
+    /**
+     * Default overriding collector, where each existing entry ({@code current} is overridden by a subsequent non-null
+     * entry evaluated by {@code propertySource.get(key)}.
+     */
+    public final PropertyValueCombinationPolicy DEFAULT_OVERRIDING_COLLECTOR =
+        (current, key, propertySource) -> Optional.ofNullable(propertySource.get(key))
+                                                  .filter(s -> !s.isEmpty())
+                                                  .orElse(current);
+
+    /**
+     * Method that is called for each value evaluated by a PropertySource for the given key. This method is called
+     * either when a single key is accessed, e.g. by calling {@code org.apache.tamaya.Configuration.getXXX}, but also
+     * when the full configuration property map is accessed by calling
+     * {@link org.apache.tamaya.Configuration#getProperties()}.
+     *
+     * @param currentValue the current value, including null.
+     *                     The collector should either combine the existing value with value from {@code currentValue}
+     *                     or replace the value in {@code currentValue} with {@code valueRead}, hereby returning the
+     *                     result to be used as new {@code currentValue}.
+     * @param key The current key to be evaluated.
+     * @param propertySource The PropertySource that may return an value for the given key. The PropertySource given
+     *                       may be evaluated for additional meta-data, how the given values are to be combined.
+     *                       Note that the value returned by a PropertySource can be null. In that case
+     *                       {@code currentValue} should be returned in almost all cases.
+     * @return the value to be used for future evaluation.
+     */
+    String collect(String currentValue, String key, PropertySource propertySource);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java b/attic/java8/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java
new file mode 100644
index 0000000..f248503
--- /dev/null
+++ b/attic/java8/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java
@@ -0,0 +1,66 @@
+/*
+ * 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.spi;
+
+import java.util.List;
+
+
+/**
+ * This class models the component that is managing the lifecycle current the
+ * services used by the Configuration API.
+ */
+public interface ServiceContext {
+
+    /**
+     * Get the current {@link ServiceContext}. If necessary the {@link ServiceContext} will be laziliy loaded.
+     *
+     * @return the {@link ServiceContext} to be used.
+     */
+    public static ServiceContext getInstance() {
+        return ServiceContextManager.getServiceContext();
+    }
+
+    /**
+     * @return ordinal of the ServiceContext. The one with the highest ordinal will be taken.
+     */
+    default int ordinal() {
+        return 1;
+    }
+
+    /**
+     * Access a service singleton via its type.
+     * If multiple implementations for the very serviceType exist then
+     * the one with the highest {@link javax.annotation.Priority} will be used.
+     *
+     * @param serviceType the service type.
+     * @return The instance to be used, never {@code null}
+     * @throws org.apache.tamaya.ConfigException if there are multiple service implementations with the maximum priority.
+     */
+    <T> T getService(Class<T> serviceType);
+
+    /**
+     * Access a list current services, given its type. The bootstrap mechanism should
+     * order the instance for precedence, hereby the most significant should be
+     * first in order.
+     *
+     * @param serviceType the service type.
+     * @return The instance to be used, never {@code null}
+     */
+    <T> List<T> getServices(Class<T> serviceType);
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java b/attic/java8/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java
new file mode 100644
index 0000000..bcaca06
--- /dev/null
+++ b/attic/java8/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.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.tamaya.spi;
+
+import org.apache.tamaya.ConfigException;
+
+import java.util.Objects;
+import java.util.ServiceLoader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * This singleton provides access to the services available in the current {@link ServiceContext}. The
+ * behaviour can be adapted, by calling {@link ServiceContextManager#set(ServiceContext)} before accessing any
+ * services.
+ */
+public final class ServiceContextManager {
+
+    /** The logger used. */
+    private static final Logger LOG = Logger.getLogger(ServiceContextManager.class.getName());
+
+    /**
+     * The ServiceProvider used.
+     */
+    private static volatile ServiceContext serviceContextProviderDelegate;
+
+    /**
+     * Private singletons constructor.
+     */
+    private ServiceContextManager() {
+    }
+
+    /**
+     * Load the {@link ServiceContext} to be used.
+     *
+     * @return {@link ServiceContext} to be used for loading the services.
+     */
+    private static ServiceContext loadDefaultServiceProvider() {
+        ServiceContext highestServiceContext = null;
+        try {
+            int highestOrdinal = 0;
+            for (ServiceContext serviceContext : ServiceLoader.load(ServiceContext.class)) {
+                if (serviceContext.ordinal() > highestOrdinal) {
+                    highestServiceContext = serviceContext;
+                    highestOrdinal = serviceContext.ordinal();
+                }
+            }
+        } catch (Exception e) {
+            throw new ConfigException("ServiceContext not loadable", e);
+        }
+        if (highestServiceContext == null) {
+            throw new ConfigException("No ServiceContext found");
+        }
+        LOG.info("Using Service Context of type: " + highestServiceContext.getClass().getName());
+        return highestServiceContext;
+    }
+
+    /**
+     * Replace the current {@link ServiceContext} in use.
+     *
+     * @param serviceContextProvider the new {@link ServiceContext}, not null.
+     */
+    public static ServiceContext set(ServiceContext serviceContextProvider) {
+        ServiceContext currentContext = ServiceContextManager.serviceContextProviderDelegate;
+        Objects.requireNonNull(serviceContextProvider);
+        synchronized (ServiceContextManager.class) {
+            if (ServiceContextManager.serviceContextProviderDelegate == null) {
+                ServiceContextManager.serviceContextProviderDelegate = serviceContextProvider;
+                Logger.getLogger(ServiceContextManager.class.getName())
+                        .log(Level.INFO, "Using ServiceProvider: " + serviceContextProvider.getClass().getName());
+            } else {
+                Logger.getLogger(ServiceContextManager.class.getName())
+                        .log(Level.WARNING, "Replacing ServiceProvider " +
+                                ServiceContextManager.serviceContextProviderDelegate.getClass().getName() +
+                                " with: " + serviceContextProvider.getClass().getName());
+                ServiceContextManager.serviceContextProviderDelegate = serviceContextProvider;
+            }
+        }
+        return currentContext;
+    }
+
+    /**
+     * Ge {@link ServiceContext}. If necessary the {@link ServiceContext} will be laziliy loaded.
+     *
+     * @return the {@link ServiceContext} used.
+     */
+    public static ServiceContext getServiceContext() {
+        if (serviceContextProviderDelegate == null) {
+            synchronized (ServiceContextManager.class) {
+                if (serviceContextProviderDelegate == null) {
+                    serviceContextProviderDelegate = loadDefaultServiceProvider();
+                }
+            }
+        }
+        return serviceContextProviderDelegate;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/test/java/org/apache/tamaya/ConfigExceptionTest.java
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/test/java/org/apache/tamaya/ConfigExceptionTest.java b/attic/java8/api/src/test/java/org/apache/tamaya/ConfigExceptionTest.java
new file mode 100644
index 0000000..e5898cf
--- /dev/null
+++ b/attic/java8/api/src/test/java/org/apache/tamaya/ConfigExceptionTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Tests instantiating {@link org.apache.tamaya.ConfigException}.
+ */
+public class ConfigExceptionTest {
+
+    @Test
+    public void testCreationMessage(){
+        ConfigException ex = new ConfigException("test");
+        assertNull(ex.getCause());
+        assertEquals(ex.getMessage(), "test");
+    }
+
+    @Test
+    public void testCreationMessageThrowable(){
+        Exception e = new IllegalStateException("blabla");
+        ConfigException ex = new ConfigException("test", e);
+        assertTrue(ex.getCause() == e);
+        assertEquals("test", ex.getMessage());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/test/java/org/apache/tamaya/ConfigurationProviderTest.java
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/test/java/org/apache/tamaya/ConfigurationProviderTest.java b/attic/java8/api/src/test/java/org/apache/tamaya/ConfigurationProviderTest.java
new file mode 100644
index 0000000..8870d22
--- /dev/null
+++ b/attic/java8/api/src/test/java/org/apache/tamaya/ConfigurationProviderTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Simple tests for the }@link ConfigurationProvider} singleton class.
+ */
+public class ConfigurationProviderTest {
+
+    @Test
+    public void testGetConfiguration() throws Exception {
+        Configuration cfg = ConfigurationProvider.getConfiguration();
+        assertNotNull(cfg);
+    }
+
+//    @Test
+//    public void testSetConfigurationContext() throws Exception {
+//        ConfigurationContextBuilder builder = ConfigurationProvider.getConfigurationContextBuilder();
+//        ConfigurationContext ctx = builder.build();
+//        ConfigurationContext prevCtx = ConfigurationProvider.getConfigurationContext();
+//        assertNotNull(prevCtx);
+//        ConfigurationProvider.setConfigurationContext(ctx);
+//        assertTrue(ConfigurationProvider.getConfigurationContext() == ctx);
+//        ConfigurationProvider.setConfigurationContext(prevCtx);
+//        assertTrue(ConfigurationProvider.getConfigurationContext() == prevCtx);
+//
+//    }
+//
+//    @Test
+//    public void testIsConfigurationContextSettable() throws Exception {
+//        assertTrue(ConfigurationProvider.isConfigurationContextSettable());
+//    }
+//
+//    @Test
+//    public void testGetConfigurationContextBuilder() throws Exception {
+//        ConfigurationContextBuilder builder = ConfigurationProvider.getConfigurationContextBuilder();
+//        assertNotNull(builder);
+//        assertTrue(builder.build().getPropertyConverters().isEmpty());
+//        assertTrue(builder.build().getPropertyFilters().isEmpty());
+//        assertTrue(builder.build().getPropertySources().isEmpty());
+//
+//    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/test/java/org/apache/tamaya/ConfigurationTest.java
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/test/java/org/apache/tamaya/ConfigurationTest.java b/attic/java8/api/src/test/java/org/apache/tamaya/ConfigurationTest.java
new file mode 100644
index 0000000..8490455
--- /dev/null
+++ b/attic/java8/api/src/test/java/org/apache/tamaya/ConfigurationTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Test class that tests the default methods implemented on {@link org.apache.tamaya.Configuration}. The provided
+ * {@link org.apache.tamaya.TestConfiguration} is implemented with maximal use of the default methods.
+ */
+public class ConfigurationTest {
+
+    @Test
+    public void testget() throws Exception {
+        assertEquals(Boolean.TRUE, ConfigurationProvider.getConfiguration().getOptional("booleanTrue", Boolean.class).get());
+        assertEquals(Boolean.FALSE, ConfigurationProvider.getConfiguration().getOptional("booleanFalse", Boolean.class).get());
+        assertEquals((int) Byte.MAX_VALUE, (int) ConfigurationProvider.getConfiguration().getOptional("byte", Byte.class).get());
+        assertEquals((int) Integer.MAX_VALUE, (int) ConfigurationProvider.getConfiguration().getOptional("int", Integer.class).get());
+        assertEquals((long) Long.MAX_VALUE, (long) ConfigurationProvider.getConfiguration().getOptional("long", Long.class).get());
+        assertEquals((double) Float.MAX_VALUE, (double) ConfigurationProvider.getConfiguration().getOptional("float", Float.class).get(), 0.0d);
+        assertEquals((double) Double.MAX_VALUE, (double) ConfigurationProvider.getConfiguration().getOptional("double", Double.class).get(), 0.0d);
+    }
+
+    @Test
+    public void testGetBoolean() throws Exception {
+        assertTrue(ConfigurationProvider.getConfiguration().getBoolean("booleanTrue").isPresent());
+        assertTrue(ConfigurationProvider.getConfiguration().getBoolean("booleanFalse").isPresent());
+        assertFalse(ConfigurationProvider.getConfiguration().getBoolean("booleanFalse").get());
+        assertTrue(ConfigurationProvider.getConfiguration().getBoolean("booleanTrue").get());
+        assertFalse(ConfigurationProvider.getConfiguration().getBoolean("fooBar").isPresent());
+    }
+
+    @Test
+    public void testGetInteger() throws Exception {
+        assertEquals(Integer.MAX_VALUE, ConfigurationProvider.getConfiguration().getInteger("int").getAsInt());
+    }
+
+    @Test
+    public void testGetLong() throws Exception {
+        assertEquals(Long.MAX_VALUE, ConfigurationProvider.getConfiguration().getLong("long").getAsLong());
+    }
+
+    @Test
+    public void testGetDouble() throws Exception {
+        assertEquals(Double.MAX_VALUE, ConfigurationProvider.getConfiguration().getDouble("double").getAsDouble(), 0.0d);
+    }
+
+    @Test
+    public void testWith() throws Exception {
+        assertEquals(ConfigurationProvider.getConfiguration(), ConfigurationProvider.getConfiguration().with(c -> c));
+    }
+
+    @Test
+    public void testQuery() throws Exception {
+        assertEquals("myFooResult", ConfigurationProvider.getConfiguration().query(c -> "myFooResult"));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/test/java/org/apache/tamaya/TestConfiguration.java
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/test/java/org/apache/tamaya/TestConfiguration.java b/attic/java8/api/src/test/java/org/apache/tamaya/TestConfiguration.java
new file mode 100644
index 0000000..ef7cccf
--- /dev/null
+++ b/attic/java8/api/src/test/java/org/apache/tamaya/TestConfiguration.java
@@ -0,0 +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.tamaya;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Test Configuration class, that is used to testdata the default methods provided by the API.
+ */
+public class TestConfiguration implements Configuration {
+
+    private static final Map<String, String> VALUES;
+
+    static {
+        VALUES = new HashMap<String, String>();
+        VALUES.put("long", String.valueOf(Long.MAX_VALUE));
+        VALUES.put("int", String.valueOf(Integer.MAX_VALUE));
+        VALUES.put("double", String.valueOf(Double.MAX_VALUE));
+        VALUES.put("float", String.valueOf(Float.MAX_VALUE));
+        VALUES.put("short", String.valueOf(Short.MAX_VALUE));
+        VALUES.put("byte", String.valueOf(Byte.MAX_VALUE));
+        VALUES.put("booleanTrue", "true");
+        VALUES.put("booleanFalse", "false");
+        VALUES.put("String", "aStringValue");
+    }
+
+    @Override
+    public String get(String key) {
+        return VALUES.get(key);
+    }
+
+    @Override
+    public <T> T get(String key, TypeLiteral<T> type) {
+        if (type.getType().equals(Long.class)) {
+            return (T) (Object) Long.MAX_VALUE;
+        } else if (type.getType().equals(Integer.class)) {
+            return (T) (Object) Integer.MAX_VALUE;
+        } else if (type.getType().equals(Double.class)) {
+            return (T) (Object) Double.MAX_VALUE;
+        } else if (type.getType().equals(Float.class)) {
+            return (T) (Object) Float.MAX_VALUE;
+        } else if (type.getType().equals(Short.class)) {
+            return (T) (Object) Short.MAX_VALUE;
+        } else if (type.getType().equals(Byte.class)) {
+            return (T) (Object) Byte.MAX_VALUE;
+        } else if (type.getType().equals(Boolean.class)) {
+            if ("booleanTrue".equals(key)) {
+                return (T) (Object) Boolean.TRUE;
+            } else if ("booleanFalse".equals(key)) {
+                return (T) (Object) Boolean.FALSE;
+            }
+        } else if (type.getType().equals(String.class)) {
+            return (T) (Object) "aStringValue";
+        }
+        return null;
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/test/java/org/apache/tamaya/TestConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/test/java/org/apache/tamaya/TestConfigurationProvider.java b/attic/java8/api/src/test/java/org/apache/tamaya/TestConfigurationProvider.java
new file mode 100644
index 0000000..98820ca
--- /dev/null
+++ b/attic/java8/api/src/test/java/org/apache/tamaya/TestConfigurationProvider.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya;
+
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.ConfigurationProviderSpi;
+
+/**
+ * Test Configuration class, that is used to testdata the default methods provided by the API.
+ */
+public class TestConfigurationProvider implements ConfigurationProviderSpi {
+
+    private static final Configuration config = new TestConfiguration();
+
+
+    @Override
+    public Configuration getConfiguration() {
+        return config;
+    }
+
+    @Override
+    public ConfigurationContext getConfigurationContext() {
+        return null;
+    }
+
+    @Override
+    public ConfigurationContextBuilder getConfigurationContextBuilder() {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/test/java/org/apache/tamaya/TypeLiteralTest.java
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/test/java/org/apache/tamaya/TypeLiteralTest.java b/attic/java8/api/src/test/java/org/apache/tamaya/TypeLiteralTest.java
new file mode 100644
index 0000000..79f6257
--- /dev/null
+++ b/attic/java8/api/src/test/java/org/apache/tamaya/TypeLiteralTest.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for the {@link org.apache.tamaya.TypeLiteral} class.
+ */
+public class TypeLiteralTest {
+
+    @Test
+    public void test_constrcutor(){
+        TypeLiteral<List<String>> listTypeLiteral = new TypeLiteral<List<String>>(){};
+        assertEquals(List.class, listTypeLiteral.getRawType());
+        assertEquals(String.class, TypeLiteral.getTypeParameters(listTypeLiteral.getType())[0]);
+    }
+
+    @Test
+    public void test_of(){
+        class MyListClass extends ArrayList<String>{};
+        TypeLiteral<MyListClass> listTypeLiteral = TypeLiteral.of(MyListClass.class);
+        assertEquals(MyListClass.class, listTypeLiteral.getRawType());
+        assertEquals(MyListClass.class, listTypeLiteral.getType());
+    }
+
+    @Test
+    public void test_getTypeParameter(){
+        TypeLiteral<List<String>> listTypeLiteral = new TypeLiteral<List<String>>(){};
+        assertEquals(List.class, listTypeLiteral.getRawType());
+        assertEquals(String.class, TypeLiteral.getTypeParameters(listTypeLiteral.getType())[0]);
+    }
+
+    @Test
+    public void test_getGenericInterfaceTypeParameter(){
+        class MyListClass extends ArrayList<String> implements List<String>{};
+        assertEquals(String.class, TypeLiteral.getGenericInterfaceTypeParameters(MyListClass.class, List.class)[0]);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java b/attic/java8/api/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java
new file mode 100644
index 0000000..949170d
--- /dev/null
+++ b/attic/java8/api/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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.spi;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+import static org.junit.Assert.assertTrue;
+
+public class ServiceContextManagerTest {
+
+    private static URLClassLoader classLoader;
+    private static Field delegateField;
+
+    @BeforeClass
+    public static void init() throws Exception {
+
+        // setup the environment for our ugly hacks
+
+        // replace classloader with our own
+        classLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
+        Thread.currentThread().setContextClassLoader(new UglyHackClassLoader(classLoader));
+
+        // clear the caching field
+        delegateField = ServiceContextManager.class.getDeclaredField("serviceContextProviderDelegate");
+        delegateField.setAccessible(true);
+
+        delegateField.set(null, null);
+    }
+
+    @AfterClass
+    public static void clean() throws Exception {
+
+        // clean our hacks
+
+        delegateField.set(null, null);
+        Thread.currentThread().setContextClassLoader(classLoader);
+    }
+
+    @Test
+    public void testGetServiceContext() {
+
+        ServiceContext context = ServiceContextManager.getServiceContext();
+        Assert.assertEquals(1, context.ordinal());
+
+    }
+
+    @Test
+    public void testSetServiceContext(){
+        ServiceContext ctx = new ServiceContext() {
+            @Override
+            public <T> T getService(Class<T> serviceType) {
+                return null;
+            }
+
+            @Override
+            public <T> List<T> getServices(Class<T> serviceType) {
+                return Collections.emptyList();
+            }
+        };
+        ServiceContext prevContext = ServiceContextManager.set(ctx);
+        if(prevContext!=null) {
+            ServiceContextManager.set(prevContext);
+            assertTrue(ServiceContextManager.getServiceContext() == prevContext);
+        }
+    }
+
+
+    // has to be public because ServiceLoader won't find it otherwise
+    public static class ServiceContextWithOrdinal implements ServiceContext {
+
+        @Override
+        public int ordinal() {
+            return 100;
+        }
+
+        @Override
+        public <T> T getService(Class<T> serviceType) {
+            return null;
+        }
+
+        @Override
+        public <T> List<T> getServices(Class<T> serviceType) {
+            return null;
+        }
+    }
+
+    // to override the getResources method to use our own 'ServiceLoader'-file we have to this ugly hack
+    private static class UglyHackClassLoader extends URLClassLoader {
+
+        private UglyHackClassLoader(URLClassLoader urlClassLoader) {
+            super(urlClassLoader.getURLs());
+        }
+
+
+        @Override
+        public Enumeration<URL> getResources(String name) throws IOException {
+            if ("META-INF/services/org.apache.tamaya.spi.ServiceContext".equals(name)) {
+                return super.getResources("ServiceContextWithOrdinal");
+            }
+
+            return super.getResources(name);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/test/java/org/apache/tamaya/spi/ServiceContextTest.java
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/test/java/org/apache/tamaya/spi/ServiceContextTest.java b/attic/java8/api/src/test/java/org/apache/tamaya/spi/ServiceContextTest.java
new file mode 100644
index 0000000..28d9fac
--- /dev/null
+++ b/attic/java8/api/src/test/java/org/apache/tamaya/spi/ServiceContextTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.spi;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+import static org.junit.Assert.*;
+
+public class ServiceContextTest {
+
+    private ServiceContext serviceContext = new ServiceContext() {
+
+        @Override
+        public <T> T getService(Class<T> serviceType) {
+            if (String.class.equals(serviceType)) {
+                return serviceType.cast("ServiceContextTest");
+            }
+            return null;
+        }
+
+        @Override
+        public <T> List<T> getServices(Class<T> serviceType) {
+            if (String.class.equals(serviceType)) {
+                List<String> list = new ArrayList<>();
+                list.add("ServiceContextTest");
+                return List.class.cast(list);
+            }
+            return Collections.EMPTY_LIST;
+        }
+    };
+
+    @Test
+    public void testOrdinal() throws Exception {
+        assertEquals(1, serviceContext.ordinal());
+    }
+
+    @Test
+    public void testgetService() throws Exception {
+        assertEquals("ServiceContextTest", serviceContext.getService(String.class));
+        assertTrue(serviceContext.getService(Integer.class)==null);
+    }
+
+    @Test
+    public void testGetService() throws Exception {
+        String service = serviceContext.getService(String.class);
+        assertNotNull(service);
+        assertTrue(service!=null);
+        assertEquals("ServiceContextTest", service);
+        Integer intService = serviceContext.getService(Integer.class);
+        assertNull(intService);
+    }
+
+    @Test
+    public void testGetServices() throws Exception {
+        Collection<String> services = serviceContext.getServices(String.class);
+        assertNotNull(services);
+        assertFalse(services.isEmpty());
+        assertEquals("ServiceContextTest", services.iterator().next());
+        List<Integer> intServices = serviceContext.getServices(Integer.class);
+        assertNotNull(intServices);
+        assertTrue(intServices.isEmpty());
+    }
+
+    @Test
+    public void testGetInstance() throws Exception {
+        assertNotNull(ServiceContext.getInstance());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/test/java/org/apache/tamaya/spi/TestServiceContext.java
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/test/java/org/apache/tamaya/spi/TestServiceContext.java b/attic/java8/api/src/test/java/org/apache/tamaya/spi/TestServiceContext.java
new file mode 100644
index 0000000..720a5c4
--- /dev/null
+++ b/attic/java8/api/src/test/java/org/apache/tamaya/spi/TestServiceContext.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.spi;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class implements the (default) {@link org.apache.tamaya.spi.ServiceContext} interface and hereby uses the JDK
+ * {@link java.util.ServiceLoader} to load the services required.
+ */
+public final class TestServiceContext implements ServiceContext {
+    /**
+     * List current services loaded, per class.
+     */
+    private final ConcurrentHashMap<Class<?>, List<Object>> servicesLoaded = new ConcurrentHashMap<>();
+    /**
+     * Singletons.
+     */
+    private final Map<Class<?>, Object> singletons = new ConcurrentHashMap<>();
+
+    @Override
+    public <T> T getService(Class<T> serviceType) {
+        T cached = serviceType.cast(singletons.get(serviceType));
+        if (cached == null) {
+            List<? extends T> services = getServices(serviceType);
+            if (services.isEmpty()) {
+                cached = null;
+            } else {
+                cached = services.get(0);
+            }
+            singletons.put(serviceType, cached);
+        }
+        return cached;
+    }
+
+    /**
+     * Loads and registers services.
+     *
+     * @param serviceType The service type.
+     * @param <T>         the concrete type.
+     * @return the items found, never {@code null}.
+     */
+    @Override
+    public <T> List<T> getServices(Class<T> serviceType) {
+        try {
+            List<T> services = new ArrayList<>();
+            for (T t : ServiceLoader.load(serviceType)) {
+                services.add(t);
+            }
+            services = Collections.unmodifiableList(services);
+            final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>) services));
+            return previousServices != null ? previousServices : services;
+        } catch (Exception e) {
+            Logger.getLogger(TestServiceContext.class.getName()).log(Level.WARNING,
+                    "Error loading services current type " + serviceType, e);
+            return Collections.emptyList();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.ConfigurationProviderSpi
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.ConfigurationProviderSpi b/attic/java8/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.ConfigurationProviderSpi
new file mode 100644
index 0000000..b9c5ba5
--- /dev/null
+++ b/attic/java8/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.ConfigurationProviderSpi
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.tamaya.TestConfigurationProvider

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext b/attic/java8/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
new file mode 100644
index 0000000..199956f
--- /dev/null
+++ b/attic/java8/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.tamaya.spi.TestServiceContext
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/api/src/test/resources/ServiceContextWithOrdinal
----------------------------------------------------------------------
diff --git a/attic/java8/api/src/test/resources/ServiceContextWithOrdinal b/attic/java8/api/src/test/resources/ServiceContextWithOrdinal
new file mode 100644
index 0000000..4112c18
--- /dev/null
+++ b/attic/java8/api/src/test/resources/ServiceContextWithOrdinal
@@ -0,0 +1,25 @@
+# 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.
+
+# this is just an ugly hack to test the loading of ServiceContexts
+# if we have more than one
+
+# this one is without overriding ordinal so it shall take the default
+org.apache.tamaya.spi.TestServiceContext
+
+# this one has a higher ordinal (100)
+org.apache.tamaya.spi.ServiceContextManagerTest$ServiceContextWithOrdinal
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/core/pom.xml
----------------------------------------------------------------------
diff --git a/attic/java8/core/pom.xml b/attic/java8/core/pom.xml
new file mode 100644
index 0000000..08860b6
--- /dev/null
+++ b/attic/java8/core/pom.xml
@@ -0,0 +1,87 @@
+<!-- 
+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-java8</artifactId>
+        <version>0.2-incubating-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>tamaya-core</artifactId>
+    <name>Apache Tamaya Java 8 Core</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-library</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-core</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copyMain</id>
+                        <phase>process-test-classes</phase>
+                        <goals>
+                            <goal>copy</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}</outputDirectory>
+                            <overWriteReleases>false</overWriteReleases>
+                            <overWriteSnapshots>false</overWriteSnapshots>
+                            <overWriteIfNewer>true</overWriteIfNewer>
+                            <stripVersion>true</stripVersion>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>org.jboss.arquillian.daemon</groupId>
+                                    <artifactId>arquillian-daemon-main</artifactId>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
----------------------------------------------------------------------
diff --git a/attic/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java b/attic/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
new file mode 100644
index 0000000..8eaa5cd
--- /dev/null
+++ b/attic/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.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.tamaya.core.internal;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+/**
+ * Implementation of the Configuration API. This class uses the current {@link ConfigurationContext} to evaluate the
+ * chain of {@link org.apache.tamaya.spi.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 maximal number of filter cycles performed before aborting.
+     */
+    private static final int MAX_FILTER_LOOPS = 10;
+
+    /**
+     * The current {@link org.apache.tamaya.spi.ConfigurationContext} of the current instance.
+     */
+    private final ConfigurationContext configurationContext;
+
+    /**
+     * Constructor.
+     * @param configurationContext The configuration Context to be used.
+     */
+    public DefaultConfiguration(ConfigurationContext configurationContext){
+        this.configurationContext = Objects.requireNonNull(configurationContext);
+    }
+
+    /**
+     * This method evaluates the given configuration key. Hereby if goes down the chain or PropertySource instances
+     * provided by the current {@link org.apache.tamaya.spi.ConfigurationContext}. The first non-null-value returned
+     * is taken as an intermediate value. Finally the value is filtered through the
+     * {@link org.apache.tamaya.spi.PropertyFilter} instances installed, before it is returned as the final result of
+     * this method.
+     *
+     * @param key the property's key, not null.
+     * @return the optional configuration value, never null.
+     */
+    @Override
+    public String get(String key) {
+        List<PropertySource> propertySources = configurationContext.getPropertySources();
+        String unfilteredValue = null;
+        PropertyValueCombinationPolicy combinationPolicy = this.configurationContext
+                .getPropertyValueCombinationPolicy();
+        for (PropertySource propertySource : propertySources) {
+                unfilteredValue = combinationPolicy.collect(unfilteredValue, key, propertySource);
+        }
+        return applyFilter(key, unfilteredValue);
+    }
+
+    /**
+     * Apply filters to a single property value.
+     *
+     * @param key             the key, used for logging, not null.
+     * @param unfilteredValue the unfiltered property value.
+     * @return the filtered value, or null.
+     */
+    private String applyFilter(String key, String unfilteredValue) {
+        // Apply filters to values, prevent values filtered to null!
+        for (int i = 0; i < MAX_FILTER_LOOPS; i++) {
+            boolean changed = false;
+            // Apply filters to values, prevent values filtered to null!
+            for (PropertyFilter filter : configurationContext.getPropertyFilters()) {
+                String newValue = filter.filterProperty(key, unfilteredValue);
+                if (newValue != null && !newValue.equals(unfilteredValue)) {
+                    changed = true;
+                    if (LOG.isLoggable(Level.FINEST)) {
+                        LOG.finest("Filter - " + key + ": " + unfilteredValue + " -> " + newValue + " by " + filter);
+                    }
+                } else if (unfilteredValue != null && !unfilteredValue.equals(newValue)) {
+                    changed = true;
+                    if (LOG.isLoggable(Level.FINEST)) {
+                        LOG.finest("Filter - " + key + ": " + unfilteredValue + " -> " + newValue + " by " + filter);
+                    }
+                }
+                unfilteredValue = newValue;
+            }
+            if (!changed) {
+                LOG.finest(() -> "Finishing filter loop, no changes detected.");
+                break;
+            } else {
+                if (i == (MAX_FILTER_LOOPS - 1)) {
+                    if (LOG.isLoggable(Level.WARNING)) {
+                        LOG.warning("Maximal filter loop count reached, aborting filter evaluation after cycles: " + i);
+                    }
+                } else {
+                    LOG.finest(() -> "Repeating filter loop, changes detected.");
+                }
+            }
+        }
+        return unfilteredValue;
+    }
+
+    /**
+     * Get the current properties, composed by the loaded {@link org.apache.tamaya.spi.PropertySource} and filtered
+     * by registered {@link org.apache.tamaya.spi.PropertyFilter}.
+     *
+     * @return the final properties.
+     */
+    @Override
+    public Map<String, String> getProperties() {
+        List<PropertySource> propertySources = new ArrayList<>(configurationContext.getPropertySources());
+        Map<String, String> result = new HashMap<>();
+        for (PropertySource propertySource : propertySources) {
+            try {
+                int origSize = result.size();
+                Map<String, String> otherMap = propertySource.getProperties();
+                LOG.log(Level.FINEST, null, () -> "Overriding with properties from " + propertySource.getName());
+                result.putAll(otherMap);
+                LOG.log(Level.FINEST, null, () -> "Handled properties from " + propertySource.getName() + "(new: " +
+                        (result.size() - origSize) + ", overrides: " + origSize + ", total: " + result.size());
+            } catch (Exception e) {
+                LOG.log(Level.SEVERE, "Error adding properties from PropertySource: " + propertySource + ", ignoring PropertySource.", e);
+            }
+        }
+        return applyFilters(result);
+    }
+
+    /**
+     * Filter a full configuration property map.
+     *
+     * @param inputMap the unfiltered map
+     * @return the filtered map.
+     */
+    private Map<String, String> applyFilters(Map<String, String> inputMap) {
+        // Apply filters to values, prevent values filtered to null!
+        for (int i = 0; i < MAX_FILTER_LOOPS; i++) {
+            AtomicInteger changes = new AtomicInteger();
+            for (PropertyFilter filter : configurationContext.getPropertyFilters()) {
+                inputMap.replaceAll((k, v) -> {
+                    String newValue = filter.filterProperty(k, v);
+                    if (newValue != null && !newValue.equals(v)) {
+                        changes.incrementAndGet();
+                        LOG.finest(() -> "Filter - " + k + ": " + v + " -> " + newValue + " by " + filter);
+                    } else if (v != null && !v.equals(newValue)) {
+                        changes.incrementAndGet();
+                        LOG.finest(() -> "Filter - " + k + ": " + v + " -> " + newValue + " by " + filter);
+                    }
+                    return newValue;
+                });
+            }
+            if (changes.get() == 0) {
+                LOG.finest(() -> "Finishing filter loop, no changes detected.");
+                break;
+            } else {
+                if (i == (MAX_FILTER_LOOPS - 1)) {
+                    if (LOG.isLoggable(Level.WARNING)) {
+                        LOG.warning("Maximal filter loop count reached, aborting filter evaluation after cycles: " + i);
+                    }
+                } else {
+                    LOG.finest(() -> "Repeating filter loop, changes detected: " + changes.get());
+                }
+                changes.set(0);
+            }
+        }
+        // Remove null values
+        return inputMap.entrySet().parallelStream().filter((e) -> e.getValue() != null).collect(
+                Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+    }
+
+    /**
+     * Accesses the current String value for the given key (see {@link #getOptional(String)}) and tries to convert it
+     * using the {@link org.apache.tamaya.spi.PropertyConverter} instances provided by the current
+     * {@link org.apache.tamaya.spi.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) {
+        Optional<String> value = getOptional(key);
+        if (value.isPresent()) {
+            List<PropertyConverter<T>> converters = configurationContext.getPropertyConverters(type);
+            for (PropertyConverter<T> converter : converters) {
+                try {
+                    T t = converter.convert(value.get());
+                    if (t != null) {
+                        return t;
+                    }
+                } catch (Exception e) {
+                    LOG.log(Level.FINEST, e, () -> "PropertyConverter: " + converter +
+                            " failed to convert value: " + value.get());
+                }
+            }
+
+            throw new ConfigException("Unable to convert config value for key " +
+                                      key + " in type " + type.getType());
+        }
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java
----------------------------------------------------------------------
diff --git a/attic/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java b/attic/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java
new file mode 100644
index 0000000..4657a32
--- /dev/null
+++ b/attic/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java
@@ -0,0 +1,240 @@
+/*
+ * 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.internal;
+
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertySourceProvider;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+import org.apache.tamaya.spi.ServiceContext;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import javax.annotation.Priority;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.StringJoiner;
+import java.util.function.Function;
+import java.util.logging.Logger;
+
+/**
+ * Default Implementation of a simple ConfigurationContext.
+ */
+public class DefaultConfigurationContext implements ConfigurationContext {
+    /** The logger used. */
+    private final static Logger LOG = Logger.getLogger(DefaultConfigurationContext.class.getName());
+    /**
+     * Cubcomponent handling {@link org.apache.tamaya.spi.PropertyConverter} instances.
+     */
+    private PropertyConverterManager propertyConverterManager = new PropertyConverterManager();
+
+    /**
+     * The current unmodifiable list of loaded {@link org.apache.tamaya.spi.PropertySource} instances.
+     */
+    private List<PropertySource> immutablePropertySources;
+
+    /**
+     * The current unmodifiable list of loaded {@link org.apache.tamaya.spi.PropertyFilter} instances.
+     */
+    private List<PropertyFilter> immutablePropertyFilters;
+
+    /**
+     * The overriding policy used when combining PropertySources registered to evalute the final configuration
+     * values.
+     */
+    private PropertyValueCombinationPolicy propertyValueCombinationPolicy;
+
+    /**
+     * The first time the Configuration system gets invoked we do initialize
+     * all our {@link org.apache.tamaya.spi.PropertySource}s and
+     * {@link org.apache.tamaya.spi.PropertyFilter}s which are known at startup.
+     */
+    public DefaultConfigurationContext() {
+        List<PropertySource> propertySources = new ArrayList<>();
+
+        // first we load all PropertySources which got registered via java.util.ServiceLoader
+        propertySources.addAll(ServiceContext.getInstance().getServices(PropertySource.class));
+
+        // after that we add all PropertySources which get dynamically registered via their PropertySourceProviders
+        propertySources.addAll(evaluatePropertySourcesFromProviders());
+
+        // now sort them according to their ordinal values
+        Collections.sort(propertySources, this::comparePropertySources);
+        immutablePropertySources = Collections.unmodifiableList(propertySources);
+        LOG.info(() -> "Registered " + immutablePropertySources.size() + " property sources: " +
+                createStringList(immutablePropertySources,ps -> ps.getName() + '[' + ps.getClass().getName()+']'));
+
+        // as next step we pick up the PropertyFilters pretty much the same way
+        List<PropertyFilter> propertyFilters = new ArrayList<>();
+        propertyFilters.addAll(ServiceContext.getInstance().getServices(PropertyFilter.class));
+        Collections.sort(propertyFilters, this::comparePropertyFilters);
+        immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+        LOG.info(() -> "Registered " + immutablePropertyFilters.size() + " property filters: " +
+                createStringList(immutablePropertyFilters,f -> f.getClass().getName()));
+
+        propertyValueCombinationPolicy = ServiceContext.getInstance().getService(PropertyValueCombinationPolicy.class);
+        if(propertyValueCombinationPolicy==null) {
+            propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+        }
+        LOG.info(() -> "Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
+    }
+
+    DefaultConfigurationContext(DefaultConfigurationContextBuilder builder) {
+        List<PropertySource> propertySources = new ArrayList<>();
+        // first we load all PropertySources which got registered via java.util.ServiceLoader
+        propertySources.addAll(builder.propertySources);
+        // now sort them according to their ordinal values
+        Collections.sort(propertySources, this::comparePropertySources);
+        immutablePropertySources = Collections.unmodifiableList(propertySources);
+        LOG.info(() -> "Registered " + immutablePropertySources.size() + " property sources: " +
+                createStringList(immutablePropertySources,ps -> ps.getName() + '[' + ps.getClass().getName()+']'));
+
+        // as next step we pick up the PropertyFilters pretty much the same way
+        List<PropertyFilter> propertyFilters = new ArrayList<>();
+        propertyFilters.addAll(ServiceContext.getInstance().getServices(PropertyFilter.class));
+        Collections.sort(propertyFilters, this::comparePropertyFilters);
+        immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+        LOG.info(() -> "Registered " + immutablePropertyFilters.size() + " property filters: " +
+                createStringList(immutablePropertyFilters,f -> f.getClass().getName()));
+
+        propertyValueCombinationPolicy = ServiceContext.getInstance().getService(PropertyValueCombinationPolicy.class);
+        if(propertyValueCombinationPolicy==null){
+            propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+        }
+        LOG.info(() -> "Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
+    }
+
+    /**
+     * Pick up all {@link org.apache.tamaya.spi.PropertySourceProvider}s and return all the
+     * {@link org.apache.tamaya.spi.PropertySource}s they like to register.
+     */
+    private Collection<? extends PropertySource> evaluatePropertySourcesFromProviders() {
+        List<PropertySource> propertySources = new ArrayList<>();
+        Collection<PropertySourceProvider> propertySourceProviders = ServiceContext.getInstance().getServices(PropertySourceProvider.class);
+        for (PropertySourceProvider propertySourceProvider : propertySourceProviders) {
+            Collection<PropertySource> sources = propertySourceProvider.getPropertySources();
+                LOG.finer(() -> "PropertySourceProvider " + propertySourceProvider.getClass().getName() +
+                        " provided the following property sources: " +
+                        createStringList(sources,ps -> ps.getName() + '[' + ps.getClass().getName()+']'));
+                propertySources.addAll(sources);
+        }
+        return propertySources;
+    }
+
+//    @Override
+//    public void addPropertySources(PropertySource... propertySourcesToAdd) {
+//        Lock writeLock = propertySourceLock.asWriteLock();
+//        try {
+//            writeLock.lock();
+//            List<PropertySource> newPropertySources = new ArrayList<>(this.immutablePropertySources);
+//            newPropertySources.addAll(Arrays.asList(propertySourcesToAdd));
+//            Collections.sort(newPropertySources, this::comparePropertySources);
+//
+//            this.immutablePropertySources = Collections.unmodifiableList(newPropertySources);
+//        } finally {
+//            writeLock.unlock();
+//        }
+//    }
+
+    /**
+     * Order property source reversely, the most important come first.
+     *
+     * @param source1 the first PropertySource
+     * @param source2 the second PropertySource
+     * @return the comparison result.
+     */
+    private int comparePropertySources(PropertySource source1, PropertySource source2) {
+        if (source1.getOrdinal() < source2.getOrdinal()) {
+            return -1;
+        } else if (source1.getOrdinal() > source2.getOrdinal()) {
+            return 1;
+        } else {
+            return source1.getClass().getName().compareTo(source2.getClass().getName());
+        }
+    }
+
+    /**
+     * Compare 2 filters for ordering the filter chain.
+     *
+     * @param filter1 the first filter
+     * @param filter2 the second filter
+     * @return the comparison result
+     */
+    private int comparePropertyFilters(PropertyFilter filter1, PropertyFilter filter2) {
+        Priority prio1 = filter1.getClass().getAnnotation(Priority.class);
+        Priority prio2 = filter2.getClass().getAnnotation(Priority.class);
+        int ord1 = prio1 != null ? prio1.value() : 0;
+        int ord2 = prio2 != null ? prio2.value() : 0;
+
+        if (ord1 < ord2) {
+            return -1;
+        } else if (ord1 > ord2) {
+            return 1;
+        } else {
+            return filter1.getClass().getName().compareTo(filter2.getClass().getName());
+        }
+    }
+
+    @Override
+    public List<PropertySource> getPropertySources() {
+        return immutablePropertySources;
+    }
+
+    @Override
+    public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+        return propertyConverterManager.getPropertyConverters();
+    }
+
+    @Override
+    public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+        return propertyConverterManager.getPropertyConverters(targetType);
+    }
+
+    @Override
+    public List<PropertyFilter> getPropertyFilters() {
+        return immutablePropertyFilters;
+    }
+
+    @Override
+    public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(){
+        return propertyValueCombinationPolicy;
+    }
+
+    @Override
+    public ConfigurationContextBuilder toBuilder() {
+        ServiceContext serviceContext = ServiceContextManager.getServiceContext();
+        ConfigurationContextBuilder service = serviceContext.getService(ConfigurationContextBuilder.class);
+
+        service.setContext(this);
+
+        return service;
+    }
+
+    private <T> String createStringList(Collection<T> propertySources, Function<T,String> mapper){
+        StringJoiner joiner = new StringJoiner(", ");
+        propertySources.forEach(t -> joiner.add(mapper.apply(t)));
+        return joiner.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b6dc2eed/attic/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java
----------------------------------------------------------------------
diff --git a/attic/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java b/attic/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java
new file mode 100644
index 0000000..c181373
--- /dev/null
+++ b/attic/java8/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java
@@ -0,0 +1,145 @@
+/*
+ * 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.internal;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * Default implementation of {@link org.apache.tamaya.spi.ConfigurationContextBuilder}.
+ */
+public class DefaultConfigurationContextBuilder implements ConfigurationContextBuilder {
+
+    List<PropertySource> propertySources = new ArrayList<>();
+    List<PropertyFilter> propertyFilters = new ArrayList<>();
+    Map<TypeLiteral<?>, List<PropertyConverter<?>>> propertyConverters = new HashMap<>();
+    PropertyValueCombinationPolicy combinationPolicy;
+
+    public DefaultConfigurationContextBuilder(){
+    }
+
+    @Override
+    public ConfigurationContextBuilder setContext(ConfigurationContext context) {
+        this.propertySources.clear();
+        this.propertySources.addAll(context.getPropertySources());
+        this.propertyFilters.clear();
+        this.propertyFilters.addAll(context.getPropertyFilters());
+        this.propertyConverters.clear();
+        this.propertyConverters.putAll(context.getPropertyConverters());
+        this.combinationPolicy = context.getPropertyValueCombinationPolicy();
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder addPropertySources(Collection<PropertySource> propertySourcesToAdd) {
+        Set<String> names = this.propertySources.stream().map(ps -> ps.getName()).collect(Collectors.toSet());
+        for(PropertySource ps:propertySourcesToAdd){
+            if(names.contains(ps.getName())){
+                throw new ConfigException("Duplicate PropertySource: " + ps.getName());
+            }
+        }
+        this.propertySources.addAll(propertySourcesToAdd);
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertySources(Collection<String> propertySourcesToRemove) {
+        this.propertySources = this.propertySources.stream().filter(ps -> !propertySourcesToRemove
+                .contains(ps.getName())).collect(Collectors.toList());
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder addPropertyFilters(Collection<PropertyFilter> filters) {
+        this.propertyFilters.addAll(filters);
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertyFilters(Predicate<PropertyFilter> selector) {
+        Collection<PropertyFilter> filtersToRemove = this.propertyFilters.stream().filter(selector)
+                .collect(Collectors.toList());
+        this.propertyFilters.removeAll(filtersToRemove);
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertyFilters(Collection<PropertyFilter> filters) {
+        this.propertyFilters.removeAll(filters);
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertySources(Predicate<PropertySource> selector) {
+        Collection<PropertySource> sourcesToRemove = this.propertySources.stream().filter(selector)
+                .collect(Collectors.toList());
+        this.propertySources.removeAll(sourcesToRemove);
+        return this;
+    }
+
+    @Override
+    public <T> ConfigurationContextBuilder addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+        List<PropertyConverter<?>> converters = this.propertyConverters.computeIfAbsent(typeToConvert, (k) -> new ArrayList<>());
+        converters.add(propertyConverter);
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert, PropertyConverter<?>... converters) {
+        return removePropertyConverters(typeToConvert, Arrays.asList(converters));
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert, Collection<PropertyConverter<?>> converters) {
+        List<PropertyConverter<?>> existing = this.propertyConverters.get(typeToConvert);
+        if(existing!=null) {
+            existing.removeAll(converters);
+        }
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy) {
+        this.combinationPolicy = Objects.requireNonNull(policy);
+        return this;
+    }
+
+    @Override
+    public ConfigurationContext build() {
+        return new DefaultConfigurationContext(this);
+    }
+
+}



Mime
View raw message