You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2017/11/14 09:25:44 UTC

[03/12] incubator-tamaya git commit: TAMAYA-318 Moved spi-support as API base implementation package to remove code duplicates.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SimplePropertySource.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SimplePropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SimplePropertySource.java
new file mode 100644
index 0000000..070a564
--- /dev/null
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SimplePropertySource.java
@@ -0,0 +1,284 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport.propertysource;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.logging.Logger;
+
+/**
+ * Simple implementation of a {@link org.apache.tamaya.spi.PropertySource} for
+ * simple property files and XML property files.
+ */
+public class SimplePropertySource extends BasePropertySource {
+
+    private static final Logger LOG = Logger.getLogger(SimplePropertySource.class.getName());
+
+    /**
+     * The current properties.
+     */
+    private Map<String, PropertyValue> properties = new HashMap<>();
+
+    /**
+     * Creates a new Properties based PropertySource based on the given URL.
+     *
+     * @param propertiesLocation the URL encoded location, not null.
+     */
+    public SimplePropertySource(File propertiesLocation) {
+        super(propertiesLocation.toString(), 0);
+        try {
+            this.properties = load(propertiesLocation.toURI().toURL());
+        } catch (IOException e) {
+            throw new ConfigException("Failed to load properties from " + propertiesLocation, e);
+        }
+    }
+
+    /**
+     * Creates a new Properties based PropertySource based on the given URL.
+     *
+     * @param propertiesLocation the URL encoded location, not null.
+     */
+    public SimplePropertySource(URL propertiesLocation) {
+        super(propertiesLocation.toString(), 0);
+        this.properties = load(Objects.requireNonNull(propertiesLocation));
+    }
+
+    /**
+     * Creates a new Properties based PropertySource.
+     *
+     * @param name the property source name, not null.
+     * @param properties the properties, not null
+     * @param defaultOrdinal the default ordinal
+     */
+    public SimplePropertySource(String name, Map<String, String> properties, int defaultOrdinal){
+        super(name, defaultOrdinal);
+        for(Map.Entry<String,String> en: properties.entrySet()) {
+            this.properties.put(en.getKey(), PropertyValue.of(en.getKey(), en.getValue(), name));
+        }
+    }
+
+    /**
+     * Creates a new Properties based PropertySource based on the given properties map.
+     *
+     * @param name       the name, not null.
+     * @param properties the properties, not null.
+     */
+    public SimplePropertySource(String name, Map<String, String> properties) {
+        this(name, properties, 0);
+    }
+
+    /**
+     * Creates a new Properties based PropertySource based on the given URL.
+     *
+     * @param name               The property source name
+     * @param propertiesLocation the URL encoded location, not null.
+     */
+    public SimplePropertySource(String name, URL propertiesLocation) {
+        super(name, 0);
+        this.properties = load(propertiesLocation);
+    }
+
+    private SimplePropertySource(Builder builder) {
+        properties = builder.properties;
+        if(builder.defaultOrdinal!=null){
+            setDefaultOrdinal(builder.defaultOrdinal);
+        }
+        if(builder.ordinal!=null){
+            setOrdinal(builder.ordinal);
+        }
+        setName(builder.name);
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    @Override
+    public Map<String, PropertyValue> getProperties() {
+        return this.properties;
+    }
+
+    /**
+     * loads the Properties from the given URL
+     *
+     * @param propertiesFile {@link URL} to load Properties from
+     * @return loaded {@link Properties}
+     * @throws IllegalStateException in case of an error while reading properties-file
+     */
+    private static Map<String, PropertyValue> load(URL propertiesFile) {
+        boolean isXML = isXMLPropertieFiles(propertiesFile);
+
+        Map<String, PropertyValue> properties = new HashMap<>();
+        try (InputStream stream = propertiesFile.openStream()) {
+            Properties props = new Properties();
+            if (stream != null) {
+                if (isXML) {
+                    props.loadFromXML(stream);
+                } else {
+                    props.load(stream);
+                }
+            }
+            String source = propertiesFile.toString();
+            for (String key : props.stringPropertyNames()) {
+                properties.put(key, PropertyValue.of(key, props.getProperty(key), source));
+            }
+        } catch (IOException e) {
+            throw new ConfigException("Error loading properties from " + propertiesFile, e);
+        }
+
+        return properties;
+    }
+
+    private static boolean isXMLPropertieFiles(URL url) {
+        return url.getFile().endsWith(".xml");
+    }
+
+
+    /**
+     * {@code SimplePropertySource} builder static inner class.
+     */
+    public static final class Builder {
+        private String name;
+        private Integer defaultOrdinal;
+        private Integer ordinal;
+        private Map<String, PropertyValue> properties = new HashMap<>();
+
+        private Builder() {
+        }
+
+        /**
+         * Sets the {@code name} to a new UUID and returns a reference to this Builder so that the methods
+         * can be chained together.
+         *
+         * @return a reference to this Builder
+         */
+        public Builder withUuidName() {
+            this.name = UUID.randomUUID().toString();
+            return this;
+        }
+
+        /**
+         * Sets the {@code name} and returns a reference to this Builder so that the methods
+         * can be chained together.
+         *
+         * @param val the {@code name} to set, not null.
+         * @return a reference to this Builder
+         */
+        public Builder withName(String val) {
+            this.name = Objects.requireNonNull(name);
+            return this;
+        }
+
+        /**
+         * Sets the {@code ordinal} and returns a reference to this Builder so that the methods
+         * can be chained together.
+         *
+         * @param val the {@code ordinal} to set
+         * @return a reference to this Builder
+         */
+        public Builder withOrdinal(int val) {
+            this.ordinal = val;
+            return this;
+        }
+
+        /**
+         * Sets the {@code defaultOrdinal} and returns a reference to this Builder so that the methods
+         * can be chained together.
+         *
+         * @param val the {@code defaultOrdinal} to set
+         * @return a reference to this Builder
+         */
+        public Builder withDefaultOrdinal(int val) {
+            this.defaultOrdinal = val;
+            return this;
+        }
+
+        /**
+         * Reads the {@code properties} from the given resource and returns a reference
+         * to this Builder so that the methods can be chained together.
+         *
+         * @param resource the {@code resource} to read
+         * @return a reference to this Builder
+         */
+        public Builder withProperties(URL resource) {
+            this.properties.putAll(load(resource));
+            return this;
+        }
+
+        /**
+         * Reads the {@code properties} from the given resource and returns a reference
+         * to this Builder so that the methods can be chained together.
+         *
+         * @param file the {@code file} to read from (xml or properties format).
+         * @return a reference to this Builder
+         */
+        public Builder withProperties(File file) {
+            try {
+                this.properties.putAll(load(file.toURI().toURL()));
+            } catch (MalformedURLException e) {
+                throw new IllegalArgumentException("Failed to read file: " + file, e);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the {@code properties} and returns a reference to this Builder so that the methods can be chained together.
+         *
+         * @param val the {@code properties} to set
+         * @return a reference to this Builder
+         */
+        public Builder withProperties(Map<String, String> val) {
+            for(Map.Entry<String,String> en: val.entrySet()) {
+                this.properties.put(en.getKey(), PropertyValue.of(en.getKey(), en.getValue(), name));
+            }
+            return this;
+        }
+
+        /**
+         * Sets the {@code properties} and returns a reference to this Builder so that the methods can be chained together.
+         *
+         * @param val the {@code properties} to set
+         * @return a reference to this Builder
+         */
+        public Builder withProperty(String key, String val) {
+            this.properties.put(key, PropertyValue.of(key, val, name));
+            return this;
+        }
+
+        /**
+         * Returns a {@code SimplePropertySource} built from the parameters previously set.
+         *
+         * @return a {@code SimplePropertySource} built with parameters of this {@code SimplePropertySource.Builder}
+         */
+        public SimplePropertySource build() {
+            return new SimplePropertySource(this);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SystemPropertySource.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SystemPropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SystemPropertySource.java
new file mode 100644
index 0000000..cfc60bb
--- /dev/null
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/SystemPropertySource.java
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport.propertysource;
+
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * This {@link org.apache.tamaya.spi.PropertySource} manages the system properties. You can disable this feature by
+ * setting {@code tamaya.envprops.disable} or {@code tamaya.defaults.disable}.
+ */
+public class SystemPropertySource extends BasePropertySource {
+
+    /**
+     * default ordinal used.
+     */
+    public static final int DEFAULT_ORDINAL = 1000;
+
+    private volatile Map<String,PropertyValue> cachedProperties;
+
+    /**
+     * previous System.getProperties().hashCode()
+     * so we can check if we need to reload
+     */
+    private volatile int previousHash;
+
+    /**
+     * Prefix that allows system properties to virtually be mapped on specified sub section.
+     */
+    private String prefix;
+
+    /**
+     * If true, this property source does not return any properties. This is useful since this
+     * property source is applied by default, but can be switched off by setting the
+     * {@code tamaya.envprops.disable} system/environment property to {@code true}.
+     */
+    private boolean disabled = false;
+
+    /**
+     * Creates a new instance. Also initializes the {@code prefix} and {@code disabled} properties
+     * from the system-/ environment properties:
+     * <pre>
+     *     tamaya.envprops.prefix
+     *     tamaya.envprops.disable
+     * </pre>
+     */
+    public SystemPropertySource(){
+        super("system-properties", DEFAULT_ORDINAL);
+        initFromSystemProperties();
+        if(!disabled){
+            cachedProperties = Collections.unmodifiableMap(loadProperties());
+        }
+    }
+
+    /**
+     * Initializes the {@code prefix} and {@code disabled} properties from the system-/
+     * environment properties:
+     * <pre>
+     *     tamaya.envprops.prefix
+     *     tamaya.envprops.disable
+     * </pre>
+     */
+    private void initFromSystemProperties() {
+        String value = System.getProperty("tamaya.sysprops.prefix");
+        if(value==null){
+            prefix = System.getenv("tamaya.sysprops.prefix");
+        }
+        value = System.getProperty("tamaya.sysprops.disable");
+        if(value==null){
+            value = System.getenv("tamaya.sysprops.disable");
+        }
+        if(value==null){
+            value = System.getProperty("tamaya.defaults.disable");
+        }
+        if(value==null){
+            value = System.getenv("tamaya.defaults.disable");
+        }
+        if(value!=null && !value.isEmpty()) {
+            this.disabled = Boolean.parseBoolean(value);
+        }
+    }
+
+    /**
+     * Creates a new instance using a fixed ordinal value.
+     * @param ordinal the ordinal number.
+     */
+    public SystemPropertySource(int ordinal){
+        this(null, ordinal);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the prefix to be used, or null.
+     * @param ordinal the ordinal to be used.
+     */
+    public SystemPropertySource(String prefix, int ordinal){
+        this.prefix = prefix;
+        setOrdinal(ordinal);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the prefix to be used, or null.
+     */
+    public SystemPropertySource(String prefix){
+        this.prefix = prefix;
+    }
+
+
+    private Map<String, PropertyValue> loadProperties() {
+        Properties sysProps = System.getProperties();
+        previousHash = System.getProperties().hashCode();
+        final String prefix = this.prefix;
+        Map<String, PropertyValue> entries = new HashMap<>();
+        for (Map.Entry<Object,Object> entry : sysProps.entrySet()) {
+            if(entry.getKey() instanceof String && entry.getValue() instanceof String) {
+                if (prefix == null) {
+                    entries.put((String) entry.getKey(),
+                            PropertyValue.of((String) entry.getKey(),
+                                    (String) entry.getValue(),
+                                    getName()));
+                } else {
+                    entries.put(prefix + entry.getKey(),
+                            PropertyValue.of(prefix + entry.getKey(),
+                                    (String) entry.getValue(),
+                                    getName()));
+                }
+            }
+        }
+        return entries;
+    }
+
+    @Override
+    public String getName() {
+        if(disabled){
+            return super.getName() + "(disabled)";
+        }
+        return super.getName();
+    }
+
+    @Override
+    public PropertyValue get(String key) {
+        if(disabled){
+            return null;
+        }
+        String prefix = this.prefix;
+        if(prefix==null) {
+            return PropertyValue.of(key, System.getProperty(key), getName());
+        }
+        return PropertyValue.of(key, System.getProperty(key.substring(prefix.length())), getName());
+    }
+
+    @Override
+    public Map<String, PropertyValue> getProperties() {
+        if(disabled){
+            return Collections.emptyMap();
+        }
+        // only need to reload and fill our map if something has changed
+        // synchronization was removed, Instance was marked as volatile. In the worst case it
+        // is reloaded twice, but the values will be the same.
+        if (previousHash != System.getProperties().hashCode()) {
+            Map<String, PropertyValue> properties = loadProperties();
+            this.cachedProperties = Collections.unmodifiableMap(properties);
+        }
+        return this.cachedProperties;
+    }
+
+    @Override
+    public boolean isScannable() {
+        return true;
+    }
+
+    @Override
+    protected String toStringValues() {
+        return  super.toStringValues() +
+                "  prefix=" + prefix + '\n' +
+                "  disabled=" + disabled + '\n';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/WrappedPropertySource.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/WrappedPropertySource.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/WrappedPropertySource.java
new file mode 100644
index 0000000..feaaf7b
--- /dev/null
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/WrappedPropertySource.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.spisupport.propertysource;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spisupport.PropertySourceComparator;
+
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Property source effectively managed by the configuration context, allowing resetting of ordinal and its
+ * delegate (e.g. in case of refresh).
+ */
+class WrappedPropertySource implements PropertySource{
+
+    private Integer ordinal;
+    private PropertySource delegate;
+    private long loaded = System.currentTimeMillis();
+
+    private WrappedPropertySource(PropertySource delegate) {
+        this(delegate, null);
+    }
+
+    private WrappedPropertySource(PropertySource delegate, Integer ordinal) {
+        this.delegate = Objects.requireNonNull(delegate);
+        this.ordinal = ordinal;
+    }
+
+    public static WrappedPropertySource of(PropertySource ps) {
+        if(ps instanceof  WrappedPropertySource){
+            return (WrappedPropertySource)ps;
+        }
+        return new WrappedPropertySource(ps);
+    }
+
+    public static WrappedPropertySource of(PropertySource ps, Integer ordinal) {
+        if(ps instanceof  WrappedPropertySource){
+            return new WrappedPropertySource(((WrappedPropertySource)ps).getDelegate(), ordinal);
+        }
+        return new WrappedPropertySource(ps, ordinal);
+    }
+
+    public int getOrdinal() {
+        if(this.ordinal!=null){
+            return this.ordinal;
+        }
+        return PropertySourceComparator.getOrdinal(delegate);
+    }
+
+    public void setOrdinal(Integer ordinal) {
+        this.ordinal = ordinal;
+    }
+
+    public void setDelegate(PropertySource delegate) {
+        this.delegate = Objects.requireNonNull(delegate);
+        this.loaded = System.currentTimeMillis();
+    }
+
+    @Override
+    public String getName() {
+        return delegate.getName();
+    }
+
+    @Override
+    public PropertyValue get(String key) {
+        return delegate.get(key);
+    }
+
+    @Override
+    public Map<String, PropertyValue> getProperties() {
+        return delegate.getProperties();
+    }
+
+    @Override
+    public boolean isScannable() {
+        return delegate.isScannable();
+    }
+
+    public PropertySource getDelegate() {
+        return delegate;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof WrappedPropertySource)) return false;
+
+        WrappedPropertySource that = (WrappedPropertySource) o;
+
+        return getDelegate().getName().equals(that.getDelegate().getName());
+    }
+
+    @Override
+    public int hashCode() {
+        return getDelegate().getName().hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "WrappedPropertySource{" +
+                "name=" + getName() +
+                ", ordinal=" + getOrdinal() +
+                ", scannable=" + isScannable() +
+                ", loadedAt=" + loaded +
+                ", delegate-class=" + delegate.getClass().getName() +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/package-info.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/package-info.java b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/package-info.java
new file mode 100644
index 0000000..21e5aec
--- /dev/null
+++ b/code/spi-support/src/main/java/org/apache/tamaya/spisupport/propertysource/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ * Contains internal implementations artifacts registered as services.
+ */
+package org.apache.tamaya.spisupport.propertysource;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/A.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/A.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/A.java
new file mode 100644
index 0000000..4101f1e
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/A.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+class A implements AutoCloseable{
+    @Override
+    public void close() throws Exception {
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/B.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/B.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/B.java
new file mode 100644
index 0000000..584b923
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/B.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+public class B extends A implements Runnable{
+    @Override
+    public void run() {
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/BuildablePropertySourceProviderTest.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/BuildablePropertySourceProviderTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/BuildablePropertySourceProviderTest.java
new file mode 100644
index 0000000..5f95859
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/BuildablePropertySourceProviderTest.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.spisupport.propertysource.BuildablePropertySource;
+import org.apache.tamaya.spisupport.propertysource.BuildablePropertySourceProvider;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class BuildablePropertySourceProviderTest {
+
+    @Test
+    public void getPropertySources() throws Exception {
+        BuildablePropertySource ps = BuildablePropertySource.builder()
+                .withName("test1").build();
+        BuildablePropertySourceProvider prov = BuildablePropertySourceProvider.builder()
+                .withPropertySourcs(ps).build();
+        assertNotNull(prov);
+        assertEquals(prov.getPropertySources().iterator().next(), ps);
+    }
+
+    @Test
+    public void equals() throws Exception {
+        BuildablePropertySource ps = BuildablePropertySource.builder()
+                .withName("test1").build();
+        BuildablePropertySourceProvider prov1 = BuildablePropertySourceProvider.builder()
+                .withPropertySourcs(ps).build();
+        BuildablePropertySourceProvider prov2 = BuildablePropertySourceProvider.builder()
+                .withPropertySourcs(ps).build();
+        assertEquals(prov1, prov2);
+        BuildablePropertySource ps2 = BuildablePropertySource.builder()
+                .withName("test12").build();
+        prov2 = BuildablePropertySourceProvider.builder()
+                .withPropertySourcs(ps2).build();
+        assertNotEquals(prov1, prov2);
+    }
+
+    @Test
+    public void testHashCode() throws Exception {
+        BuildablePropertySource ps = BuildablePropertySource.builder()
+                .withName("test1").build();
+        BuildablePropertySourceProvider prov1 = BuildablePropertySourceProvider.builder()
+                .withPropertySourcs(ps).build();
+        BuildablePropertySourceProvider prov2 = BuildablePropertySourceProvider.builder()
+                .withPropertySourcs(ps).build();
+        assertEquals(prov1.hashCode(), prov2.hashCode());
+        BuildablePropertySource ps2 = BuildablePropertySource.builder()
+                .withName("test12").build();
+        prov2 = BuildablePropertySourceProvider.builder()
+                .withPropertySourcs(ps2).build();
+        assertNotEquals(prov1.hashCode(), prov2.hashCode());
+    }
+
+
+    @Test
+    public void builder() throws Exception {
+        assertNotNull(BuildablePropertySource.builder());
+        assertNotEquals(BuildablePropertySource.builder(), BuildablePropertySource.builder());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/BuildablePropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/BuildablePropertySourceTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/BuildablePropertySourceTest.java
new file mode 100644
index 0000000..b91cb59
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/BuildablePropertySourceTest.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.spisupport.propertysource.BuildablePropertySource;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class BuildablePropertySourceTest {
+    @Test
+    public void getOrdinal() throws Exception {
+        BuildablePropertySource ps1 = BuildablePropertySource.builder()
+                .withOrdinal(55).build();
+        assertEquals(55, ps1.getOrdinal());
+    }
+
+    @Test
+    public void getName() throws Exception {
+        BuildablePropertySource ps1 = BuildablePropertySource.builder()
+                .withName("test1").build();
+        assertEquals("test1", ps1.getName());
+        ps1 = BuildablePropertySource.builder().build();
+        assertNotNull(ps1.getName());
+    }
+
+    @Test
+    public void get() throws Exception {
+        BuildablePropertySource ps1 = BuildablePropertySource.builder()
+                .withSimpleProperty("a", "b").build();
+        assertEquals("b", ps1.get("a").getValue());
+    }
+
+    @Test
+    public void getProperties() throws Exception {
+        BuildablePropertySource ps1 = BuildablePropertySource.builder()
+                .withSimpleProperty("a", "b").build();
+        assertNotNull(ps1.getProperties());
+        assertEquals(1, ps1.getProperties().size());
+        assertEquals("b", ps1.getProperties().get("a").getValue());
+    }
+
+    @Test
+    public void equals() throws Exception {
+        BuildablePropertySource ps1 = BuildablePropertySource.builder()
+                .withName("test1").build();
+        BuildablePropertySource ps2 = BuildablePropertySource.builder()
+                .withName("test1").build();
+        assertEquals(ps1, ps2);
+        ps2 = BuildablePropertySource.builder()
+                .withName("test2").build();
+        assertNotEquals(ps1, ps2);
+    }
+
+    @Test
+    public void testHashCode() throws Exception {
+        BuildablePropertySource ps1 = BuildablePropertySource.builder()
+                .withName("test1").build();
+        BuildablePropertySource ps2 = BuildablePropertySource.builder()
+                .withName("test1").build();
+        assertEquals(ps1.hashCode(), ps2.hashCode());
+        ps2 = BuildablePropertySource.builder()
+                .withName("test2").build();
+        assertNotEquals(ps1.hashCode(), ps2.hashCode());
+    }
+
+    @Test
+    public void builder() throws Exception {
+        assertNotNull(BuildablePropertySource.builder());
+        assertNotEquals(BuildablePropertySource.builder(), BuildablePropertySource.builder());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/C.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/C.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/C.java
new file mode 100644
index 0000000..da581e6
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/C.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import java.io.IOException;
+import java.nio.CharBuffer;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+public class C extends B implements Readable{
+
+    private final String inValue;
+
+    public C(String inValue){
+        this.inValue = inValue;
+    }
+
+    @Override
+    public int read(CharBuffer cb) throws IOException {
+        return 0;
+    }
+
+    /**
+     * Returns the input value, set on creation. Used for test assertion.
+     * @return the in value.
+     */
+    public String getInValue() {
+        return inValue;
+    }
+
+    @Override
+    public String toString() {
+        return "C{" +
+                "inValue='" + inValue + '\'' +
+                '}';
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/CTestConverter.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/CTestConverter.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/CTestConverter.java
new file mode 100644
index 0000000..dce8121
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/CTestConverter.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+
+/**
+ * Created by Anatole on 13.06.2015.
+ */
+public class CTestConverter implements PropertyConverter<C>{
+    @Override
+    public C convert(String value, ConversionContext context) {
+        return new C(value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultConfigurationTest.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultConfigurationTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultConfigurationTest.java
new file mode 100644
index 0000000..6e3dc5b
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultConfigurationTest.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.*;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+public class DefaultConfigurationTest {
+
+    /**
+     * Tests for get(String)
+     */
+    @Test(expected = NullPointerException.class)
+    public void getDoesNotAcceptNull() {
+        DefaultConfiguration c =  new DefaultConfiguration(new DummyConfigurationContext());
+
+        c.get(null);
+    }
+
+    /**
+     * Tests for get(String, Class)
+     */
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+	@Test(expected = NullPointerException.class)
+    public void getDoesNotAcceptNullForClassTargetType() {
+        DefaultConfiguration c = new DefaultConfiguration(new DummyConfigurationContext());
+
+        c.get("a", (Class) null);
+    }
+
+    /**
+     * Tests for get(String, TypeLiteral)
+     */
+    @Test(expected = NullPointerException.class)
+    public void getDoesNotAcceptNullForTypeLiteralTargetType() {
+        DefaultConfiguration c =  new DefaultConfiguration(new DummyConfigurationContext());
+
+        c.get("a", (TypeLiteral<?>)null);
+    }
+
+    /**
+     * Tests for getOrDefault(String, Class, String)
+     */
+    @Test(expected = NullPointerException.class)
+    public void getOrDefaultDoesNotAcceptNullAsKeyForThreeParameterVariant() {
+        DefaultConfiguration c = new DefaultConfiguration(new DummyConfigurationContext());
+
+        c.getOrDefault(null, String.class, "ok");
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void getOrDefaultDoesNotAcceptNullAsDefaultValueForThreeParameterVariant() {
+        DefaultConfiguration c = new DefaultConfiguration(new DummyConfigurationContext());
+
+        c.getOrDefault("a", String.class, null);
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+	@Test(expected = NullPointerException.class)
+    public void getOrDefaultDoesNotAcceptNullAsTargetTypeForThreeParameterVariant() {
+        DefaultConfiguration c = new DefaultConfiguration(new DummyConfigurationContext());
+
+        c.getOrDefault("a", (Class)null, "b");
+    }
+
+    /**
+     * Tests for getOrDefault(String, TypeLiteral, String)
+     */
+    @Test(expected = NullPointerException.class)
+    public void getOrDefaultDoesNotAcceptNullAsKeyForThreeParameterVariantSecondIsTypeLiteral() {
+        DefaultConfiguration c = new DefaultConfiguration(new DummyConfigurationContext());
+
+        c.getOrDefault(null, TypeLiteral.of(String.class), "ok");
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void getOrDefaultDoesNotAcceptNullAsDefaultValueForThreeParameterVariantSecondIsTypeLiteral() {
+        DefaultConfiguration c = new DefaultConfiguration(new DummyConfigurationContext());
+
+        c.getOrDefault("a", TypeLiteral.of(String.class), null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void getOrDefaultDoesNotAcceptNullAsTargetTypeForThreeParameterVariantSecondIsTypeLiteral() {
+        DefaultConfiguration c = new DefaultConfiguration(new DummyConfigurationContext());
+
+        c.getOrDefault("a", (TypeLiteral<String>) null, "b");
+    }
+
+    /**
+     * Tests for getOrDefault(String, String)
+     */
+    @Test(expected = NullPointerException.class)
+    public void getOrDefaultDoesNotAcceptNullAsKeyForTwoParameterVariantDefaultValueIsSecond() {
+        DefaultConfiguration c = new DefaultConfiguration(new DummyConfigurationContext());
+
+        c.getOrDefault(null, "ok");
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void getOrDefaultDoesNotAcceptNullAsDefaultValueForTwoParameterVariantDefaultValueIsSecond() {
+        DefaultConfiguration c = new DefaultConfiguration(new DummyConfigurationContext());
+
+        c.getOrDefault("a", null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void with_Null() {
+        DefaultConfiguration c = new DefaultConfiguration(new DummyConfigurationContext());
+
+        c.with(null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void query_Null() {
+        DefaultConfiguration c = new DefaultConfiguration(new DummyConfigurationContext());
+
+        c.query(null);
+    }
+
+    @Test
+    public void with() {
+        DefaultConfiguration c = new DefaultConfiguration(new DummyConfigurationContext());
+        assertEquals(c.with(config -> config), c);
+    }
+
+    @Test
+    public void query() {
+        DefaultConfiguration c = new DefaultConfiguration(new DummyConfigurationContext());
+        assertEquals(c.query(config -> "testQ"), "testQ");
+    }
+
+    public static class DummyConfigurationContext implements ConfigurationContext {
+        @Override
+        public void addPropertySources(PropertySource... propertySources) {
+            throw new RuntimeException("Method should be never called in this test");
+        }
+
+        @Override
+        public List<PropertySource> getPropertySources() {
+            throw new RuntimeException("Method should be never called in this test");
+        }
+
+        @Override
+        public PropertySource getPropertySource(String name) {
+            throw new RuntimeException("Method should be never called in this test");
+        }
+
+        @Override
+        public <T> void addPropertyConverter(TypeLiteral<T> type, PropertyConverter<T> propertyConverter) {
+            throw new RuntimeException("Method should be never called in this test");
+        }
+
+        @Override
+        public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+            throw new RuntimeException("Method should be never called in this test");
+        }
+
+        @Override
+        public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> type) {
+            throw new RuntimeException("Method should be never called in this test");
+        }
+
+        @Override
+        public List<PropertyFilter> getPropertyFilters() {
+            throw new RuntimeException("Method should be never called in this test");
+        }
+
+        @Override
+        public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy() {
+            throw new RuntimeException("Method should be never called in this test");
+        }
+
+        @Override
+        public ConfigurationContextBuilder toBuilder() {
+            throw new RuntimeException("Method should be never called in this test");
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContext.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContext.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContext.java
new file mode 100644
index 0000000..c5286e0
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContext.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.*;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class EmptyConfigurationContext implements ConfigurationContext{
+
+    private static final ConfigurationContext INSTANCE = new EmptyConfigurationContext();
+
+    @Override
+    public void addPropertySources(PropertySource... propertySources) {
+    }
+
+    @Override
+    public List<PropertySource> getPropertySources() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public PropertySource getPropertySource(String name) {
+        return null;
+    }
+
+    @Override
+    public <T> void addPropertyConverter(TypeLiteral<T> type, PropertyConverter<T> propertyConverter) {
+    }
+
+    @Override
+    public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+        return Collections.emptyMap();
+    }
+
+    @Override
+    public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> type) {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public List<PropertyFilter> getPropertyFilters() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy() {
+        return PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_POLICY;
+    }
+
+    @Override
+    public ConfigurationContextBuilder toBuilder() {
+        return EmptyConfigurationContextBuilder.instance();
+    }
+
+    public static ConfigurationContext instance() {
+        return INSTANCE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContextBuilder.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContextBuilder.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContextBuilder.java
new file mode 100644
index 0000000..4f17d9a
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/EmptyConfigurationContextBuilder.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import com.sun.org.apache.bcel.internal.generic.INSTANCEOF;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.*;
+
+import java.util.*;
+
+public class EmptyConfigurationContextBuilder implements ConfigurationContextBuilder{
+
+    private static final ConfigurationContextBuilder INSTANCE = new EmptyConfigurationContextBuilder();
+
+    @Override
+    public ConfigurationContextBuilder setContext(ConfigurationContext context) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder addPropertySources(PropertySource... propertySources) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder addPropertySources(Collection<PropertySource> propertySources) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder addDefaultPropertySources() {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertySources(PropertySource... propertySources) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertySources(Collection<PropertySource> propertySources) {
+        return this;
+    }
+
+    @Override
+    public List<PropertySource> getPropertySources() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public List<PropertyFilter> getPropertyFilters() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> getPropertyConverter() {
+        return Collections.emptyMap();
+    }
+
+    @Override
+    public ConfigurationContextBuilder increasePriority(PropertySource propertySource) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder decreasePriority(PropertySource propertySource) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder highestPriority(PropertySource propertySource) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder lowestPriority(PropertySource propertySource) {
+        return null;
+    }
+
+    @Override
+    public ConfigurationContextBuilder addPropertyFilters(PropertyFilter... filters) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder addPropertyFilters(Collection<PropertyFilter> filters) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder addDefaultPropertyFilters() {
+        return null;
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertyFilters(PropertyFilter... filters) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertyFilters(Collection<PropertyFilter> filters) {
+        return this;
+    }
+
+    @Override
+    public <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> typeToConvert, PropertyConverter<T>... propertyConverters) {
+        return null;
+    }
+
+    @Override
+    public <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> typeToConvert, Collection<PropertyConverter<T>> propertyConverters) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder addDefaultPropertyConverters() {
+        return this;
+    }
+
+    @Override
+    public <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert, PropertyConverter<T>... propertyConverters) {
+        return this;
+    }
+
+    @Override
+    public <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert, Collection<PropertyConverter<T>> propertyConverters) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder sortPropertySources(Comparator<PropertySource> comparator) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder sortPropertyFilter(Comparator<PropertyFilter> comparator) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy) {
+        return this;
+    }
+
+    @Override
+    public ConfigurationContext build() {
+        return EmptyConfigurationContext.instance();
+    }
+
+    public static ConfigurationContextBuilder instance() {
+        return INSTANCE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/PriorityServiceComparatorTest.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/PriorityServiceComparatorTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/PriorityServiceComparatorTest.java
new file mode 100644
index 0000000..b8e5555
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/PriorityServiceComparatorTest.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.spisupport.propertysource.SystemPropertySource;
+import org.junit.Test;
+
+import javax.annotation.Priority;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by atsticks on 12.09.16.
+ */
+public class PriorityServiceComparatorTest {
+
+    @Test
+    public void compare() throws Exception {
+        assertTrue(PriorityServiceComparator.getInstance().compare("a", "b")==0);
+        assertTrue(PriorityServiceComparator.getInstance().compare(getClass(), getClass())==0);
+        assertTrue(PriorityServiceComparator.getInstance().compare(new A(), new SystemPropertySource())==-1);
+        assertTrue(PriorityServiceComparator.getInstance().compare(new SystemPropertySource(), new A())==1);
+    }
+
+    @Priority(100)
+    private static final class A{}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertyConverterManagerTest.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertyConverterManagerTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertyConverterManagerTest.java
new file mode 100644
index 0000000..b91e6e4
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertyConverterManagerTest.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.TypeLiteral;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+
+public class PropertyConverterManagerTest {
+
+    private final ConversionContext DUMMY_CONTEXT = new ConversionContext.Builder(
+            "someKey", TypeLiteral.of(Object.class)).build();
+
+    @Test
+    public void customTypeWithFactoryMethodOfIsRecognizedAsSupported() {
+        PropertyConverterManager manager = new PropertyConverterManager(true);
+
+        assertThat(manager.isTargetTypeSupported(TypeLiteral.of(MyType.class)),
+                   is(true));
+    }
+
+    @Test
+    public void factoryMethodOfIsUsedAsConverter() {
+        PropertyConverterManager manager = new PropertyConverterManager(true);
+
+        List<PropertyConverter<MyType>> converters = manager.getPropertyConverters(
+                (TypeLiteral)TypeLiteral.of(MyType.class));
+
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<MyType> converter = converters.get(0);
+
+        Object result = converter.convert("IN", DUMMY_CONTEXT);
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(MyType.class));
+        assertThat(((MyType)result).getValue(), equalTo("IN"));
+    }
+
+    @Test
+    public void testDirectConverterMapping(){
+        PropertyConverterManager manager = new PropertyConverterManager(true);
+        List<PropertyConverter<C>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(C.class)));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<C> converter = converters.get(0);
+        C result = converter.convert("testDirectConverterMapping", DUMMY_CONTEXT);
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat((result).getInValue(), equalTo("testDirectConverterMapping"));
+    }
+
+    @Test
+    public void testDirectSuperclassConverterMapping(){
+        PropertyConverterManager manager = new PropertyConverterManager(true);
+        List<PropertyConverter<B>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(B.class)));
+        assertThat(converters, hasSize(1));
+        converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(B.class)));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<B> converter = converters.get(0);
+        B result = converter.convert("testDirectSuperclassConverterMapping", DUMMY_CONTEXT);
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testDirectSuperclassConverterMapping"));
+    }
+
+    @Test
+    public void testMultipleConverterLoad(){
+        PropertyConverterManager manager = new PropertyConverterManager(true);
+        List<PropertyConverter<B>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(B.class)));
+        assertThat(converters, hasSize(1));
+        manager = new PropertyConverterManager(true);
+        converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(B.class)));
+        assertThat(converters, hasSize(1));
+    }
+
+    @Test
+    public void testTransitiveSuperclassConverterMapping(){
+        PropertyConverterManager manager = new PropertyConverterManager(true);
+        List<PropertyConverter<A>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(A.class)));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<A> converter = converters.get(0);
+        A result = converter.convert("testTransitiveSuperclassConverterMapping", DUMMY_CONTEXT);
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testTransitiveSuperclassConverterMapping"));
+    }
+
+    @Test
+    public void testDirectInterfaceMapping(){
+        PropertyConverterManager manager = new PropertyConverterManager(true);
+        List<PropertyConverter<Readable>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(Readable.class)));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<Readable> converter = converters.get(0);
+        Readable result = converter.convert("testDirectInterfaceMapping", DUMMY_CONTEXT);
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testDirectInterfaceMapping"));
+    }
+
+    @Test
+    public void testTransitiveInterfaceMapping1(){
+        PropertyConverterManager manager = new PropertyConverterManager(true);
+        List<PropertyConverter<Runnable>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(Runnable.class)));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<Runnable> converter = converters.get(0);
+        Runnable result = converter.convert("testTransitiveInterfaceMapping1", DUMMY_CONTEXT);
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testTransitiveInterfaceMapping1"));
+    }
+
+    @Test
+    public void testTransitiveInterfaceMapping2(){
+        PropertyConverterManager manager = new PropertyConverterManager(true);
+        List<PropertyConverter<AutoCloseable>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(AutoCloseable.class)));
+        assertThat(converters, hasSize(1));
+
+        PropertyConverter<AutoCloseable> converter = converters.get(0);
+        AutoCloseable result = converter.convert("testTransitiveInterfaceMapping2", DUMMY_CONTEXT);
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testTransitiveInterfaceMapping2"));
+    }
+
+    public static class MyType {
+        private final String typeValue;
+
+        private MyType(String value) {
+            typeValue = value;
+        }
+
+        public static MyType of(String source) {
+            return new MyType(source);
+        }
+
+        public String getValue() {
+            return typeValue;
+        }
+
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertyFilterComparatorTest.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertyFilterComparatorTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertyFilterComparatorTest.java
new file mode 100644
index 0000000..9a212f7
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertyFilterComparatorTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.spi.FilterContext;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spisupport.PropertyFilterComparator;
+import org.junit.Test;
+
+import javax.annotation.Priority;
+
+import java.util.Comparator;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PropertyFilterComparatorTest {
+
+    @Test
+    public void comparationOfFiltersWithSamePriorityIsCorrect() {
+        Comparator<PropertyFilter> comparator = PropertyFilterComparator.getInstance();
+
+        int result = comparator.compare(new PropertyFilterA(), new PropertyFilterA());
+
+        assertThat(result).isEqualTo(0);
+    }
+
+    @Test
+    public void comparationOfFiltersFirstHigherThenSecondWorksCorrectly() {
+        Comparator<PropertyFilter> comparator = PropertyFilterComparator.getInstance();
+
+        int result = comparator.compare(new PropertyFilterB(), new PropertyFilterA());
+
+        assertThat(result).isGreaterThan(0);
+    }
+
+    @Test
+    public void comparationOfFiltersSecondHigherThenFirstWorksCorrectly() {
+        Comparator<PropertyFilter> comparator = PropertyFilterComparator.getInstance();
+
+        int result = comparator.compare(new PropertyFilterA(), new PropertyFilterB());
+
+        assertThat(result).isLessThan(0);
+    }
+
+
+    @Priority(1)
+    private static class PropertyFilterA  implements PropertyFilter {
+        public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
+            throw new RuntimeException("Not implemented or look at me!");
+        }
+    }
+
+    @Priority(2)
+    private static class PropertyFilterB  implements PropertyFilter {
+        public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
+            throw new RuntimeException("Not implemented or look at me!");
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/RegexPropertyFilterTest.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/RegexPropertyFilterTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/RegexPropertyFilterTest.java
new file mode 100644
index 0000000..2822cb6
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/RegexPropertyFilterTest.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.FilterContext;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for {@link RegexPropertyFilter}. Created by anatole on 11.02.16.
+ */
+public class RegexPropertyFilterTest {
+
+    private static PropertyValue prop1 = PropertyValue.of("test1", "test1", "test");
+    private static PropertyValue prop2 = PropertyValue.of("test2", "test2", "test");
+    private static PropertyValue prop3 = PropertyValue.of("test1.test3", "test.test3", "test");
+    private static ConfigurationContext configContext = EmptyConfigurationContext.instance();
+
+    @org.junit.Test
+    public void testFilterProperty() throws Exception {
+        RegexPropertyFilter filter = new RegexPropertyFilter();
+        filter.setIncludes("test1.*");
+        Map<String,PropertyValue> map = new HashMap<>();
+        map.put(prop1.getKey(), prop1);
+        map.put(prop2.getKey(), prop2);
+        map.put(prop3.getKey(), prop3);
+        assertEquals(filter.filterProperty(prop1, new FilterContext(prop1, configContext)), prop1);
+        assertNull(filter.filterProperty(prop2, new FilterContext(prop2, configContext)));
+        assertEquals(filter.filterProperty(
+                prop3,
+                new FilterContext(prop3, map, configContext)), prop3);
+        assertEquals(filter.filterProperty(
+                prop3,
+                new FilterContext(prop3, map, configContext)), prop3);
+        filter = new RegexPropertyFilter();
+        filter.setIncludes("test1.*");
+        assertNotNull(filter.filterProperty(prop1, new FilterContext(prop1, map, configContext)));
+        assertNull(filter.filterProperty(prop2, new FilterContext(prop2, map, configContext)));
+        assertNotNull(filter.filterProperty(prop3, new FilterContext(prop3, map, configContext)));
+    }
+
+    @org.junit.Test
+    public void testToString() throws Exception {
+        RegexPropertyFilter filter = new RegexPropertyFilter();
+        filter.setIncludes("test\\..*");
+        assertTrue(filter.toString().contains("test\\..*"));
+        assertTrue(filter.toString().contains("RegexPropertyFilter"));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/BasePropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/BasePropertySourceTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/BasePropertySourceTest.java
new file mode 100644
index 0000000..eb549a4
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/BasePropertySourceTest.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport.propertysource;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spisupport.PropertySourceComparator;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.*;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class BasePropertySourceTest {
+
+    @Test
+    public void isAlwaysScanable() {
+        BasePropertySource bs = new BasePropertySource() {
+            @Override
+            public Map<String, PropertyValue> getProperties() {
+                return Collections.emptyMap();
+            }
+        };
+
+        assertThat(bs.isScannable()).isTrue();
+    }
+
+    @Test
+    public void givenOrdinalOverwritesGivenDefaulOrdinal() {
+        BasePropertySource bs = new BasePropertySource() {
+            @Override
+            public Map<String, PropertyValue> getProperties() {
+                return Collections.emptyMap();
+            }
+        };
+
+        bs.setDefaultOrdinal(10);
+
+        assertThat(bs.getDefaultOrdinal()).isEqualTo(10);
+        assertThat(bs.getOrdinal()).isEqualTo(10);
+
+        bs.setOrdinal(20);
+
+        assertThat(bs.getOrdinal()).isEqualTo(20);
+    }
+
+    @Test
+    public void testGetOrdinal() {
+
+        PropertySource defaultPropertySource = new BasePropertySource(56) {
+
+            @Override
+            public String getName() {
+                return "testWithDefault";
+            }
+
+            @Override
+            public PropertyValue get(String key) {
+                return null;
+            }
+
+            @Override
+            public Map<String, PropertyValue> getProperties() {
+                return Collections.emptyMap();
+            }
+        };
+
+        Assert.assertEquals(56, PropertySourceComparator.getOrdinal(defaultPropertySource));
+        Assert.assertEquals(1000, new OverriddenOrdinalPropertySource().getOrdinal());
+
+        // propertySource with invalid ordinal
+        Assert.assertEquals(1, new OverriddenInvalidOrdinalPropertySource().getOrdinal());
+    }
+
+    @Test
+    public void testGet() {
+        Assert.assertEquals(1000, new OverriddenOrdinalPropertySource().getOrdinal());
+    }
+
+    private static class OverriddenOrdinalPropertySource extends BasePropertySource {
+
+        private OverriddenOrdinalPropertySource() {
+            super(250);
+        }
+
+        @Override
+        public String getName() {
+            return "overriddenOrdinal";
+        }
+
+        @Override
+        public Map<String, PropertyValue> getProperties() {
+            Map<String,PropertyValue> result = new HashMap<>(1);
+            result.put(PropertySource.TAMAYA_ORDINAL, PropertyValue.of(PropertySource.TAMAYA_ORDINAL, "1000", getName()));
+            return result;
+        }
+    }
+
+    private static class OverriddenInvalidOrdinalPropertySource extends BasePropertySource {
+
+        private OverriddenInvalidOrdinalPropertySource() {
+            super(1);
+        }
+
+        @Override
+        public String getName() {
+            return "overriddenInvalidOrdinal";
+        }
+
+        @Override
+        public Map<String, PropertyValue> getProperties() {
+            Map<String,PropertyValue> result = new HashMap<>(1);
+            result.put(PropertySource.TAMAYA_ORDINAL, PropertyValue.of(PropertySource.TAMAYA_ORDINAL, "invalid", getName()));
+            return result;
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/CLIPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/CLIPropertySourceTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/CLIPropertySourceTest.java
new file mode 100644
index 0000000..4507772
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/CLIPropertySourceTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.spisupport.propertysource;
+
+import org.apache.tamaya.spisupport.propertysource.CLIPropertySource;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for PropertySource for reading main arguments as configuration.
+ */
+public class CLIPropertySourceTest {
+
+    @Test
+    public void setCLIProps() throws Exception {
+        System.clearProperty("main.args");
+        CLIPropertySource ps = new CLIPropertySource();
+        assertTrue(ps.getProperties().isEmpty());
+        CLIPropertySource.initMainArgs("-a", "b");
+        assertFalse(ps.getProperties().isEmpty());
+        assertEquals(ps.getProperties().get("a").getValue(), "b");
+        CLIPropertySource.initMainArgs("--c");
+        assertFalse(ps.getProperties().isEmpty());
+        assertEquals(ps.getProperties().get("c").getValue(), "c");
+        CLIPropertySource.initMainArgs("sss");
+        assertFalse(ps.getProperties().isEmpty());
+        assertEquals(ps.getProperties().get("sss").getValue(), "sss");
+        CLIPropertySource.initMainArgs("-a", "b", "--c", "sss", "--val=vvv");
+        assertFalse(ps.getProperties().isEmpty());
+        assertEquals(ps.getProperties().get("a").getValue(), "b");
+        assertEquals(ps.getProperties().get("c").getValue(), "c");
+        assertEquals(ps.getProperties().get("sss").getValue(), "sss");
+    // getProperties() throws Exception {
+        System.setProperty("main.args", "-a b\t--c sss  ");
+        ps = new CLIPropertySource();
+        assertFalse(ps.getProperties().isEmpty());
+        System.clearProperty("main.args");
+        assertEquals(ps.getProperties().get("a").getValue(), "b");
+        assertEquals(ps.getProperties().get("c").getValue(), "c");
+        assertEquals(ps.getProperties().get("sss").getValue(), "sss");
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/EnumConverterTest.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/EnumConverterTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/EnumConverterTest.java
new file mode 100644
index 0000000..3453caa
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/EnumConverterTest.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.spisupport.propertysource;
+
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spisupport.EnumConverter;
+import org.junit.Test;
+
+import java.math.RoundingMode;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Test class testing the {@link EnumConverter} class.
+ */
+public class EnumConverterTest {
+
+    private final EnumConverter testConverter = new EnumConverter(RoundingMode.class);
+
+    private final ConversionContext DUMMY_CONTEXT = new ConversionContext.Builder("someKey", TypeLiteral.of(Enum.class)).build();
+
+    @Test
+    public void testConvert() {
+        assertEquals(testConverter.convert(RoundingMode.CEILING.toString(),
+                DUMMY_CONTEXT), RoundingMode.CEILING);
+    }
+
+    @Test
+    public void testConvert_LowerCase() {
+        assertEquals(testConverter.convert("ceiling", DUMMY_CONTEXT), RoundingMode.CEILING);
+    }
+
+    @Test
+    public void testConvert_MixedCase()  {
+        assertEquals(testConverter.convert("CeiLinG", DUMMY_CONTEXT), RoundingMode.CEILING);
+    }
+
+    @Test
+    public void testConvert_OtherValue() {
+        assertNull(testConverter.convert("fooBars", DUMMY_CONTEXT));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7917a9f3/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySourceTest.java b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySourceTest.java
new file mode 100644
index 0000000..1e6c958
--- /dev/null
+++ b/code/spi-support/src/test/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySourceTest.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.spisupport.propertysource;
+
+import org.apache.tamaya.spisupport.propertysource.EnvironmentPropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.junit.Test;
+
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for {@link EnvironmentPropertySource}.
+ */
+public class EnvironmentPropertySourceTest {
+
+    private final EnvironmentPropertySource envPropertySource = new EnvironmentPropertySource();
+
+    @Test
+    public void testGetOrdinal() throws Exception {
+        assertEquals(EnvironmentPropertySource.DEFAULT_ORDINAL, envPropertySource.getOrdinal());
+    }
+
+    @Test
+    public void testGetName() throws Exception {
+        assertEquals("environment-properties", envPropertySource.getName());
+    }
+
+    @Test
+    public void testGet() throws Exception {
+        for (Map.Entry<String, String> envEntry : System.getenv().entrySet()) {
+            assertEquals(envPropertySource.get(envEntry.getKey()).getValue(), envEntry.getValue());
+        }
+    }
+
+    @Test
+    public void testGetProperties() throws Exception {
+        Map<String, PropertyValue> props = envPropertySource.getProperties();
+        for(Map.Entry<String,PropertyValue> en: props.entrySet()){
+            if(!en.getKey().startsWith("_")){
+                assertEquals(System.getenv(en.getKey()), en.getValue().getValue());
+            }
+        }
+    }
+
+    @Test
+    public void testIsScannable() throws Exception {
+        assertTrue(envPropertySource.isScannable());
+    }
+}
\ No newline at end of file