tamaya-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ple...@apache.org
Subject [8/8] incubator-tamaya git commit: Moved module core to ./code/
Date Sun, 20 Dec 2015 13:05:55 GMT
Moved module core to ./code/


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

Branch: refs/heads/master
Commit: eadbfe97395bded760b9492297f31b6421ce2a0f
Parents: 84d52f1
Author: Oliver B. Fischer <plexus@apache.org>
Authored: Sun Dec 20 14:05:42 2015 +0100
Committer: Oliver B. Fischer <plexus@apache.org>
Committed: Sun Dec 20 14:05:42 2015 +0100

----------------------------------------------------------------------
 code/core/pom.xml                               | 103 +++++
 .../core/internal/DefaultConfiguration.java     | 197 ++++++++
 .../internal/DefaultConfigurationContext.java   | 278 ++++++++++++
 .../DefaultConfigurationContextBuilder.java     | 153 +++++++
 .../internal/DefaultConfigurationProvider.java  |  68 +++
 .../core/internal/DefaultServiceContext.java    | 156 +++++++
 .../tamaya/core/internal/OSGIActivator.java     |  53 +++
 .../core/internal/OSGIServiceComparator.java    |  69 +++
 .../core/internal/OSGIServiceContext.java       |  83 ++++
 .../tamaya/core/internal/OSGIServiceLoader.java | 158 +++++++
 .../internal/PriorityServiceComparator.java     |  67 +++
 .../core/internal/PropertyConverterManager.java | 448 +++++++++++++++++++
 .../core/internal/PropertyFilterComparator.java |  60 +++
 .../tamaya/core/internal/PropertyFiltering.java | 131 ++++++
 .../core/internal/PropertySourceComparator.java |  54 +++
 .../tamaya/core/internal/ReflectionUtil.java    |  42 ++
 .../converters/BigDecimalConverter.java         |  63 +++
 .../converters/BigIntegerConverter.java         |  94 ++++
 .../internal/converters/BooleanConverter.java   |  57 +++
 .../core/internal/converters/ByteConverter.java |  71 +++
 .../core/internal/converters/CharConverter.java |  69 +++
 .../internal/converters/ClassConverter.java     |  63 +++
 .../internal/converters/CurrencyConverter.java  |  89 ++++
 .../internal/converters/DoubleConverter.java    |  81 ++++
 .../core/internal/converters/EnumConverter.java |  68 +++
 .../internal/converters/FloatConverter.java     |  81 ++++
 .../internal/converters/IntegerConverter.java   |  74 +++
 .../core/internal/converters/LongConverter.java |  72 +++
 .../internal/converters/NumberConverter.java    |  72 +++
 .../internal/converters/ShortConverter.java     |  72 +++
 .../core/internal/converters/URIConverter.java  |  47 ++
 .../core/internal/converters/URLConverter.java  |  47 ++
 .../core/propertysource/BasePropertySource.java |  85 ++++
 .../EnvironmentPropertySource.java              |  64 +++
 .../propertysource/SimplePropertySource.java    | 128 ++++++
 .../propertysource/SystemPropertySource.java    |  93 ++++
 .../provider/JavaConfigurationProvider.java     |  61 +++
 .../services/org.apache.tamaya.Configuration    |  19 +
 ...pache.tamaya.spi.ConfigurationContextBuilder |  19 +
 ...g.apache.tamaya.spi.ConfigurationProviderSpi |  19 +
 .../org.apache.tamaya.spi.PropertyConverter     |  33 ++
 .../org.apache.tamaya.spi.PropertySource        |  20 +
 ...org.apache.tamaya.spi.PropertySourceProvider |  19 +
 .../org.apache.tamaya.spi.ServiceContext        |  19 +
 .../apache/tamaya/core/ConfigurationTest.java   |  67 +++
 .../java/org/apache/tamaya/core/internal/A.java |  29 ++
 .../java/org/apache/tamaya/core/internal/B.java |  29 ++
 .../java/org/apache/tamaya/core/internal/C.java |  56 +++
 .../tamaya/core/internal/CTestConverter.java    |  32 ++
 .../internal/DefaultServiceContextTest.java     | 140 ++++++
 .../internal/PropertyConverterManagerTest.java  | 179 ++++++++
 .../converters/BigDecimalConverterTest.java     | 103 +++++
 .../converters/BooleanConverterTest.java        | 108 +++++
 .../internal/converters/ByteConverterTest.java  |  81 ++++
 .../internal/converters/CharConverterTest.java  |  86 ++++
 .../ConverterTestsPropertySource.java           | 252 +++++++++++
 .../converters/CurrencyConverterTest.java       | 154 +++++++
 .../converters/DoubleConverterTest.java         | 175 ++++++++
 .../internal/converters/EnumConverterTest.java  |  60 +++
 .../internal/converters/FloatConverterTest.java | 176 ++++++++
 .../converters/IntegerConverterTest.java        | 111 +++++
 .../internal/converters/LongConverterTest.java  | 111 +++++
 .../converters/NumberConverterTest.java         | 103 +++++
 .../internal/converters/ShortConverterTest.java | 111 +++++
 .../propertysource/BasePropertySourceTest.java  | 104 +++++
 .../EnvironmentPropertySourceTest.java          |  62 +++
 .../PropertiesFilePropertySourceTest.java       |  58 +++
 .../SystemPropertySourceTest.java               |  99 ++++
 .../provider/JavaConfigurationProviderTest.java |  60 +++
 .../testdata/TestPropertyDefaultSource.java     |  56 +++
 .../core/testdata/TestPropertyFilter.java       |  37 ++
 .../testdata/TestPropertySourceProvider.java    |  78 ++++
 .../testdata/TestRemovingPropertyFilter.java    |  41 ++
 .../META-INF/javaconfiguration.properties       |  22 +
 ...tServiceContextTest$InvalidPriorityInterface |  18 +
 ...efaultServiceContextTest$MultiImplsInterface |  20 +
 .../org.apache.tamaya.spi.PropertyConverter     |  19 +
 .../org.apache.tamaya.spi.PropertyFilter        |  20 +
 .../org.apache.tamaya.spi.PropertySource        |  22 +
 ...org.apache.tamaya.spi.PropertySourceProvider |  20 +
 .../test/resources/overrideOrdinal.properties   |  25 ++
 .../core/src/test/resources/testfile.properties |  22 +
 code/core/src/test/resources/x34.properties     |  19 +
 code/pom.xml                                    |   1 +
 core/pom.xml                                    | 103 -----
 .../core/internal/DefaultConfiguration.java     | 197 --------
 .../internal/DefaultConfigurationContext.java   | 278 ------------
 .../DefaultConfigurationContextBuilder.java     | 153 -------
 .../internal/DefaultConfigurationProvider.java  |  68 ---
 .../core/internal/DefaultServiceContext.java    | 156 -------
 .../tamaya/core/internal/OSGIActivator.java     |  53 ---
 .../core/internal/OSGIServiceComparator.java    |  69 ---
 .../core/internal/OSGIServiceContext.java       |  83 ----
 .../tamaya/core/internal/OSGIServiceLoader.java | 158 -------
 .../internal/PriorityServiceComparator.java     |  67 ---
 .../core/internal/PropertyConverterManager.java | 448 -------------------
 .../core/internal/PropertyFilterComparator.java |  60 ---
 .../tamaya/core/internal/PropertyFiltering.java | 131 ------
 .../core/internal/PropertySourceComparator.java |  54 ---
 .../tamaya/core/internal/ReflectionUtil.java    |  42 --
 .../converters/BigDecimalConverter.java         |  63 ---
 .../converters/BigIntegerConverter.java         |  94 ----
 .../internal/converters/BooleanConverter.java   |  57 ---
 .../core/internal/converters/ByteConverter.java |  71 ---
 .../core/internal/converters/CharConverter.java |  69 ---
 .../internal/converters/ClassConverter.java     |  63 ---
 .../internal/converters/CurrencyConverter.java  |  89 ----
 .../internal/converters/DoubleConverter.java    |  81 ----
 .../core/internal/converters/EnumConverter.java |  68 ---
 .../internal/converters/FloatConverter.java     |  81 ----
 .../internal/converters/IntegerConverter.java   |  74 ---
 .../core/internal/converters/LongConverter.java |  72 ---
 .../internal/converters/NumberConverter.java    |  72 ---
 .../internal/converters/ShortConverter.java     |  72 ---
 .../core/internal/converters/URIConverter.java  |  47 --
 .../core/internal/converters/URLConverter.java  |  47 --
 .../core/propertysource/BasePropertySource.java |  85 ----
 .../EnvironmentPropertySource.java              |  64 ---
 .../propertysource/SimplePropertySource.java    | 128 ------
 .../propertysource/SystemPropertySource.java    |  93 ----
 .../provider/JavaConfigurationProvider.java     |  61 ---
 .../services/org.apache.tamaya.Configuration    |  19 -
 ...pache.tamaya.spi.ConfigurationContextBuilder |  19 -
 ...g.apache.tamaya.spi.ConfigurationProviderSpi |  19 -
 .../org.apache.tamaya.spi.PropertyConverter     |  33 --
 .../org.apache.tamaya.spi.PropertySource        |  20 -
 ...org.apache.tamaya.spi.PropertySourceProvider |  19 -
 .../org.apache.tamaya.spi.ServiceContext        |  19 -
 .../apache/tamaya/core/ConfigurationTest.java   |  67 ---
 .../java/org/apache/tamaya/core/internal/A.java |  29 --
 .../java/org/apache/tamaya/core/internal/B.java |  29 --
 .../java/org/apache/tamaya/core/internal/C.java |  56 ---
 .../tamaya/core/internal/CTestConverter.java    |  32 --
 .../internal/DefaultServiceContextTest.java     | 140 ------
 .../internal/PropertyConverterManagerTest.java  | 179 --------
 .../converters/BigDecimalConverterTest.java     | 103 -----
 .../converters/BooleanConverterTest.java        | 108 -----
 .../internal/converters/ByteConverterTest.java  |  81 ----
 .../internal/converters/CharConverterTest.java  |  86 ----
 .../ConverterTestsPropertySource.java           | 252 -----------
 .../converters/CurrencyConverterTest.java       | 154 -------
 .../converters/DoubleConverterTest.java         | 175 --------
 .../internal/converters/EnumConverterTest.java  |  60 ---
 .../internal/converters/FloatConverterTest.java | 176 --------
 .../converters/IntegerConverterTest.java        | 111 -----
 .../internal/converters/LongConverterTest.java  | 111 -----
 .../converters/NumberConverterTest.java         | 103 -----
 .../internal/converters/ShortConverterTest.java | 111 -----
 .../propertysource/BasePropertySourceTest.java  | 104 -----
 .../EnvironmentPropertySourceTest.java          |  62 ---
 .../PropertiesFilePropertySourceTest.java       |  58 ---
 .../SystemPropertySourceTest.java               |  99 ----
 .../provider/JavaConfigurationProviderTest.java |  60 ---
 .../testdata/TestPropertyDefaultSource.java     |  56 ---
 .../core/testdata/TestPropertyFilter.java       |  37 --
 .../testdata/TestPropertySourceProvider.java    |  78 ----
 .../testdata/TestRemovingPropertyFilter.java    |  41 --
 .../META-INF/javaconfiguration.properties       |  22 -
 ...tServiceContextTest$InvalidPriorityInterface |  18 -
 ...efaultServiceContextTest$MultiImplsInterface |  20 -
 .../org.apache.tamaya.spi.PropertyConverter     |  19 -
 .../org.apache.tamaya.spi.PropertyFilter        |  20 -
 .../org.apache.tamaya.spi.PropertySource        |  22 -
 ...org.apache.tamaya.spi.PropertySourceProvider |  20 -
 .../test/resources/overrideOrdinal.properties   |  25 --
 core/src/test/resources/testfile.properties     |  22 -
 core/src/test/resources/x34.properties          |  19 -
 pom.xml                                         |   1 -
 168 files changed, 6785 insertions(+), 6785 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/eadbfe97/code/core/pom.xml
