tamaya-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From strub...@apache.org
Subject [16/34] incubator-tamaya git commit: first step: move all sources to a 'dormant' directory
Date Sat, 27 Dec 2014 13:58:00 GMT
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/config/ConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/config/ConfigurationBuilder.java b/dormant/core/src/main/java/org/apache/tamaya/core/config/ConfigurationBuilder.java
new file mode 100644
index 0000000..f8b1c95
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/config/ConfigurationBuilder.java
@@ -0,0 +1,374 @@
+/*
+* 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.config;
+
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.BiFunction;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.PropertySource;
+import org.apache.tamaya.core.properties.AggregationPolicy;
+import org.apache.tamaya.core.properties.PropertySourceBuilder;
+
+/**
+* Builder for assembling non trivial {@link org.apache.tamaya.Configuration} instances.
+*/
+public final class ConfigurationBuilder {
+
+    /**
+     * The final meta info to be used, or null, if a default should be generated.
+     */
+    private PropertySourceBuilder builderDelegate;
+
+    /**
+     * Private singleton constructor.
+     */
+    private ConfigurationBuilder(String name) {
+        this.builderDelegate = PropertySourceBuilder.of(name);
+    }
+
+    /**
+     * Private singleton constructor.
+     */
+    private ConfigurationBuilder(String name, PropertySource source) {
+        this.builderDelegate = PropertySourceBuilder.of(name, source);
+    }
+
+    /**
+     * Private singleton constructor.
+     */
+    private ConfigurationBuilder(PropertySource source) {
+        this.builderDelegate = PropertySourceBuilder.of(source);
+    }
+
+
+    /**
+     * Creates a new builder instance.
+     *
+     * @param provider the base provider to be used, not null.
+     * @return a new builder instance, never null.
+     */
+    public static ConfigurationBuilder of(PropertySource provider) {
+        return new ConfigurationBuilder(provider);
+    }
+
+    /**
+     * Creates a new builder instance.
+     *
+     * @param name the provider name, not null.
+     * @return a new builder instance, never null.
+     */
+    public static ConfigurationBuilder of(String name) {
+        return new ConfigurationBuilder(Objects.requireNonNull(name));
+    }
+
+    /**
+     * Creates a new builder instance.
+     *
+     * @return a new builder instance, never null.
+     */
+    public static ConfigurationBuilder of() {
+        return new ConfigurationBuilder("<noname>");
+    }
+
+
+
+
+    /**
+     * Sets the aggregation policy to be used, when adding additional property sets. The policy will
+     * be active a slong as the builder is used or it is reset to another keys.
+     *
+     * @param aggregationPolicy the aggregation policy, not null.
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder withAggregationPolicy(AggregationPolicy aggregationPolicy) {
+        this.builderDelegate.withAggregationPolicy(aggregationPolicy);
+        return this;
+    }
+
+    /**
+     * Sets the meta info to be used for the next operation.
+     *
+     * @param name the name, not null.
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder withName(String name) {
+        this.builderDelegate.withName(name);
+        return this;
+    }
+
+    /**
+     * Adds the given providers with the current active {@link AggregationPolicy}. By
+     * default {@link AggregationPolicy#OVERRIDE} is used.
+     * @see #withAggregationPolicy(AggregationPolicy)
+     * @param providers providers to be added, not null.
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder addProviders(PropertySource... providers) {
+        this.builderDelegate.addProviders(providers);
+        return this;
+    }
+
+    /**
+     * Adds the given providers with the current active {@link AggregationPolicy}. By
+     * default {@link AggregationPolicy#OVERRIDE} is used.
+     * @see #withAggregationPolicy(AggregationPolicy)
+     * @param providers providers to be added, not null.
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder addProviders(List<PropertySource> providers) {
+        this.builderDelegate.addProviders(providers);
+        return this;
+    }
+
+
+    /**
+     * Creates a new {@link org.apache.tamaya.PropertySource} using the given command line arguments and adds it
+     * using the current aggregation policy in place.
+     *
+     * @param args the command line arguments, not null.
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder addArgs(String... args) {
+        this.builderDelegate.addArgs(args);
+        return this;
+    }
+
+    /**
+     * Creates a new read-only {@link org.apache.tamaya.PropertySource} by reading the according path resources. The effective resources read
+     * hereby are determined by the {@code PathResolverService} configured into the {@code Bootstrap} SPI.
+     * Properties read are aggregated using the current aggregation policy active.
+     *
+     * @param paths the paths to be resolved by the {@code PathResolverService} , not null.
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder addPaths(String... paths) {
+        this.builderDelegate.addPaths(paths);
+        return this;
+    }
+
+
+    /**
+     * Creates a new read-only {@link org.apache.tamaya.PropertySource} by reading the according path resources. The effective resources read
+     * hereby are determined by the {@code PathResolverService} configured into the {@code Bootstrap} SPI.
+     * Properties read are aggregated using the current aggregation policy active.
+     *
+     * @param paths the paths to be resolved by the {@code PathResolverService} , not null.
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder addPaths(List<String> paths) {
+        this.builderDelegate.addPaths(paths);
+        return this;
+    }
+
+    /**
+     * Creates a new read-only {@link org.apache.tamaya.PropertySource} by reading the according URL resources.
+     * Properties read are aggregated using the current aggregation policy active.
+     *
+     * @param urls the urls to be read, not null.
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder addURLs(URL... urls) {
+        this.builderDelegate.addURLs(urls);
+        return this;
+    }
+
+    /**
+     * Creates a new read-only {@link org.apache.tamaya.PropertySource} by reading the according URL resources.
+     * Properties read are aggregated using the current aggregation policy active.
+     *
+     * @param urls the urls to be read, not null.
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder addURLs(List<URL> urls) {
+        this.builderDelegate.addURLs(urls);
+        return this;
+    }
+
+
+    /**
+     * Creates a new read-only {@link org.apache.tamaya.PropertySource} based on the given map.
+     * Properties read are aggregated using the current aggregation policy active.
+     *
+     * @param map the map to be added, not null.
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder addMap(Map<String, String> map) {
+        this.builderDelegate.addMap(map);
+        return this;
+    }
+
+
+    /**
+     * Add the current environment properties. Aggregation is based on the current {@link AggregationPolicy} acvtive.
+     *
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder addEnvironmentProperties() {
+        this.builderDelegate.addEnvironmentProperties();
+        return this;
+    }
+
+    /**
+     * Add the current system properties. Aggregation is based on the current {@link AggregationPolicy} acvtive.
+     *
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder addSystemProperties() {
+        this.builderDelegate.addSystemProperties();
+        return this;
+    }
+
+    /**
+     * Adds the given {@link org.apache.tamaya.PropertySource} instances using the current {@link AggregationPolicy}
+     * active.
+     *
+     * @param providers the maps to be included, not null.
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder aggregate(PropertySource... providers) {
+        this.builderDelegate.aggregate(providers);
+        return this;
+    }
+
+
+    /**
+     * Adds the given {@link org.apache.tamaya.PropertySource} instances using the current {@link AggregationPolicy}
+     * active.
+     *
+     * @param providers the maps to be included, not null.
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder aggregate(List<PropertySource> providers) {
+        this.builderDelegate.aggregate(providers);
+        return this;
+    }
+
+
+    /**
+     * Intersetcs the current properties with the given {@link org.apache.tamaya.PropertySource} instance.
+     *
+     * @param providers the maps to be intersected, not null.
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder intersect(PropertySource... providers) {
+        this.builderDelegate.intersect(providers);
+        return this;
+    }
+
+
+    /**
+     * Subtracts with the given {@link org.apache.tamaya.PropertySource} instance from the current properties.
+     *
+     * @param providers the maps to be subtracted, not null.
+     * @return the builder for chaining.
+     */
+    public ConfigurationBuilder subtract(PropertySource... providers) {
+        this.builderDelegate.subtract(providers);
+        return this;
+    }
+
+
+    /**
+     * Filters the current properties based on the given predicate..
+     *
+     * @param filter the filter to be applied, not null.
+     * @return the new filtering instance.
+     */
+    public ConfigurationBuilder filter(Predicate<String> filter) {
+        this.builderDelegate.filter(filter);
+        return this;
+    }
+
+    /**
+     * Filters the current {@link org.apache.tamaya.Configuration} with the given valueFilter.
+     * @param valueFilter the value filter, not null.
+     * @return the (dynamically) filtered source instance, never null.
+     */
+    public ConfigurationBuilder filterValues(BiFunction<String, String, String> valueFilter){
+        this.builderDelegate.filterValues(valueFilter);
+        return this;
+    }
+
+    /**
+     * Creates a new contextual {@link org.apache.tamaya.PropertySource}. Contextual maps delegate to different instances current PropertyMap depending
+     * on the keys returned fromMap the isolationP
+     *
+     * @param mapSupplier          the supplier creating new provider instances
+     * @param isolationKeySupplier the supplier providing contextual keys based on the current environment.
+     */
+    public ConfigurationBuilder addContextual(Supplier<PropertySource> mapSupplier,
+                                                 Supplier<String> isolationKeySupplier) {
+        this.builderDelegate.addContextual(mapSupplier, isolationKeySupplier);
+        return this;
+    }
+
+    /**
+     * Replaces all keys in the current provider by the given map.
+     *
+     * @param replacementMap the map instance, that will replace all corresponding entries in {@code mainMap}, not null.
+     * @return the new delegating instance.
+     */
+    public ConfigurationBuilder replace(Map<String, String> replacementMap) {
+        this.builderDelegate.replace(replacementMap);
+        return this;
+    }
+
+    /**
+     * Build a new property provider based on the input.
+     * @return a new property provider, or null.
+     */
+    public PropertySource buildPropertySource(){
+        return this.builderDelegate.build();
+    }
+
+    /**
+     * Build a new property provider based on the input.
+     * @return a new property provider, or null.
+     */
+    public Configuration build(){
+        return this.buildPropertySource().toConfiguration();
+    }
+
+    /**
+     * Creates a {@link org.apache.tamaya.PropertySource} instance that is serializable and immutable,
+     * so it can be sent over a network connection.
+     *
+     * @return the freezed instance, never null.
+     */
+    public PropertySource buildFreezedPropertySource() {
+        return this.builderDelegate.buildFrozen();
+    }
+
+    /**
+     * Creates a {@link org.apache.tamaya.PropertySource} instance that is serializable and immutable,
+     * so it can be sent over a network connection.
+     *
+     * @return the freezed instance, never null.
+     */
+    public Configuration buildFreezed() {
+        return FreezedConfiguration.of(this.buildFreezedPropertySource().toConfiguration());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/config/ConfigurationFormat.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/config/ConfigurationFormat.java b/dormant/core/src/main/java/org/apache/tamaya/core/config/ConfigurationFormat.java
new file mode 100644
index 0000000..8feaf6a
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/config/ConfigurationFormat.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.config;
+
+import org.apache.tamaya.core.resource.Resource;
+import org.apache.tamaya.core.spi.ConfigurationFormatSpi;
+import org.apache.tamaya.spi.ServiceContext;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Implementations current this class encapsulate the mechanism how to read a
+ * resource URI including interpreting the format correctly (e.g. xml vs.
+ * properties).
+ */
+public interface ConfigurationFormat{
+
+    /**
+     * Returns a unique identifier that identifies each format.
+     *
+     * @return the unique format id, mever null.
+     */
+    public String getFormatName();
+
+    /**
+     * Check if the given {@link java.net.URI} and path xpression qualify that this format should be
+     * able to read them, e.g. checking for compatible file endings.
+     *
+     * @param resource   the configuration location, not null
+     * @return {@code true} if the given resource is in a format supported by
+     * this instance.
+     */
+    boolean isAccepted(Resource resource);
+
+    /**
+     * Reads a {@link org.apache.tamaya.PropertySource} fromMap the given URI, using this format.
+     *
+     * @param resource    the configuration location, not null
+     * @return the corresponding {@link java.util.Map}, never {@code null}.
+     */
+    Map<String,String> readConfiguration(Resource resource);
+
+    /**
+     * Access a {@link ConfigurationFormat}.
+     *
+     * @param formatName the format name
+     * @return the corresponding {@link ConfigurationFormat}, or {@code null}, if
+     * not available for the given environment.
+     */
+    public static ConfigurationFormat of(String formatName){
+        return ServiceContext.getInstance().getSingleton(ConfigurationFormatSpi.class).getFormat(formatName);
+    }
+
+    /**
+     * Get a collection current the keys current the registered {@link ConfigurationFormat} instances.
+     *
+     * @return a collection current the keys current the registered {@link ConfigurationFormat} instances.
+     */
+    public static Collection<String> getFormatNames(){
+        return ServiceContext.getInstance().getSingleton(ConfigurationFormatSpi.class).getFormatNames();
+    }
+
+    /**
+     * Evaluate the matching format for a given resource.
+     *
+     * @param resource The resource
+     * @return a matching configuration format, or {@code null} if no matching format could be determined.
+     */
+    public static ConfigurationFormat from(Resource resource){
+        return ServiceContext.getInstance().getSingleton(ConfigurationFormatSpi.class).getFormat(resource);
+
+    }
+
+    /**
+     * Get an instance for reading configuration fromMap a {@code .properties} file,
+     * as defined by {@link java.util.Properties#load(java.io.InputStream)}.
+     *
+     * @return a format instance for reading configuration fromMap a {@code .properties} file, never null.
+     */
+    public static ConfigurationFormat getPropertiesFormat(){
+        return ServiceContext.getInstance().getSingleton(ConfigurationFormatSpi.class).getPropertiesFormat();
+    }
+
+    /**
+     * Get an instance for reading configuration fromMap a {@code .xml} properties file,
+     * as defined by {@link java.util.Properties#loadFromXML(java.io.InputStream)}.
+     *
+     * @return a format instance for reading configuration fromMap a {@code .xml} properties file, never null.
+     */
+    public static ConfigurationFormat getXmlPropertiesFormat(){
+        return ServiceContext.getInstance().getSingleton(ConfigurationFormatSpi.class).getXmlPropertiesFormat();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/config/FreezedConfiguration.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/config/FreezedConfiguration.java b/dormant/core/src/main/java/org/apache/tamaya/core/config/FreezedConfiguration.java
new file mode 100644
index 0000000..43d6957
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/config/FreezedConfiguration.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy 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.config;
+
+import org.apache.tamaya.*;
+import org.apache.tamaya.core.properties.PropertySourceBuilder;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * Configuration implementation that stores all current values current a given (possibly dynamic, contextual and non remote
+ * capable instance) and is fully serializable.
+ */
+final class FreezedConfiguration extends AbstractConfiguration implements Serializable{
+    private static final long serialVersionUID = -6373137316556444171L;
+
+    private PropertySource properties;
+
+    /**
+     * Constructor.
+     * @param config The base configuration.
+     */
+    private FreezedConfiguration(Configuration config){
+        super(config.getName());
+        this.properties = PropertySourceBuilder.of(config).buildFrozen();
+    }
+
+    public static final Configuration of(Configuration config){
+        if(config instanceof FreezedConfiguration){
+            return config;
+        }
+        return new FreezedConfiguration(config);
+    }
+
+    @Override
+    public Map<String,String> getProperties(){
+        return properties.getProperties();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        FreezedConfiguration that = (FreezedConfiguration) o;
+
+        if (!properties.equals(that.properties)) return false;
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = properties.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "FreezedConfiguration{" +
+                "properties=" + properties +
+                ", name=" + name +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/config/MappedConfiguration.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/config/MappedConfiguration.java b/dormant/core/src/main/java/org/apache/tamaya/core/config/MappedConfiguration.java
new file mode 100644
index 0000000..736b33e
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/config/MappedConfiguration.java
@@ -0,0 +1,56 @@
+package org.apache.tamaya.core.config;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.UnaryOperator;
+
+import org.apache.tamaya.Configuration;
+
+/**
+ * Configuration implementation that maps certain parts (defined by an {@code UnaryOperator<String>}) to alternate areas.
+ */
+class MappedConfiguration extends AbstractConfiguration implements Configuration {
+
+	private static final long serialVersionUID = 8690637705511432083L;
+
+	/** The mapping operator. */
+    private UnaryOperator<String> keyMapper;
+    /** The base configuration. */
+    private Configuration config;
+
+    /**
+     * Creates a new instance.
+     * @param config the base configuration, not null
+     * @param keyMapper The mapping operator, not null
+     */
+    public MappedConfiguration(Configuration config, UnaryOperator<String> keyMapper) {
+        super(config.getName());
+        this.config = Objects.requireNonNull(config);
+        this.keyMapper = Objects.requireNonNull(keyMapper);
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        Map<String, String> result = new HashMap<>();
+        Map<String, String> map = this.config.getProperties();
+        map.forEach((k,v) -> {
+            String targetKey = keyMapper.apply(k);
+            if(targetKey!=null){
+                result.put(targetKey, v);
+            }
+        });
+        return result;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return this.config.isEmpty();
+    }
+
+    @Override
+    public Configuration toConfiguration() {
+        return this;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/MetaConfig.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/MetaConfig.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/MetaConfig.java
new file mode 100644
index 0000000..8d3ad15
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/MetaConfig.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.core.resource.Resource;
+import org.apache.tamaya.spi.ServiceContext;
+import org.apache.tamaya.core.properties.ConfigurationFormat;
+import org.apache.tamaya.core.resource.ResourceLoader;
+
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Singleton to read the configuration for the configuration system
+ * fromMap {@code META-INF/config.properties}.
+ * Created by Anatole on 17.10.2014.
+ */
+public final class MetaConfig {
+
+    private static  final Logger LOG = Logger.getLogger(MetaConfig.class.getName());
+
+    private static final MetaConfig INSTANCE = new MetaConfig();
+
+    private Map<String,String> properties = new HashMap<>();
+
+    private MetaConfig(){
+        List<Resource> resources = ServiceContext.getInstance().getSingleton(ResourceLoader.class).getResources(MetaConfig.class.getClassLoader(),
+                "classpath:META-INF/config.properties");
+        for(Resource res:resources){
+            try{
+                ConfigurationFormat format = ConfigurationFormat.from(res);
+                Map<String,String> read = format.readConfiguration(res);
+                properties.putAll(read);
+            }
+            catch(Exception e){
+                LOG.log(Level.SEVERE, e, () -> "Error reading meta configuration fromMap " + res);
+            }
+        }
+    }
+
+    public static String getKey(String key){
+        return INSTANCE.properties.get(key);
+    }
+
+    public static String getOrDefault(String key, String defaultValue){
+        return INSTANCE.properties.getOrDefault(key, defaultValue);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/Utils.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/Utils.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/Utils.java
new file mode 100644
index 0000000..fd490ce
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/Utils.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.core.internal;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Utility class simplifying some implementation aspects.
+ * Created by Anatole on 11.11.2014.
+ */
+@SuppressWarnings("unchecked")
+public final class Utils {
+
+    private static final Logger LOG = Logger.getLogger(Utils.class.getName());
+
+    private Utils(){}
+
+    /**
+     * Utility method to read out repeatable annotations.
+     * @param annotated the annotated instance.
+     * @param repeatableAnnotation the repeatable annotation type
+     * @param annotationContainer the container annotation type
+     * @param <T> the repeatable annotation type
+     * @param <R> the repeatable container annotation type
+     * @return a list with the annotations found (could be empty, but never null).
+     */
+	public static <T extends Annotation, R extends Annotation> Collection<T>
+            getAnnotations(AnnotatedElement annotated,
+                              Class<T> repeatableAnnotation,
+                              Class<R> annotationContainer){
+        List<T> result = new ArrayList<>();
+        R containerAnnot = annotated.getAnnotation(annotationContainer);
+        if(containerAnnot!=null){
+            Method valueMethod;
+            try {
+                valueMethod = annotationContainer.getMethod("keys");
+                result.addAll(Arrays.asList((T[])valueMethod.invoke(containerAnnot)));
+            } catch (Exception e) {
+                LOG.log(Level.SEVERE, "Failed to evaluate repeatable annotation.", e);
+            }
+        }
+        else{
+            T annot = annotated.getAnnotation(repeatableAnnotation);
+            if(annot!=null){
+                result.add(annot);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Utility method to read out repeatable annotations.
+     * @param annotated the annotated instance.
+     * @param repeatableAnnotation the repeatable annotation type
+     * @param annotationContainer the container annotation type
+     * @param <T> the repeatable annotation type
+     * @param <R> the repeatable container annotation type
+     * @return a list with the annotations found (could be empty, but never null).
+     */
+    public static <T extends Annotation, R extends Annotation> Collection<T>
+    getAnnotations(AccessibleObject annotated,
+                   Class<T> repeatableAnnotation,
+                   Class<R> annotationContainer){
+        List<T> result = new ArrayList<>();
+        R containerAnnot = annotated.getAnnotation(annotationContainer);
+        if(containerAnnot!=null){
+            Method valueMethod;
+            try {
+                valueMethod = annotationContainer.getMethod("keys");
+                result.addAll(Arrays.asList((T[])valueMethod.invoke(containerAnnot)));
+            } catch (Exception e) {
+                LOG.log(Level.SEVERE, "Failed to evaluate repeatable annotation.", e);
+            }
+        }
+        else{
+            T annot = annotated.getAnnotation(repeatableAnnotation);
+            if(annot!=null){
+                result.add(annot);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Utility method to read out repeatable annotations.
+     * @param annotationType the annotation type.
+     * @param objects the accessible objects to be looked up
+     * @param <T> the repeatable annotation type
+     * @return a list with the annotations found (could be empty, but never null).
+     */
+    public static <T extends Annotation> T getAnnotation(
+                   Class<T> annotationType, AnnotatedElement... objects){
+        for(AnnotatedElement obj:objects){
+            T annot = obj.getAnnotation(annotationType);
+            if(annot!=null){
+                return annot;
+            }
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationSpi.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationSpi.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationSpi.java
new file mode 100644
index 0000000..8b7180c
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationSpi.java
@@ -0,0 +1,116 @@
+/*
+ * 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.config;
+
+import java.lang.reflect.Proxy;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.core.internal.el.DefaultExpressionEvaluator;
+import org.apache.tamaya.core.internal.inject.ConfigTemplateInvocationHandler;
+import org.apache.tamaya.core.internal.inject.ConfigurationInjector;
+import org.apache.tamaya.core.spi.ConfigurationProviderSpi;
+import org.apache.tamaya.core.spi.ExpressionEvaluator;
+import org.apache.tamaya.spi.ConfigurationSpi;
+import org.apache.tamaya.spi.ServiceContext;
+
+
+/**
+ * Default SPI that implements the behaviour of {@link org.apache.tamaya.spi.ConfigurationSpi}.
+ */
+@SuppressWarnings("unchecked")
+public class DefaultConfigurationSpi implements ConfigurationSpi {
+
+    private static final String DEFAULT_CONFIG_NAME = "default";
+
+    private Map<String, ConfigurationProviderSpi> configProviders = new ConcurrentHashMap<>();
+
+    private ExpressionEvaluator expressionEvaluator = loadEvaluator();
+
+    private ExpressionEvaluator loadEvaluator() {
+        ExpressionEvaluator eval = ServiceContext.getInstance().getService(ExpressionEvaluator.class).orElse(null);
+        if (eval == null) {
+            eval = new DefaultExpressionEvaluator();
+        }
+        return eval;
+    }
+
+    public DefaultConfigurationSpi() {
+        if(configProviders.isEmpty()) {
+            for (ConfigurationProviderSpi spi : ServiceContext.getInstance().getServices(ConfigurationProviderSpi.class, Collections.emptyList())) {
+                configProviders.put(spi.getConfigName(), spi);
+            }
+        }
+    }
+
+    @Override
+    public <T> T createTemplate(Class<T> type, Configuration... configurations) {
+        ClassLoader cl = Optional.ofNullable(Thread.currentThread()
+                .getContextClassLoader()).orElse(getClass().getClassLoader());
+        return (T) Proxy.newProxyInstance(cl, new Class[]{type}, new ConfigTemplateInvocationHandler(type, configurations));
+    }
+
+    /**
+     *
+     * @param instance the instance with configuration annotations, not null.
+     * @param configurations the configurations to be used for evaluating the values for injection into {@code instance}.
+     *                If no items are passed, the default configuration is used.
+     */
+    @Override
+    public void configure(Object instance, Configuration... configurations) {
+        ConfigurationInjector.configure(instance, configurations);
+    }
+
+
+    @Override
+    public String evaluateValue(String expression, Configuration... configurations) {
+        return expressionEvaluator.evaluate(expression, configurations);
+    }
+
+    @Override
+    public boolean isConfigurationAvailable(String name) {
+        ConfigurationProviderSpi spi = this.configProviders.get(name);
+        return spi != null;
+    }
+
+    @Override
+    public Configuration getConfiguration(String name) {
+        ConfigurationProviderSpi provider = configProviders.get(name);
+        if (provider == null) {
+            if (DEFAULT_CONFIG_NAME.equals(name)) {
+                provider = new FallbackSimpleConfigProvider();
+                configProviders.put(DEFAULT_CONFIG_NAME, provider);
+            } else {
+                throw new ConfigException("No such config: " + name);
+            }
+        }
+        Configuration config = provider.getConfiguration();
+        if (config == null) {
+            throw new ConfigException("No such config: " + name);
+        }
+        return config;
+    }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultPropertyAdapterSpi.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultPropertyAdapterSpi.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultPropertyAdapterSpi.java
new file mode 100644
index 0000000..f1b14e0
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultPropertyAdapterSpi.java
@@ -0,0 +1,168 @@
+/*
+ * 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.config;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.util.Currency;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.PropertyAdapter;
+import org.apache.tamaya.annotation.WithPropertyAdapter;
+import org.apache.tamaya.spi.PropertyAdapterSpi;
+
+/**
+ * Default codecs singleton, which provides default codesc for all kind of classes out of the box, which will be
+ * instantiatable from configuration, if one of the following is given:
+ * <ul>
+ *     <li>static factory methods using a String as simgle argument, called {@code of, valueOf, getInstance, instance, parse}</li>
+ *     <li>have constructors taking a single String</li>
+ * </ul>
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class DefaultPropertyAdapterSpi implements PropertyAdapterSpi {
+
+
+	private Map<Class,PropertyAdapter> adapters = new ConcurrentHashMap<>();
+
+    public DefaultPropertyAdapterSpi(){
+        // Add default adapters
+        register(char.class, (s) -> s.charAt(0));
+        register(byte.class, Byte::parseByte);
+        register(short.class, Short::parseShort);
+        register(int.class, Integer::parseInt);
+        register(long.class, Long::parseLong);
+        register(boolean.class, Boolean::parseBoolean);
+        register(float.class, Float::parseFloat);
+        register(double.class, Double::parseDouble);
+
+        register(Character.class, (s) -> s.charAt(0));
+        register(Byte.class, Byte::valueOf);
+        register(Short.class, Short::valueOf);
+        register(Integer.class, Integer::valueOf);
+        register(Long.class, Long::valueOf);
+        register(Boolean.class, Boolean::valueOf);
+        register(Float.class, Float::valueOf);
+        register(Double.class, Double::valueOf);
+        register(BigDecimal.class, BigDecimal::new);
+        register(BigInteger.class, BigInteger::new);
+
+        register(Currency.class, Currency::getInstance);
+
+        register(LocalDate.class, LocalDate::parse);
+        register(LocalTime.class, LocalTime::parse);
+        register(LocalDateTime.class, LocalDateTime::parse);
+        register(ZoneId.class, ZoneId::of);
+    }
+
+	@Override
+    public <T> PropertyAdapter<T> register(Class<T> targetType, PropertyAdapter<T> adapter){
+        return adapters.put(targetType, adapter);
+    }
+
+    @Override
+    public <T> PropertyAdapter<T> getPropertyAdapter(Class<T> targetType, WithPropertyAdapter adapterAnnot){
+        PropertyAdapter codec = null;
+        Class<? extends PropertyAdapter> configuredCodec = null;
+        if(adapterAnnot != null){
+            configuredCodec = adapterAnnot.value();
+            if(!configuredCodec.equals(PropertyAdapter.class)){
+                try{
+                    codec = configuredCodec.newInstance();
+                }
+                catch(Exception e){
+                    throw new ConfigException("Invalid codec configured.", e);
+                }
+            }
+        }
+        if(codec == null){
+            codec = adapters.get(targetType);
+        }
+        if(codec == null){
+            codec = getDefaultPropertyAdapter(targetType);
+        }
+        if(codec == null){
+            throw new ConfigException("No Codec found for " + targetType.getName());
+        }
+        return codec;
+    }
+
+    private <T> PropertyAdapter getDefaultPropertyAdapter(Class<T> targetType) {
+        PropertyAdapter<T> decoder = null;
+        Method factoryMethod = getFactoryMethod(targetType, "of", "valueOf", "instanceOf", "getInstance", "from", "parse");
+        if(factoryMethod!=null){
+            decoder = (s) -> {
+                try{
+                    factoryMethod.setAccessible(true);
+                    return targetType.cast(factoryMethod.invoke(s));
+                }
+                catch (Exception e){
+                    throw new ConfigException("Failed to decode '"+s+"'", e);
+                }
+            };
+        }
+        if(decoder==null) {
+            try {
+                Constructor<T> constr = targetType.getDeclaredConstructor(String.class);
+                decoder = (s) -> {
+                    try{
+                        constr.setAccessible(true);
+                        return constr.newInstance(s);
+                    }
+                    catch (Exception e){
+                        throw new ConfigException("Failed to decode '"+s+"'", e);
+                    }
+                };
+            } catch (Exception e) {
+                // ignore, TODO log finest
+            }
+        }
+        if(decoder!=null) {
+            return register(targetType, decoder);
+        }
+        return null;
+    }
+
+    private Method getFactoryMethod(Class<?> type, String... methodNames) {
+        Method m;
+        for(String name:methodNames){
+            try{
+                m  = type.getDeclaredMethod(name, String.class);
+                return m;
+            }
+            catch(Exception e){
+                // ignore, TODO log finest
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean isTargetTypeSupported(Class<?> targetType){
+        return adapters.containsKey(targetType);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/EnvPropertiesConfigProvider.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/EnvPropertiesConfigProvider.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/EnvPropertiesConfigProvider.java
new file mode 100644
index 0000000..6fd4672
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/EnvPropertiesConfigProvider.java
@@ -0,0 +1,54 @@
+/*
+ * 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.config;
+
+import org.apache.tamaya.core.properties.PropertySourceBuilder;
+import org.apache.tamaya.core.spi.ConfigurationProviderSpi;
+
+import org.apache.tamaya.Configuration;
+
+/**
+ * Provides a {@link org.apache.tamaya.Configuration} named 'environment.properties'
+ * containing the current environment properties.
+ *
+ * Created by Anatole on 29.09.2014.
+ */
+public class EnvPropertiesConfigProvider implements ConfigurationProviderSpi{
+
+    private Configuration envConfig;
+
+    public EnvPropertiesConfigProvider(){
+        envConfig = Configuration.from(PropertySourceBuilder.of("environment.properties").addEnvironmentProperties().build());
+    }
+
+    @Override
+    public String getConfigName(){
+        return "environment.properties";
+    }
+
+    @Override
+    public Configuration getConfiguration(){
+        return envConfig;
+    }
+
+    @Override
+    public void reload() {
+        // nothing todo here
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FallbackSimpleConfigProvider.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FallbackSimpleConfigProvider.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FallbackSimpleConfigProvider.java
new file mode 100644
index 0000000..7bcfb77
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FallbackSimpleConfigProvider.java
@@ -0,0 +1,60 @@
+package org.apache.tamaya.core.internal.config;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.core.properties.AggregationPolicy;
+import org.apache.tamaya.core.properties.PropertySourceBuilder;
+import org.apache.tamaya.core.spi.ConfigurationProviderSpi;
+
+/**
+ * Implementation of a default config provider used as fallback, if no {@link org.apache.tamaya.core.spi.ConfigurationProviderSpi}
+ * instance is registered for providing the {@code default} {@link org.apache.tamaya.Configuration}. The providers loads the follwing
+ * config resources:
+ * <ul>
+ *     <li>Classpath: META-INF/cfg/default/&#42;&#42;/&#42;.xml, META-INF/cfg/default/&#42;&#42;/&#42;.properties, META-INF/cfg/default/&#42;&#42;/&#42;.ini</li>
+ *     <li>Classpath: META-INF/cfg/config/#42;#42;/#42;.xml, META-INF/cfg/config/#42;#42;/#42;.properties, META-INF/cfg/config/#42;#42;/#42;.ini</li>
+ *     <li>Files: defined by the system property -Dconfig.dir</li>
+ *     <li>system properties</li>
+ * </ul>
+ */
+public class FallbackSimpleConfigProvider implements ConfigurationProviderSpi {
+
+    private static final String DEFAULT_CONFIG_NAME = "default";
+
+    /**
+     * The loaded configuration instance.
+     */
+    private volatile Configuration configuration;
+
+    @Override
+    public String getConfigName() {
+        return DEFAULT_CONFIG_NAME;
+    }
+
+    @Override
+    public Configuration getConfiguration() {
+        Configuration cfg = configuration;
+        if (cfg == null) {
+            reload();
+            cfg = configuration;
+        }
+        return cfg;
+    }
+
+
+    @Override
+    public void reload() {
+        this.configuration = Configuration.from(
+                PropertySourceBuilder.of(DEFAULT_CONFIG_NAME)
+                        .addProviders(PropertySourceBuilder.of("CL default")
+                                .withAggregationPolicy(AggregationPolicy.LOG_ERROR)
+                                .addPaths("META-INF/cfg/default/**/*.xml", "META-INF/cfg/default/**/*.properties", "META-INF/cfg/default/**/*.ini")
+                                .build())
+                        .addProviders(PropertySourceBuilder.of("CL default")
+                                .withAggregationPolicy(AggregationPolicy.LOG_ERROR)
+                                .addPaths("META-INF/cfg/config/**/*.xml", "META-INF/cfg/config/**/*.properties", "META-INF/cfg/config/**/*.ini")
+                                .build())
+                        .addSystemProperties()
+                        .addEnvironmentProperties()
+                        .build());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileChangeListener.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileChangeListener.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileChangeListener.java
new file mode 100644
index 0000000..afd1199
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileChangeListener.java
@@ -0,0 +1,137 @@
+package org.apache.tamaya.core.internal.config;
+
+import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
+import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
+import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
+
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardWatchEventKinds;
+import java.nio.file.WatchEvent;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchService;
+import java.util.Map;
+import java.util.Objects;
+
+import org.apache.log4j.Logger;
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.core.spi.ConfigurationProviderSpi;
+
+/**
+ * Class that has the responsibility to watch the folder and then commit the {@link ConfigurationProviderSpi}
+ * to commit the Configuration from the properties or xml files, another ones will be ignored.
+ * @see FilesPropertiesConfigProvider
+ * This listener will wait to events and wait to one second to watch again.
+ * <p>If new file was created or modified will commit from this file.</p>
+ * <p>If a file was removed then the listener will load using all files left.</p>
+ * @author otaviojava
+ */
+class FileChangeListener implements Runnable {
+
+    private static final Logger LOGGER = Logger.getLogger(FileChangeListener.class);
+
+    private WatchService watchService;
+
+    private FileChangeObserver observer;
+
+    private Map<String, String> configurationMap;
+
+    private Path directory;
+
+    private FileReader fileReader = new FileReader();
+
+    public FileChangeListener(FileChangeObserver observer, Map<String, String> mapConfiguration, Path directory) {
+        this.observer = observer;
+        this.configurationMap = mapConfiguration;
+        this.directory = directory;
+        this.watchService = getWatchService();
+
+        if (Objects.nonNull(watchService) && Objects.nonNull(directory)) {
+            try {
+                directory.register(watchService, ENTRY_DELETE, ENTRY_MODIFY,
+                        ENTRY_CREATE);
+            } catch (IOException e) {
+                throw new FileChangeListenerException("An error happened when does try to registry to watch the folder", e);
+            }
+        }
+    }
+
+
+    @Override
+    public void run() {
+        if (Objects.isNull(watchService) || Objects.isNull(directory)) {
+            return;
+        }
+        while (true) {
+            watchFolder();
+        }
+    }
+
+
+    private void watchFolder() {
+        try {
+            WatchKey watckKey = watchService.take();
+            boolean needUpdate = false;
+            for (WatchEvent<?> event : watckKey.pollEvents()) {
+                Path keyDirectory = (Path) watckKey.watchable();
+                if(listenerPath(event, keyDirectory)) {
+                    needUpdate = true;
+                }
+            }
+
+            if (needUpdate) {
+                observer.update(configurationMap);
+            }
+            watckKey.reset();
+            Thread.sleep(1_000L);
+        } catch (Exception e) {
+            throw new FileChangeListenerException("An error happened when does try to watch the folder", e);
+        }
+    }
+
+    private boolean listenerPath(WatchEvent<?> event, Path keyDirectory) {
+        boolean wasModified = false;
+        Path path = keyDirectory.resolve((Path)event.context());
+        if(fileReader.isObservavleFile(path)) {
+
+            if (event.kind() == ENTRY_CREATE || event.kind() == ENTRY_MODIFY) {
+                wasModified = true;
+                configurationMap.putAll(fileReader.runFile(path.toAbsolutePath()));
+                LOGGER.info("An event was detected  in file: " + path.getFileName());
+            }
+
+            if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
+                wasModified = true;
+                configurationMap = fileReader.runFiles(directory);
+                LOGGER.info("A remotion event was detected  in file: " + path.getFileName());
+            }
+
+        } else {
+            LOGGER.info("Ignoring the file: " +  path.getFileName() + " because is not a properties or xml file");
+        }
+        return wasModified;
+    }
+
+    private WatchService getWatchService() {
+        try {
+            FileSystem fileSystem = Paths.get(".").getFileSystem();
+            return fileSystem.newWatchService();
+        } catch (IOException e) {
+            LOGGER.warn("This file System does not supports WatchService", e);
+            return null;
+        }
+
+    }
+
+    class FileChangeListenerException extends ConfigException {
+
+        private static final long serialVersionUID = -8965486770881001513L;
+
+        public FileChangeListenerException(String message, Throwable cause) {
+            super(message, cause);
+        }
+
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileChangeObserver.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileChangeObserver.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileChangeObserver.java
new file mode 100644
index 0000000..a7d4ba9
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileChangeObserver.java
@@ -0,0 +1,13 @@
+package org.apache.tamaya.core.internal.config;
+
+import java.util.Map;
+
+/**
+ * Observer to be used in {@link FileChangeListener} to commit all configurations and provider.
+ * @author otaviojava
+ */
+interface FileChangeObserver {
+
+    void update(Map<String, String> configurationMap);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileConfiguration.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileConfiguration.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileConfiguration.java
new file mode 100644
index 0000000..4f76180
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileConfiguration.java
@@ -0,0 +1,68 @@
+package org.apache.tamaya.core.internal.config;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+import org.apache.tamaya.Configuration;
+
+/**
+ * Implementation of Configuration which the information is from xml or properties files.
+ * Once the File modified, it will commit automatically by provider.
+ * @see FilesPropertiesConfigProvider
+ * @see FileChangeObserver
+ * @author otaviojava
+ */
+class FileConfiguration implements Configuration, FileChangeObserver {
+
+	private Map<String, String> configurationMap;
+
+	public FileConfiguration(Map<String, String> configurationMap) {
+        this.configurationMap = configurationMap;
+    }
+
+    @Override
+	public Optional<String> get(String key) {
+		return Optional.ofNullable(configurationMap.get(key));
+	}
+
+    @Override
+	public String getName() {
+		return "files.config";
+	}
+
+	@Override
+	public Map<String, String> getProperties() {
+		return configurationMap;
+	}
+
+    @Override
+    public void update(Map<String, String> configurationMap) {
+        synchronized (this) {
+            this.configurationMap = configurationMap;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "org.apache.tamaya.core.internal.config.FileConfiguration: " + configurationMap.toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(configurationMap);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if(this == obj) {
+            return true;
+        }
+        if(Configuration.class.isInstance(obj)) {
+            Configuration other = Configuration.class.cast(obj);
+            return Objects.equals(configurationMap, other.getProperties());
+        }
+
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileReader.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileReader.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileReader.java
new file mode 100644
index 0000000..287ccc4
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FileReader.java
@@ -0,0 +1,80 @@
+package org.apache.tamaya.core.internal.config;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.InvalidPropertiesFormatException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * Class to read a file and creates a {@link Map} of {@link String}.
+ * The implementation of {@link Map} will {@link HashMap}
+ * @author otaviojava
+ */
+class FileReader {
+
+    private static final String EXTENSIONS_ACCEPTED = "*.{xml,properties}";
+
+    public Map<String, String> runFiles(Path directory) {
+        Properties properties = createProperties(directory);
+        return properties
+                .stringPropertyNames()
+                .stream()
+                .collect(
+                        Collectors.toMap(Function.identity(),
+                                properties::getProperty));
+    }
+
+    public Map<String, String> runFile(Path path) {
+        Properties properties = new Properties();
+        try {
+            loadFile(properties, path);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return properties
+                .stringPropertyNames()
+                .stream()
+                .collect(
+                        Collectors.toMap(Function.identity(),
+                                properties::getProperty));
+    }
+
+    private Properties createProperties(Path directory) {
+        Properties properties = new Properties();
+
+            try {
+                for (Path path : Files.newDirectoryStream(directory, EXTENSIONS_ACCEPTED)) {
+                    loadFile(properties, path);
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        return properties;
+    }
+
+    private void loadFile(Properties properties, Path path) throws IOException,
+            InvalidPropertiesFormatException {
+        if (isXmlExtension(path)) {
+            properties.loadFromXML(Files.newInputStream(path));
+        } else {
+            properties.load(Files.newInputStream(path));
+        }
+}
+
+    private boolean isXmlExtension(Path path) {
+        return path.toString().toLowerCase().endsWith(".xml");
+    }
+
+    private boolean isPropertiesExtension(Path path) {
+        return path.toString().toLowerCase().endsWith(".properties");
+    }
+
+    public boolean isObservavleFile(Path path) {
+        return isPropertiesExtension(path) || isXmlExtension(path);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FilesPropertiesConfigProvider.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FilesPropertiesConfigProvider.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FilesPropertiesConfigProvider.java
new file mode 100644
index 0000000..c2cf7fa
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/FilesPropertiesConfigProvider.java
@@ -0,0 +1,97 @@
+package org.apache.tamaya.core.internal.config;
+
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.core.spi.ConfigurationProviderSpi;
+
+/**
+ *  This implementation run in a folder and once found xml and properties files
+ *  will create the Configuration, when one file is created, deleted or modified the configuration will commit
+ *  automatically.
+ * The default folder is META-INF/configuration, but you can change using the absolute path in
+ * "-Dtamaya.configbase" parameter.
+ * @author otaviojava
+ */
+public class FilesPropertiesConfigProvider implements ConfigurationProviderSpi, FileChangeObserver {
+
+    private static final String DEFAULT_CONFIG_NAME = "files.configuration";
+
+    private Map<String, String> configurationMap = Collections.emptyMap();
+
+    private ExecutorService executor = Executors.newSingleThreadExecutor();
+
+    private List<FileChangeObserver> fileChangeObservers = new ArrayList<>();
+
+    public FilesPropertiesConfigProvider() {
+        Path directory = getDirectory();
+        if (Objects.nonNull(directory)) {
+            configurationMap = new FileReader().runFiles(directory);
+            Runnable runnable = new FileChangeListener(this, configurationMap, directory);
+            executor.execute(runnable);
+        } else {
+            executor.shutdown();
+        }
+    }
+
+    @Override
+    public String getConfigName() {
+        return DEFAULT_CONFIG_NAME;
+    }
+
+    private Path getDirectory() {
+            String absolutePath = System.getProperty("tamaya.configbase");
+
+            if(Objects.nonNull(absolutePath)) {
+                Path path = Paths.get(absolutePath);
+                if(Files.isDirectory(path)) {
+                    return path;
+                }
+            }
+
+            URL resource = FilesPropertiesConfigProvider.class.getResource("/META-INF/configuration/");
+            if (Objects.nonNull(resource)) {
+                try {
+                    return Paths.get(resource.toURI());
+                } catch (URISyntaxException e) {
+                    throw new ConfigException("An error to find the directory to watch", e);
+                }
+            }
+            return null;
+    }
+
+
+    @Override
+    public Configuration getConfiguration() {
+      return new FileConfiguration(Collections.unmodifiableMap(configurationMap));
+    }
+
+    @Override
+    public void reload() {
+        Path directory = getDirectory();
+        if (Objects.nonNull(directory)) {
+            configurationMap = new FileReader().runFiles(directory);
+        }
+    }
+
+    @Override
+    public void update(Map<String, String> configurationMap) {
+        synchronized (this) {
+            this.configurationMap = configurationMap;
+            Map<String, String> unmodifiableMap = Collections.unmodifiableMap(configurationMap);
+            fileChangeObservers.forEach(fi -> fi.update(unmodifiableMap));
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/SystemPropertiesConfigProvider.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/SystemPropertiesConfigProvider.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/SystemPropertiesConfigProvider.java
new file mode 100644
index 0000000..cdd90b2
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/config/SystemPropertiesConfigProvider.java
@@ -0,0 +1,54 @@
+/*
+ * 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.config;
+
+import org.apache.tamaya.core.properties.PropertySourceBuilder;
+import org.apache.tamaya.core.spi.ConfigurationProviderSpi;
+
+import org.apache.tamaya.Configuration;
+
+/**
+ * Provides a {@link org.apache.tamaya.Configuration} named 'system.properties'
+ * containing the current system properties.
+ *
+ * Created by Anatole on 29.09.2014.
+ */
+public class SystemPropertiesConfigProvider implements ConfigurationProviderSpi{
+
+    private Configuration systemConfig;
+
+    public SystemPropertiesConfigProvider(){
+        systemConfig = Configuration.from(PropertySourceBuilder.of("system.properties").addSystemProperties().build());
+    }
+
+    @Override
+    public String getConfigName(){
+        return "system.properties";
+    }
+
+    @Override
+    public Configuration getConfiguration(){
+        return systemConfig;
+    }
+
+    @Override
+    public void reload() {
+        // nothing todo here
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/el/DefaultExpressionEvaluator.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/el/DefaultExpressionEvaluator.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/el/DefaultExpressionEvaluator.java
new file mode 100644
index 0000000..457aa6c
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/el/DefaultExpressionEvaluator.java
@@ -0,0 +1,144 @@
+/*
+ * 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.el;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.spi.ServiceContext;
+import org.apache.tamaya.core.spi.ExpressionEvaluator;
+import org.apache.tamaya.core.spi.ExpressionResolver;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Default expression evaluator that manages several instances of {@link org.apache.tamaya.core.spi.ExpressionResolver}.
+ * Each resolver is identified by a resolver id. Each expression passed has the form resolverId:resolverExpression, which
+ * has the advantage that different resolvers can be active in parallel.
+ */
+public final class DefaultExpressionEvaluator implements ExpressionEvaluator{
+
+    private Map<String, ExpressionResolver> resolvers = new ConcurrentHashMap<>();
+
+    private ExpressionResolver defaultResolver;
+
+    public DefaultExpressionEvaluator() {
+        for(ExpressionResolver resolver: ServiceContext.getInstance().getServices(ExpressionResolver.class)){
+            resolvers.put(resolver.getResolverId(), resolver);
+        }
+        defaultResolver = ServiceContext.getInstance().getSingleton(ExpressionResolver.class);
+    }
+
+    /**
+     * Resolves an expression in the form current <code>${resolverId:expression}</code>. The expression can be
+     * part current any type current literal text. Also multiple expression, with different resolver ids are supported.
+     * All control characters (${}\) can be escaped.<br>
+     * So all the following are valid expressions:
+     * <ul>
+     * <li><code>${resolverId:expression}</code></li>
+     * <li><code>bla bla ${resolverId:expression}</code></li>
+     * <li><code>${resolverId:expression} bla bla</code></li>
+     * <li><code>bla bla ${resolverId:expression} bla bla</code></li>
+     * <li><code>${resolverId:expression}${resolverId2:expression2}</code></li>
+     * <li><code>foo ${resolverId:expression}${resolverId2:expression2}</code></li>
+     * <li><code>foo ${resolverId:expression} bar ${resolverId2:expression2}</code></li>
+     * <li><code>${resolverId:expression}foo${resolverId2:expression2}bar</code></li>
+     * <li><code>foor${resolverId:expression}bar${resolverId2:expression2}more</code></li>
+     * <li><code>\${resolverId:expression}foo${resolverId2:expression2}bar</code> (first expression is escaped).</li>
+     * </ul>
+     *
+     * @param expression the expression to be evaluated, not null
+     * @param configurations overriding configurations to be used for evaluating the values for injection into {@code instance}.
+     *                If no such config is passed, the default configurations provided by the current
+     *                registered providers are used.
+     * @return the evaluated expression.
+     * @throws org.apache.tamaya.ConfigException if resolution fails.
+     */
+    @Override
+    public String evaluate(String expression, Configuration... configurations) {
+        StringTokenizer tokenizer = new StringTokenizer(expression, "${}\\", true);
+        boolean escaped = false;
+        StringBuilder resolvedValue = new StringBuilder();
+        StringBuilder current = new StringBuilder();
+        while (tokenizer.hasMoreTokens()) {
+            String token = tokenizer.nextToken();
+            if (escaped) {
+                switch (token) {
+                    case "n":
+                        current.append("\n");
+                        break;
+                    case "r":
+                        current.append("\r");
+                        break;
+                    case "t":
+                        current.append("\t");
+                        break;
+                    default:
+                        current.append(token);
+                        break;
+                }
+                escaped = false;
+                continue;
+            }
+            switch (token) {
+                case "\\":
+                    escaped = true;
+                    break;
+                case "$":
+                    if (current.length() > 0) {
+                        resolvedValue.append(current);
+                        current.setLength(0);
+                    }
+                    if (!"{".equals(tokenizer.nextToken())) {
+                        throw new ConfigException("Invalid expression encountered: " + expression);
+                    }
+                    String subExpression = tokenizer.nextToken();
+                    if (!"}".equals(tokenizer.nextToken())) {
+                        throw new ConfigException("Invalid expression encountered: " + expression);
+                    }
+                    // evaluate sub-expression
+                    current.append(evaluteInternal(subExpression));
+                    break;
+                default:
+                    current.append(token);
+            }
+        }
+        if (current.length() > 0) {
+            resolvedValue.append(current);
+        }
+        return resolvedValue.toString();
+    }
+
+    private String evaluteInternal(String subExpression) {
+        int sepPos = subExpression.indexOf(':');
+        if (sepPos > 0) {
+            String refID = subExpression.substring(0, sepPos);
+            String expression = subExpression.substring(sepPos + 1);
+            return Optional.ofNullable(this.resolvers.get(refID)).orElseThrow(
+                    () -> new ConfigException("Resolver not found: " + refID + " in " + subExpression)
+            ).resolve(expression);
+        } else {
+            return Optional.ofNullable(this.defaultResolver).orElseThrow(
+                    () -> new ConfigException("No default Resolver set, but required by " + subExpression)
+            ).resolve(subExpression);
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/el/EnvironmentPropertyResolver.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/el/EnvironmentPropertyResolver.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/el/EnvironmentPropertyResolver.java
new file mode 100644
index 0000000..68d37a4
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/el/EnvironmentPropertyResolver.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.core.internal.el;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.core.spi.ExpressionResolver;
+
+import java.util.Optional;
+
+/**
+ * Property resolver implementation that interprets the resolver expressions as environment properties.
+ */
+public final class EnvironmentPropertyResolver implements ExpressionResolver{
+
+    @Override
+    public String getResolverId() {
+        return "env";
+    }
+
+    @Override
+    public String resolve(String expression, Configuration... configurations){
+        return Optional.ofNullable(System.getenv(expression)).orElseThrow(
+                () -> new ConfigException("No such environment property: " + expression)
+        );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/el/SystemPropertyResolver.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/el/SystemPropertyResolver.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/el/SystemPropertyResolver.java
new file mode 100644
index 0000000..c6eb298
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/el/SystemPropertyResolver.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.core.internal.el;
+
+import java.util.Optional;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.core.spi.ExpressionResolver;
+
+/**
+ * Property resolver implementation that interprets the resolver expression as system property name.
+ */
+public final class SystemPropertyResolver implements ExpressionResolver{
+
+    @Override
+    public String getResolverId() {
+        return "sys";
+    }
+
+    @Override
+    public String resolve(String expression, Configuration... configurations){
+        return Optional.ofNullable(System.getProperty(expression)).orElseThrow(
+                () -> new ConfigException("No such system property: " + expression)
+        );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/format/DefaultConfigurationFormatSpi.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/format/DefaultConfigurationFormatSpi.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/format/DefaultConfigurationFormatSpi.java
new file mode 100644
index 0000000..eac0a3b
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/format/DefaultConfigurationFormatSpi.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.core.internal.format;
+
+import org.apache.tamaya.core.resource.Resource;
+import org.apache.tamaya.core.properties.ConfigurationFormat;
+import org.apache.tamaya.core.spi.ConfigurationFormatSpi;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import org.apache.tamaya.spi.ServiceContext;
+
+/**
+ * Singleton accessor to access registered reader mechanism.
+ */
+public final class DefaultConfigurationFormatSpi implements ConfigurationFormatSpi {
+
+    public ConfigurationFormat getFormat(String formatName){
+        Objects.requireNonNull(formatName);
+        try {
+            for (ConfigurationFormat configFormat : ServiceContext.getInstance().getServices(ConfigurationFormat.class)) {
+                if(formatName.equals(configFormat.getFormatName())){
+                    return configFormat;
+                }
+            }
+        } catch (Exception e) {
+            // TODO: handle exception
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public Collection<String> getFormatNames(){
+        Set<String> result = new HashSet<>();
+        try {
+            result.addAll(ServiceContext.getInstance().getServices(ConfigurationFormat.class).stream().map(ConfigurationFormat::getFormatName)
+                    .collect(Collectors.toList()));
+        } catch (Exception e) {
+            // TODO: handle exception
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+	public ConfigurationFormat getFormat(Resource resource) {
+        Objects.requireNonNull(resource);
+        try {
+            for (ConfigurationFormat configFormat : ServiceContext.getInstance().getServices(ConfigurationFormat.class)) {
+                if(configFormat.isAccepted(resource)){
+                    return configFormat;
+                }
+            }
+        } catch (Exception e) {
+            // TODO: handle exception
+            e.printStackTrace();
+        }
+        return null;
+	}
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/internal/format/IniFormat.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/internal/format/IniFormat.java b/dormant/core/src/main/java/org/apache/tamaya/core/internal/format/IniFormat.java
new file mode 100644
index 0000000..85ce778
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/internal/format/IniFormat.java
@@ -0,0 +1,98 @@
+/*
+ * 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.format;
+
+import org.apache.tamaya.core.resource.Resource;
+import org.apache.tamaya.core.properties.ConfigurationFormat;
+
+
+import org.apache.tamaya.ConfigException;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class IniFormat implements ConfigurationFormat{
+
+    private static final Logger LOG = Logger.getLogger(IniFormat.class.getName());
+
+
+    @Override
+    public String getFormatName(){
+        return "ini";
+    }
+
+    @Override
+    public boolean isAccepted(Resource resource){
+        String path = resource.getFilename();
+        return path != null && path.endsWith(".ini");
+    }
+
+    @Override
+    public Map<String,String> readConfiguration(Resource resource){
+        Map<String,String> result = new HashMap<>();
+        if(isAccepted(resource) && resource.exists()){
+            try(InputStream is = resource.getInputStream()){
+                BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+                String line = reader.readLine();
+                int lineNum = 0;
+                String section = null;
+                while(line != null){
+                    lineNum++;
+                    line = line.trim();
+                    if(line.isEmpty()){
+                        line = reader.readLine();
+                        continue;
+                    }
+                    if(line.trim().startsWith("#")){
+                        // comment
+                    }
+                    else if(line.startsWith("[")){
+                        int end = line.indexOf(']');
+                        if(end < 0){
+                            throw new ConfigException(
+                                    "Invalid INI-Format, ']' expected, at " + lineNum + " in " + resource);
+                        }
+                        section = line.substring(1, end);
+                    }
+                    else{
+                        int sep = line.indexOf('=');
+                        String key = line.substring(0,sep);
+                        String value = line.substring(sep+1);
+                        if(section!=null){
+                            result.put(section + '.' + key, value);
+                        }
+                        else{
+                            result.put(key, value);
+                        }
+                    }
+                    line = reader.readLine();
+                }
+            }
+            catch(Exception e){
+                LOG.log(Level.SEVERE, e, () -> "Could not read configuration: " + resource);
+            }
+        }
+        return result;
+    }
+
+}


Mime
View raw message