----------------------------------------------------------------------
diff --git a/code/core/pom.xml b/code/core/pom.xml
new file mode 100644
index 0000000..3088bd6
--- /dev/null
+++ b/code/core/pom.xml
@@ -0,0 +1,103 @@
+<!-- 
+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>code</artifactId>
+        <version>0.2-incubating-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>tamaya-core</artifactId>
+    <name>Apache Tamaya Core Implementation</name>
+    <packaging>bundle</packaging>
+
+    <properties>
+        <osgi.compendium.version>5.0.0</osgi.compendium.version>
+     </properties>
+
+    <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.hamcrest</groupId>
+            <artifactId>hamcrest-library</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+            <version>${osgi.compendium.version}</version>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>${osgi.version}</version>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Import-Package>
+                            org.apache.tamaya,
+                            org.apache.tamaya.spi,
+                            javax.annotation,
+                            *
+                        </Import-Package>
+                        <Private-Package>
+                            org.apache.tamaya.core.internal,
+                            org.apache.tamaya.core.internal.converters
+                        </Private-Package>
+                        <Export-Package>
+                            org.apache.tamaya.core,
+                            org.apache.tamaya.core.propertysource,
+                            org.apache.tamaya.core.provider
+                        </Export-Package>
+                        <Bundle-Activator>
+                            org.apache.tamaya.core.internal.OSGIActivator
+                        </Bundle-Activator>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/eadbfe97/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
new file mode 100644
index 0000000..f7c363c
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
@@ -0,0 +1,197 @@
+/*
+ * 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.ConfigOperator;
+import org.apache.tamaya.ConfigQuery;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.*;
+
+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 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;
+
+
+    /**
+     * Constructor.
+     * @param configurationContext The configuration Context to be used.
+     */
+    public DefaultConfiguration(ConfigurationContext configurationContext){
+        this.configurationContext = Objects.requireNonNull(configurationContext);
+    }
+
+
+    public String get(String key) {
+        return PropertyFiltering.applyFilter(key, evaluteRawValue(key), configurationContext);
+    }
+
+    protected String evaluteRawValue(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 unfilteredValue;
+    }
+
+
+    @Override
+    public String getOrDefault(String key, String defaultValue) {
+        String val = get(key);
+        if(val==null){
+            return defaultValue;
+        }
+        return val;
+    }
+
+    @Override
+    public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
+        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 PropertyFilter}.
+     *
+     * @return the final properties.
+     */
+    @Override
+    public Map<String, String> getProperties() {
+        return PropertyFiltering.applyFilters(evaluateUnfilteredMap(), configurationContext);
+    }
+
+    protected Map<String, String> evaluateUnfilteredMap() {
+        List<PropertySource> propertySources = new ArrayList<>(configurationContext.getPropertySources());
+        Collections.reverse(propertySources);
+        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 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}.
+     * @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, 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) {
+        return convertValue(key, get(key), type);
+    }
+
+    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, 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);
+                }
+            }
+            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) {
+        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);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/eadbfe97/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java
new file mode 100644
index 0000000..ac68a73
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java
@@ -0,0 +1,278 @@
+/*
+ * 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.ConfigurationProvider;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.PropertyConverter;
+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.ServiceContextManager;
+
+import javax.annotation.Priority;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+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;
+
+    /**
+     * Lock for internal synchronization.
+     */
+    private final ReentrantReadWriteLock propertySourceLock = new ReentrantReadWriteLock();
+
+    /** Comparator used for ordering property sources. */
+    private final PropertySourceComparator propertySourceComparator = new PropertySourceComparator();
+
+    /** Comparator used for ordering property filters. */
+    private final PropertyFilterComparator propertyFilterComparator = new PropertyFilterComparator();
+
+
+    /**
+     * 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(ServiceContextManager.getServiceContext().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, new PropertySourceComparator());
+
+        immutablePropertySources = Collections.unmodifiableList(propertySources);
+        LOG.info("Registered " + immutablePropertySources.size() + " property sources: " +
+                immutablePropertySources);
+
+        // as next step we pick up the PropertyFilters pretty much the same way
+        List<PropertyFilter> propertyFilters = new ArrayList<>();
+        propertyFilters.addAll(ServiceContextManager.getServiceContext().getServices(PropertyFilter.class));
+        Collections.sort(propertyFilters, new PropertyFilterComparator());
+        immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+        LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
+                immutablePropertyFilters);
+
+        immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+        LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
+                immutablePropertyFilters);
+        propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().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.values());
+        // now sort them according to their ordinal values
+        Collections.sort(propertySources, propertySourceComparator);
+        immutablePropertySources = Collections.unmodifiableList(propertySources);
+        LOG.info("Registered " + immutablePropertySources.size() + " property sources: " +
+                immutablePropertySources);
+
+        // as next step we pick up the PropertyFilters pretty much the same way
+        List<PropertyFilter> propertyFilters = new ArrayList<>();
+        propertyFilters.addAll(ServiceContextManager.getServiceContext().getServices(PropertyFilter.class));
+        Collections.sort(propertyFilters, propertyFilterComparator);
+        immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+        LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
+                immutablePropertyFilters);
+
+        propertyValueCombinationPolicy = builder.combinationPolicy;
+        if(propertyValueCombinationPolicy==null){
+            propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().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 = ServiceContextManager.getServiceContext().getServices(PropertySourceProvider.class);
+        for (PropertySourceProvider propertySourceProvider : propertySourceProviders) {
+            Collection<PropertySource> sources = propertySourceProvider.getPropertySources();
+            LOG.finer("PropertySourceProvider " + propertySourceProvider.getClass().getName() +
+                    " provided the following property sources: " + sources);
+                propertySources.addAll(sources);
+        }
+
+        return propertySources;
+    }
+
+    @Override
+    public void addPropertySources(PropertySource... propertySourcesToAdd) {
+        Lock writeLock = propertySourceLock.writeLock();
+        try {
+            writeLock.lock();
+            List<PropertySource> newPropertySources = new ArrayList<>(this.immutablePropertySources);
+            newPropertySources.addAll(Arrays.asList(propertySourcesToAdd));
+            Collections.sort(newPropertySources, new PropertySourceComparator());
+
+            this.immutablePropertySources = Collections.unmodifiableList(newPropertySources);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    private static class PropertySourceComparator implements Comparator<PropertySource>, Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        /**
+         * 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());
+            }
+        }
+
+        @Override
+        public int compare(PropertySource source1, PropertySource source2) {
+            return comparePropertySources(source1, source2);
+        }
+    }
+
+    private static class PropertyFilterComparator implements Comparator<PropertyFilter>, Serializable{
+
+        private static final long serialVersionUID = 1L;
+
+        /**
+         * 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 int compare(PropertyFilter filter1, PropertyFilter filter2) {
+            return comparePropertyFilters(filter1, filter2);
+        }
+    }
+
+    @Override
+    public List<PropertySource> getPropertySources() {
+        return immutablePropertySources;
+    }
+
+    @Override
+    public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+        propertyConverterManager.register(typeToConvert, propertyConverter);
+        LOG.info("Added PropertyConverter: " + propertyConverter.getClass().getName());
+    }
+
+    @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() {
+        return ConfigurationProvider.getConfigurationContextBuilder().setContext(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/eadbfe97/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java
new file mode 100644
index 0000000..2c44689
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.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.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;
+
+/**
+ * Default implementation of {@link org.apache.tamaya.spi.ConfigurationContextBuilder}.
+ */
+public class DefaultConfigurationContextBuilder implements ConfigurationContextBuilder {
+
+    Map<String, PropertySource> propertySources = new HashMap<>();
+    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();
+        for(PropertySource ps:context.getPropertySources()) {
+            this.propertySources.put(ps.getName(), ps);
+        }
+        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) {
+        for(PropertySource ps:propertySourcesToAdd){
+            if(this.propertySources.containsKey(ps.getName())){
+                throw new ConfigException("Duplicate PropertySource: " + ps.getName());
+            }
+        }
+        for(PropertySource ps:propertySourcesToAdd) {
+            this.propertySources.put(ps.getName(), ps);
+        }
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder addPropertySources(PropertySource... propertySourcesToAdd) {
+        return addPropertySources(Arrays.asList(propertySourcesToAdd));
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertySources(Collection<String> propertySourcesToRemove) {
+        for(String key: propertySourcesToRemove){
+            this.propertySources.remove(key);
+        }
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertySources(String... propertySourcesToRemove) {
+        return removePropertySources(Arrays.asList(propertySourcesToRemove));
+    }
+
+    @Override
+    public ConfigurationContextBuilder addPropertyFilters(Collection<PropertyFilter> filters) {
+        this.propertyFilters.addAll(filters);
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder addPropertyFilters(PropertyFilter... filters) {
+        return addPropertyFilters(Arrays.asList(filters));
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertyFilters(Collection<PropertyFilter> filters) {
+        this.propertyFilters.removeAll(filters);
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertyFilters(PropertyFilter... filters) {
+        return removePropertyFilters(Arrays.asList(filters));
+    }
+
+    @Override
+    public <T> ConfigurationContextBuilder addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+        List<PropertyConverter<?>> converters = this.propertyConverters.get(typeToConvert);
+        if(converters==null){
+            converters =  new ArrayList<>();
+            this.propertyConverters.put(typeToConvert, converters);
+        }
+        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);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/eadbfe97/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationProvider.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationProvider.java
new file mode 100644
index 0000000..2dc15bd
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationProvider.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.ConfigurationProviderSpi;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+/**
+ * Implementation of the Configuration API. This class uses the current {@link org.apache.tamaya.spi.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 DefaultConfigurationProvider implements ConfigurationProviderSpi {
+
+    private ConfigurationContext context = new DefaultConfigurationContext();
+    private Configuration config = new DefaultConfiguration(context);
+
+    @Override
+    public Configuration getConfiguration() {
+        return config;
+    }
+
+    @Override
+    public ConfigurationContext getConfigurationContext() {
+        return context;
+    }
+
+    @Override
+    public ConfigurationContextBuilder getConfigurationContextBuilder() {
+        ConfigurationContextBuilder contextBuilder =
+             ServiceContextManager.getServiceContext().getService(ConfigurationContextBuilder.class);
+
+        return contextBuilder;
+    }
+
+    @Override
+    public void setConfigurationContext(ConfigurationContext context){
+        // TODO think on a SPI or move event part into API...
+        this.config = new DefaultConfiguration(context);
+        this.context = context;
+    }
+
+
+    @Override
+    public boolean isConfigurationContextSettable() {
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/eadbfe97/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java
new file mode 100644
index 0000000..9738b76
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultServiceContext.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.ServiceContext;
+
+import javax.annotation.Priority;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+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 DefaultServiceContext 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) {
+        Object cached = singletons.get(serviceType);
+        if (cached == null) {
+            Collection<T> services = getServices(serviceType);
+            if (services.isEmpty()) {
+                cached = null;
+            } else {
+                cached = getServiceWithHighestPriority(services, serviceType);
+            }
+            if(cached!=null) {
+                singletons.put(serviceType, cached);
+            }
+        }
+        return serviceType.cast(cached);
+    }
+
+    /**
+     * 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) {
+        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);
+            }
+            services = Collections.unmodifiableList(services);
+        } catch (Exception e) {
+            Logger.getLogger(DefaultServiceContext.class.getName()).log(Level.WARNING,
+                    "Error loading services current type " + serviceType, e);
+        }
+        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 s evaluated. If no such
+     * annotation is present, a default priority is returned (1);
+     * @param o the instance, not 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 javax.annotation.Priority#value()}
+     *
+     * @throws ConfigException if there are multiple service implementations with the maximum priority
+     */
+    private <T> T getServiceWithHighestPriority(Collection<T> services, Class<T> serviceType) {
+
+        // we do not need the priority stuff if the list contains only one element
+        if (services.size() == 1) {
+            return services.iterator().next();
+        }
+
+        Integer highestPriority = null;
+        int highestPriorityServiceCount = 0;
+        T highestService = null;
+
+        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));
+        }
+
+        return highestService;
+    }
+
+    @Override
+    public int ordinal() {
+        return 1;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/eadbfe97/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIActivator.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIActivator.java b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIActivator.java
new file mode 100644
index 0000000..8a54d35
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIActivator.java
@@ -0,0 +1,53 @@
+/*
+ * 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.spi.ServiceContextManager;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+import java.util.logging.Logger;
+
+/**
+ * A bundle activator that registers the {@link OSGIServiceLoader}.
+ */
+public class OSGIActivator implements BundleActivator {
+
+    private static final Logger LOG = Logger.getLogger(OSGIActivator.class.getName());
+
+    private OSGIServiceLoader serviceLoader;
+
+    @Override
+    public void start(BundleContext context) {
+        // Register marker service
+        ServiceContextManager.set(new OSGIServiceContext(context));
+        LOG.info("Registered OSGI enabled ServiceContext...");
+        serviceLoader = new OSGIServiceLoader();
+        context.addBundleListener(serviceLoader);
+    }
+
+    @Override
+    public void stop(BundleContext context) {
+        if(serviceLoader!=null) {
+            context.removeBundleListener(serviceLoader);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/eadbfe97/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceComparator.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceComparator.java b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceComparator.java
new file mode 100644
index 0000000..bfc34bc
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceComparator.java
@@ -0,0 +1,69 @@
+/*
+ * 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.osgi.framework.ServiceReference;
+
+import javax.annotation.Priority;
+import java.util.Comparator;
+
+/**
+ * Comparator implementation for odering services loaded based on their increasing priority values.
+ */
+class OSGIServiceComparator implements Comparator<ServiceReference> {
+
+    @Override
+    public int compare(ServiceReference o1, ServiceReference o2) {
+        int prio = getPriority(o1) - getPriority(o2);
+        if (prio < 0) {
+            return 1;
+        } else if (prio > 0) {
+            return -1;
+        } else {
+            return 0; //o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
+        }
+    }
+
+    /**
+     * Checks the given instance for a @Priority annotation. If present the annotation's value s evaluated. If no such
+     * annotation is present, a default priority is returned (1);
+     *
+     * @param o the instance, not 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 s evaluated.
+     * If no such annotation is present, a default priority is returned (1);
+     *
+     * @param type the type, not null.
+     * @return a priority, by default 1.
+     */
+    public static int getPriority(Class type) {
+        int prio = 1;
+        Priority priority = (Priority)type.getAnnotation(Priority.class);
+        if (priority != null) {
+            prio = priority.value();
+        }
+        return prio;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/eadbfe97/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceContext.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceContext.java b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceContext.java
new file mode 100644
index 0000000..083cd54
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceContext.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.core.internal;
+
+import org.apache.tamaya.spi.ServiceContext;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * ServiceContext implementation based on OSGI Service mechanisms.
+ */
+public class OSGIServiceContext implements ServiceContext{
+
+    private static final OSGIServiceComparator REF_COMPARATOR = new OSGIServiceComparator();
+
+    private BundleContext bundleContext;
+
+    public OSGIServiceContext(BundleContext bundleContext){
+        this.bundleContext = Objects.requireNonNull(bundleContext);
+    }
+
+    public boolean isInitialized(){
+        return bundleContext != null;
+    }
+
+
+    @Override
+    public int ordinal() {
+        return 10;
+    }
+
+    @Override
+    public <T> T getService(Class<T> serviceType) {
+        ServiceReference<T> ref = this.bundleContext.getServiceReference(serviceType);
+        if(ref!=null){
+            return this.bundleContext.getService(ref);
+        }
+        return null;
+    }
+
+    @Override
+    public <T> List<T> getServices(Class<T> serviceType) {
+        List<ServiceReference<T>> refs = new ArrayList<>();
+        try {
+            refs.addAll(this.bundleContext.getServiceReferences(serviceType, null));
+            Collections.sort(refs, REF_COMPARATOR);
+            List<T> services = new ArrayList<>(refs.size());
+            for(ServiceReference<T> ref:refs){
+                T service = bundleContext.getService(ref);
+                if(service!=null) {
+                    services.add(service);
+                }
+            }
+            return services;
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+            return Collections.emptyList();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/eadbfe97/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceLoader.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceLoader.java b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceLoader.java
new file mode 100644
index 0000000..dcc702f
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/OSGIServiceLoader.java
@@ -0,0 +1,158 @@
+/*
+ * 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 java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.ConcurrentModificationException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * An bundle listener that registers services defined in META-INF/services, when a bundle is starting.
+ *
+ * @author anatole@apache.org
+ */
+public class OSGIServiceLoader implements BundleListener {
+    // Provide logging
+    private static final Logger log = Logger.getLogger(OSGIServiceLoader.class.getName());
+
+    private Map<Class, ServiceTracker<Object,Object>> services = new ConcurrentHashMap<>();
+
+    @Override
+    public void bundleChanged(BundleEvent bundleEvent) {
+        // Parse and create metadta on STARTING
+        if (bundleEvent.getType() == BundleEvent.STARTED) {
+            Bundle bundle = bundleEvent.getBundle();
+            if (bundle.getEntry("META-INF/services/") == null) {
+                return;
+            }
+            Enumeration<String> entryPaths = bundle.getEntryPaths("META-INF/services/");
+            while (entryPaths.hasMoreElements()) {
+                String entryPath = entryPaths.nextElement();
+                if(!entryPath.endsWith("/")) {
+                    processEntryPath(bundle, entryPath);
+                }
+            }
+        }
+    }
+
+    private void processEntryPath(Bundle bundle, String entryPath) {
+        try {
+            String serviceName = entryPath.substring("META-INF/services/".length());
+            Class<?> serviceClass = bundle.loadClass(serviceName);
+
+            URL child = bundle.getEntry(entryPath);
+            InputStream inStream = child.openStream();
+
+            BufferedReader br = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));
+            String implClassName = br.readLine();
+            while (implClassName != null){
+                int hashIndex = implClassName.indexOf("#");
+                if (hashIndex > 0) {
+                    implClassName = implClassName.substring(0, hashIndex-1);
+                }
+                else if (hashIndex == 0) {
+                    implClassName = "";
+                }
+                implClassName = implClassName.trim();
+                if (implClassName.length() > 0) {
+                    try {
+                        // Load the service class
+                        Class<?> implClass = (Class<?>) bundle.loadClass(implClassName);
+                        if (serviceClass.isAssignableFrom(implClass) == false) {
+                            log.warning("Configured service: " + implClassName + " is not assignble to " +
+                                    serviceClass.getName());
+                            continue;
+                        }
+                        // Provide service properties
+                        Hashtable<String, String> props = new Hashtable<String, String>();
+                        props.put(Constants.VERSION_ATTRIBUTE, bundle.getVersion().toString());
+                        String vendor = (String) bundle.getHeaders().get(Constants.BUNDLE_VENDOR);
+                        props.put(Constants.SERVICE_VENDOR, (vendor != null ? vendor : "anonymous"));
+                        // Translate annotated @Priority into a service ranking
+                        props.put(Constants.SERVICE_RANKING,
+                                String.valueOf(PriorityServiceComparator.getPriority(implClass)));
+
+                        // Register the service factory on behalf of the intercepted bundle
+                        JDKUtilServiceFactory factory = new JDKUtilServiceFactory(implClass);
+                        BundleContext bundleContext = bundle.getBundleContext();
+                        bundleContext.registerService(serviceName, factory, props);
+                    }
+                    catch(Exception e){
+                        log.log(Level.SEVERE,
+                                "Failed to load service class using ServiceLoader logic: " + implClassName, e);
+                    }
+                }
+                implClassName = br.readLine();
+            }
+            br.close();
+        }
+        catch (RuntimeException rte) {
+            throw rte;
+        }
+        catch (Exception e) {
+            log.log(Level.SEVERE, "Failed to read services from: " + entryPath, e);
+        }
+    }
+
+
+    /**
+     * Service factory simply instantiating the configured service.
+     */
+    static class JDKUtilServiceFactory implements ServiceFactory
+    {
+        private Class<?> serviceClass;
+
+        public JDKUtilServiceFactory(Class<?> serviceClass) {
+            this.serviceClass = serviceClass;
+        }
+
+        @Override
+        public Object getService(Bundle bundle, ServiceRegistration registration) {
+            try {
+                Object serviceInstance = serviceClass.newInstance();
+                return serviceInstance;
+            }
+            catch (Exception ex) {
+                ex.printStackTrace();
+                throw new IllegalStateException("Cannot instanciate service", ex);
+            }
+        }
+
+        @Override
+        public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/eadbfe97/code/core/src/main/java/org/apache/tamaya/core/internal/PriorityServiceComparator.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/PriorityServiceComparator.java b/code/core/src/main/java/org/apache/tamaya/core/internal/PriorityServiceComparator.java
new file mode 100644
index 0000000..c0cfca6
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/PriorityServiceComparator.java
@@ -0,0 +1,67 @@
+/*
+ * 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 javax.annotation.Priority;
+import java.util.Comparator;
+
+/**
+ * Comparator implementation for odering services loaded based on their increasing priority values.
+ */
+public class PriorityServiceComparator implements Comparator<Object> {
+
+    @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 s evaluated. If no such
+     * annotation is present, a default priority is returned (1);
+     *
+     * @param o the instance, not 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 s evaluated.
+     * If no such annotation is present, a default priority is returned (1);
+     *
+     * @param type the type, not null.
+     * @return a priority, by default 1.
+     */
+    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