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 2016/03/14 00:59:03 UTC

[02/16] incubator-tamaya git commit: Simplified SPI/API.

Simplified SPI/API.


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

Branch: refs/heads/master
Commit: 8e9a3cc5c9cd0503f30574c8bb2b85c547145d27
Parents: c46ce36
Author: anatole <an...@apache.org>
Authored: Sun Mar 13 22:22:54 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Sun Mar 13 22:22:54 2016 +0100

----------------------------------------------------------------------
 modules/mutable-config/pom.xml                  |   7 +-
 .../mutableconfig/ChangePropagationPolicy.java  |  74 ++++
 .../mutableconfig/MutableConfiguration.java     | 119 ++++--
 .../MutableConfigurationProvider.java           | 291 +++++++++++++
 .../MutableConfigurationQuery.java              | 403 -------------------
 .../mutableconfig/ValueVisibilityPolicy.java    |  42 --
 .../internal/BasePropertySource.java            | 101 -----
 .../DefaultConfigurationBackendSpi.java         |  52 ---
 .../internal/DefaultMutableConfiguration.java   | 323 +++++++++++++++
 .../DefaultMutableConfigurationSpi.java         |  36 ++
 .../PropertiesFileConfigBackendSpi.java         | 114 ------
 .../internal/SimplePropertySource.java          | 163 --------
 .../XmlPropertiesFileConfigBackendSpi.java      | 114 ------
 .../AbstractMutablePropertySource.java          | 162 ++++++++
 .../MutablePropertiesPropertySource.java        | 194 +++++++++
 .../MutableXmlPropertiesPropertySource.java     | 195 +++++++++
 .../spi/AbstractMutableConfiguration.java       | 106 -----
 .../AbstractMutableConfigurationBackendSpi.java | 134 ------
 .../MutableConfigurationBackendProviderSpi.java |  37 --
 .../spi/MutableConfigurationBackendSpi.java     | 147 -------
 .../spi/MutableConfigurationProviderSpi.java    |  38 ++
 .../spi/MutablePropertySource.java              | 125 ++++++
 ...g.spi.MutableConfigurationBackendProviderSpi |  19 -
 ...leconfig.spi.MutableConfigurationProviderSpi |  19 +
 .../MutableConfigurationQueryTest.java          |  84 ----
 .../mutableconfig/MutableConfigurationTest.java | 177 ++++++++
 .../PropertiesFileConfigBackendTest.java        |  92 +----
 .../internal/WritablePropertiesSource.java      |  49 +++
 .../internal/WritableXmlPropertiesSource.java   |  49 +++
 .../org.apache.tamaya.spi.PropertySource        |  20 +
 30 files changed, 1857 insertions(+), 1629 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8e9a3cc5/modules/mutable-config/pom.xml
----------------------------------------------------------------------
diff --git a/modules/mutable-config/pom.xml b/modules/mutable-config/pom.xml
index 8223a3a..38cabbc 100644
--- a/modules/mutable-config/pom.xml
+++ b/modules/mutable-config/pom.xml
@@ -46,9 +46,14 @@ under the License.
         </dependency>
         <dependency>
             <groupId>org.apache.tamaya.ext</groupId>
-            <artifactId>tamaya-events</artifactId>
+            <artifactId>tamaya-spisupport</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <!--<dependency>-->
+        <!--<groupId>org.apache.tamaya.ext</groupId>-->
+        <!--<artifactId>tamaya-events</artifactId>-->
+        <!--<version>${project.version}</version>-->
+        <!--</dependency>-->
         <dependency>
             <groupId>org.apache.tamaya</groupId>
             <artifactId>tamaya-core</artifactId>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8e9a3cc5/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ChangePropagationPolicy.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ChangePropagationPolicy.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ChangePropagationPolicy.java
new file mode 100644
index 0000000..0986c08
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ChangePropagationPolicy.java
@@ -0,0 +1,74 @@
+/*
+ * 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.mutableconfig;
+
+import org.apache.tamaya.spi.PropertySource;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Policy that defines how changes are applied to the available
+ * {@link org.apache.tamaya.mutableconfig.spi.MutablePropertySource} instances, e.g.
+ * <ul>
+ *     <li><b>ALL: </b>Changes are propagated to all {@link org.apache.tamaya.mutableconfig.spi.MutablePropertySource}
+ *     instances in order of significance. This means that a key added, updated or removed in each instance, if the key
+ *     is writable/removable.</li>
+ *     <li><b>SIGNIFICANT_ONLY: </b>A change (creation, update) is only applied, if
+ * <ol>
+ *     <li>the value is not provided by a more significant read-only property source.</li>
+ *     <li>there is no more significant writable property source, which supports writing a g iven key.</li>
+ * </ol>
+ * In other words a added or updated value is written exactly once to the most significant
+ * writable property source, which accepts a given key. Otherwise the change is discarded.</li>
+ * <li><b>NONE: </b>Do not apply any changes.</li>
+ * </ul>
+ */
+public interface ChangePropagationPolicy {
+
+    /**
+     * Method being called when a multiple key/value pairs are added or updated.
+     * @param propertySources the property sources, including readable property sources of the current configuration,
+     *                        never null.
+     * @param transactionID the transaction ID, not null.
+     * @param changes the key/values being added or updated, not null.
+     */
+    void applyChanges(Collection<PropertySource> propertySources, UUID transactionID, Map<String,String> changes);
+
+    /**
+     * Method being called when a single key/value pair has been added or updated.
+     * @param propertySources the property sources, including readable property sources of the current configuration,
+     *                        never null.
+     * @param transactionID the transaction ID, not null.
+     * @param key the key, not null.
+     * @param value the value, not null.
+     */
+    void applyChange(Collection<PropertySource> propertySources, UUID transactionID, String key, String value);
+
+    /**
+     * Method being called when a multiple keys has been removed from the configuration.
+     * @param propertySources the property sources, including readable property sources of the current configuration,
+     *                        never null.
+     * @param transactionID the transaction ID, not null.
+     * @param keys the keys being removed, not null.
+     */
+    void applyRemove(Collection<PropertySource> propertySources, UUID transactionID, String... keys);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8e9a3cc5/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
index 4ad3d70..4108928 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
@@ -19,32 +19,96 @@
 package org.apache.tamaya.mutableconfig;
 
 import org.apache.tamaya.Configuration;
+import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
 
-import java.net.URI;
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
 
 /**
  * This interface extends the Configuration interface hereby adding methods to change configuration entries.
  * Hereby not all configuration entries are necessarily mutable, since some entries may be read from non
  * mutable areas of configuration. Of course, it is always possible to add a mutable shadow layer on top of all
- * configuration to enable whatever changes applied. The exact management and storage persistence algorithm should be
- * transparent.
+ * property sources to persist/control any changes applied. The exact management and storage persistence algorithm
+ * should be transparent.
  *
- * As a consequence clients should first check, using the corresponding methods, if entries are to edited or
- * removedProperties
- * actually are eligible for change/creation or removal.
+ * As a consequence clients should first check, using the corresponding methods, if entries can be added/updated or
+ * removed.
+ *
+ * This class should only used in a single threaded context, though all methods inherited from {@link Configuration}
+ * must be thread-safe. Methods handling configuration changes are expected to be used in a single threaded environment
+ * only. For multi-threaded us create a new instance of {@link MutableConfiguration} for each thread.
  */
 public interface MutableConfiguration extends Configuration {
 
     /**
+     * Starts a new transaction, if necessary, and returns the transaction id. New transaction are, similar to Java EE,
+     * bound to the current thread. As a consequences all properties added , updated or removed must be managed by
+     * a corresponding context, isolated by thread. The {@link MutablePropertySource} get the right transaction id
+     * passed, when writing (committing) any changes applied.
+     * @return the transaction id, not null.
+     */
+    UUID startTransaction();
+
+    /**
+     * Commits the request. After a commit the change is not editable anymore. All changes applied will be written to
+     * the corresponding configuration backend.
+     *
+     * NOTE that changes applied must not necessarily be visible in the current {@link Configuration} instance,
+     * since visibility of changes also depends on the ordinals set on the {@link org.apache.tamaya.spi.PropertySource}s
+     * configured.
+     * @throws org.apache.tamaya.ConfigException if the request already has been committed or cancelled, or the commit fails.
+     */
+    void commitTransaction();
+
+    /**
+     * Rollback any changes leaving everything unchanged. This will rollback all changes applied since the last commit.
+     */
+    void rollbackTransaction();
+
+    /**
+     * Get the current transaction id.
+     * @return the current transaction id, or null, if no transaction is active.
+     */
+    UUID getTransactionId();
+
+    /**
+     * Get the current autoCommit policy. AutoCommit will commit the transaction after each change applied.
+     * @return the current autoCommit policy, by default false.
+     */
+    boolean getAutoCommit();
+
+    /**
+     * Set the {@link ChangePropagationPolicy}.
+     * @see #getChangePropagationPolicy()
+     * @param changePropagationPolicy the policy, not null.
+     */
+    void setChangePropagationPolicy(ChangePropagationPolicy changePropagationPolicy);
+
+    /**
+     * Access the active {@link ChangePropagationPolicy}.This policy controls how configuration changes are written/published
+     * to the known {@link MutablePropertySource} instances of a {@link Configuration}.
+     * @return he active {@link ChangePropagationPolicy}, never null.
+     */
+    ChangePropagationPolicy getChangePropagationPolicy();
+
+    /**
+     * Set the autoCommit policy to be used for this configuration instance.
+     * @param autoCommit the new autoCommit policy.
+     * @throws IllegalStateException when there are uncommitted changes.
+     */
+    void setAutoCommit(boolean autoCommit);
+
+
+    /**
      * Identifies the configuration backend that are targeted by this instance and which are
      * also responsible for writing back the changes applied.
      *
-     * @return the backend URI, never null.
+     * @return the property sources identified, in order of their occurrence/priority (most significant first).
      */
-    URI getBackendURI();
+    List<MutablePropertySource> getMutablePropertySources();
 
     /**
      * Checks if a configuration key is writable (or it can be added).
@@ -56,6 +120,14 @@ public interface MutableConfiguration extends Configuration {
     boolean isWritable(String keyExpression);
 
     /**
+     * Identifies the configuration backends that supports writing the given key(s).
+     * @param keyExpression the key to be checked for write access (including creation), not null. Here this could also
+     *                      be a regular expression, such "as a.b.c.*".
+     * @return @return the property sources identified, in order of their occurrence/priority (most significant first).
+     */
+    List<MutablePropertySource> getPropertySourcesThatCanWrite(String keyExpression);
+
+    /**
      * Checks if a configuration key is removable. This also implies that it is writable, but there might be writable
      * keys that cannot be removedProperties.
      *
@@ -67,6 +139,14 @@ public interface MutableConfiguration extends Configuration {
     boolean isRemovable(String keyExpression);
 
     /**
+     * Identifies the configuration backend that know the given key(s) and support removing it/them.
+     * @param keyExpression the key to be checked for write access (including creation), not null. Here this could also
+     *                      be a regular expression, such "as a.b.c.*".
+     * @return @return the property sources identified, in order of their occurrence/priority (most significant first).
+     */
+    List<MutablePropertySource> getPropertySourcesThatCanRemove(String keyExpression);
+
+    /**
      * Checks if any keys of the given type already exist in the write backend. <b>NOTE:</b> there may be backends that
      * are not able to support lookups with regular expressions. In most such cases you should pass the keys to
      * lookup explicitly.
@@ -78,6 +158,14 @@ public interface MutableConfiguration extends Configuration {
     boolean isExisting(String keyExpression);
 
     /**
+     * Identifies the configuration backend that know the given key(s).
+     * @param keyExpression the key to be checked for write access (including creation), not null. Here this could also
+     *                      be a regular expression, such "as a.b.c.*".
+     * @return @return the property sources identified, in order of their occurrence/priority (most significant first).
+     */
+    List<MutablePropertySource> getPropertySourcesThatKnow(String keyExpression);
+
+    /**
      * Sets a property.
      *
      * @param key   the property's key, not null.
@@ -133,20 +221,5 @@ public interface MutableConfiguration extends Configuration {
      */
     MutableConfiguration remove(String... keys);
 
-    /**
-     * Commits the request. After a commit the change is not editable anymore. All changes applied will be written to
-     * the corresponding configuration backend.
-     *
-     * NOTE that changes applied must not necessarily be visible in the current {@link Configuration} instance,
-     * since visibility of changes also depends on the ordinals set on the {@link org.apache.tamaya.spi.PropertySource}s
-     * configured.
-     * @throws org.apache.tamaya.ConfigException if the request already has been committed or cancelled, or the commit fails.
-     */
-    void commit();
-
-    /**
-     * Rollback any changes leaving everything unchanged. This will rollback all changes applied since the last commit.
-     */
-    void rollback();
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8e9a3cc5/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationProvider.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationProvider.java
new file mode 100644
index 0000000..56c0e2a
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationProvider.java
@@ -0,0 +1,291 @@
+/*
+ * 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.mutableconfig;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.mutableconfig.spi.MutableConfigurationProviderSpi;
+import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.logging.Logger;
+
+
+/**
+ * Accessor for creating {@link MutableConfiguration} instances to change configuration and commit changes.
+ */
+public final class MutableConfigurationProvider {
+
+    private static final Logger LOG = Logger.getLogger(MutableConfigurationProvider.class.getName());
+    /**
+     * URIs used by this query instance to identify the backends to use for write operations.
+     */
+    private static final MutableConfigurationProviderSpi mutableConfigurationProviderSpi = loadSpi();
+
+    /**
+     * SPI loader method.
+     * @throws ConfigException if loading fails.
+     * @return the SPI, never null.
+     */
+    private static MutableConfigurationProviderSpi loadSpi() {
+        try{
+            return ServiceContextManager.getServiceContext().getService(
+                    MutableConfigurationProviderSpi.class)  ;      }
+        catch(Exception e){
+            throw new ConfigException("Failed to initialize MutableConfigurationProviderSpi - " +
+                    "mutable configuration support.");
+        }
+    }
+
+
+    /** Singleton constructor. */
+    private MutableConfigurationProvider(){}
+
+    /**
+     * Creates a new {@link MutableConfiguration} for the given configuration, using all
+     * {@link MutablePropertySource} instances found in its context and {@code autoCommit = true}.
+     *
+     * @param configuration the configuration to use to write the changes/config.
+     * @return a new MutableConfiguration instance
+     */
+    public static MutableConfiguration getMutableConfiguration(Configuration configuration){
+        return mutableConfigurationProviderSpi.createMutableConfiguration(configuration);
+    }
+
+    /**
+     * This propagation policy writes through all changes to all mutable property sources, where applicable.
+     * This is also the default policy.
+     */
+    public static ChangePropagationPolicy getApplyAllChangePolicy(){
+        return ALL_POLICY;
+    }
+
+    /**
+     * This propagation policy writes changes only once to the most significant property source, where a change is
+     * applicable.
+     */
+    public static ChangePropagationPolicy getApplyMostSignificantOnlyChangePolicy(){
+        return MOST_SIGNIFICANT_ONLY_POLICY;
+    }
+
+    /**
+     * This propagation policy writes changes only once to the most significant property source, where a change is
+     * applicable.
+     * @param propertySourceNames the names of the mutable property sources to be considered for writing any changes to.
+     */
+    public static ChangePropagationPolicy getApplySelectiveChangePolicy(String... propertySourceNames){
+        return new SelectiveChangeApplyPolicy(propertySourceNames);
+    }
+
+    /**
+     * This propagation policy writes changes only once to the most significant property source, where a change is
+     * applicable.
+     */
+    public static ChangePropagationPolicy getApplyNonePolicy(){
+        return NONE_POLICY;
+    }
+
+    /**
+     * This propagation policy writes through all changes to all mutable property sources, where applicable.
+     */
+    private static final ChangePropagationPolicy ALL_POLICY = new ChangePropagationPolicy() {
+        @Override
+        public void applyChanges(Collection<PropertySource> propertySources, UUID transactionID,
+                                 Map<String, String> changes) {
+            for(PropertySource propertySource: propertySources){
+                if(propertySource instanceof MutablePropertySource){
+                    MutablePropertySource target = (MutablePropertySource)propertySource;
+                    for(Map.Entry<String,String> en:changes.entrySet()) {
+                        if (target.isWritable(en.getKey())) {
+                            target.put(transactionID, en.getKey(), en.getValue());
+                        }
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void applyChange(Collection<PropertySource> propertySources, UUID transactionID,
+                                String key, String value) {
+            for(PropertySource propertySource: propertySources){
+                if(propertySource instanceof MutablePropertySource){
+                    MutablePropertySource target = (MutablePropertySource)propertySource;
+                    if (target.isWritable(key)) {
+                        target.put(transactionID, key, value);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void applyRemove(Collection<PropertySource> propertySources, UUID transactionID,
+                                String... keys) {
+            for(PropertySource propertySource: propertySources){
+                if(propertySource instanceof MutablePropertySource){
+                    MutablePropertySource target = (MutablePropertySource)propertySource;
+                    for(String key:keys) {
+                        if (target.isRemovable(key)) {
+                            target.remove(transactionID, key);
+                        }
+                    }
+                }
+            }
+        }
+    };
+
+    /**
+     * This propagation policy writes changes only once to the most significant property source, where a change is
+     * applicable.
+     */
+    private static final ChangePropagationPolicy MOST_SIGNIFICANT_ONLY_POLICY = new ChangePropagationPolicy() {
+        @Override
+        public void applyChanges(Collection<PropertySource> propertySources, UUID transactionID,
+                                 Map<String, String> changes) {
+            changes:for(Map.Entry<String,String> en:changes.entrySet()) {
+                for(PropertySource propertySource: propertySources){
+                    if(propertySource instanceof MutablePropertySource){
+                        MutablePropertySource target = (MutablePropertySource)propertySource;
+                        if (target.isWritable(en.getKey())) {
+                            target.put(transactionID, en.getKey(), en.getValue());
+                            continue changes;
+                        }
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void applyChange(Collection<PropertySource> propertySources, UUID transactionID,
+                                String key, String value) {
+            for(PropertySource propertySource: propertySources){
+                if(propertySource instanceof MutablePropertySource){
+                    MutablePropertySource target = (MutablePropertySource)propertySource;
+                    if (target.isWritable(key)) {
+                        target.put(transactionID, key, value);
+                        return;
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void applyRemove(Collection<PropertySource> propertySources, UUID transactionID,
+                                String... keys) {
+            keys:for(String key:keys) {
+                for(PropertySource propertySource: propertySources){
+                    if(propertySource instanceof MutablePropertySource){
+                        MutablePropertySource target = (MutablePropertySource)propertySource;
+                        if (target.isRemovable(key)) {
+                            target.remove(transactionID, key);
+                            continue keys;
+                        }
+                    }
+                }
+            }
+        }
+    };
+
+    /**
+     * This propagation policy writes changes only once to the most significant property source, where a change is
+     * applicable.
+     */
+    private static final ChangePropagationPolicy NONE_POLICY = new ChangePropagationPolicy() {
+        @Override
+        public void applyChanges(Collection<PropertySource> propertySources, UUID transactionID, Map<String, String> changes) {
+        }
+
+        @Override
+        public void applyChange(Collection<PropertySource> propertySources, UUID transactionID, String key, String value) {
+        }
+
+        @Override
+        public void applyRemove(Collection<PropertySource> propertySources, UUID transactionID, String... keys) {
+        }
+    };
+
+    /**
+     * This propagation policy writes through all changes to all mutable property sources, where applicable.
+     */
+    private static final class SelectiveChangeApplyPolicy implements ChangePropagationPolicy {
+
+        private Set<String> propertySourceNames = new HashSet<>();
+
+        SelectiveChangeApplyPolicy(String... propertySourceNames){
+            this.propertySourceNames.addAll(Arrays.asList(propertySourceNames));
+        }
+
+        @Override
+        public void applyChanges(Collection<PropertySource> propertySources, UUID transactionID,
+                                 Map<String, String> changes) {
+            for(PropertySource propertySource: propertySources){
+                if(propertySource instanceof MutablePropertySource){
+                    if(this.propertySourceNames.contains(propertySource.getName())) {
+                        MutablePropertySource target = (MutablePropertySource) propertySource;
+                        for (Map.Entry<String, String> en : changes.entrySet()) {
+                            if (target.isWritable(en.getKey())) {
+                                target.put(transactionID, en.getKey(), en.getValue());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void applyChange(Collection<PropertySource> propertySources, UUID transactionID,
+                                String key, String value) {
+            for(PropertySource propertySource: propertySources){
+                if(propertySource instanceof MutablePropertySource){
+                    if(this.propertySourceNames.contains(propertySource.getName())) {
+                        MutablePropertySource target = (MutablePropertySource) propertySource;
+                        if (target.isWritable(key)) {
+                            target.put(transactionID, key, value);
+                        }
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void applyRemove(Collection<PropertySource> propertySources, UUID transactionID,
+                                String... keys) {
+            for(PropertySource propertySource: propertySources){
+                if(propertySource instanceof MutablePropertySource){
+                    if(this.propertySourceNames.contains(propertySource.getName())) {
+                        MutablePropertySource target = (MutablePropertySource) propertySource;
+                        for (String key : keys) {
+                            if (target.isRemovable(key)) {
+                                target.remove(transactionID, key);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    };
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8e9a3cc5/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationQuery.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationQuery.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationQuery.java
deleted file mode 100644
index fc7f6cc..0000000
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationQuery.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.mutableconfig;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.ConfigOperator;
-import org.apache.tamaya.ConfigQuery;
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.ConfigurationProvider;
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.mutableconfig.spi.AbstractMutableConfiguration;
-import org.apache.tamaya.mutableconfig.spi.MutableConfigurationBackendSpi;
-import org.apache.tamaya.mutableconfig.spi.MutableConfigurationBackendProviderSpi;
-import org.apache.tamaya.spi.ConversionContext;
-import org.apache.tamaya.spi.PropertyConverter;
-import org.apache.tamaya.spi.PropertyValue;
-import org.apache.tamaya.spi.ServiceContextManager;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-
-/**
- * Accessor for creating {@link MutableConfiguration} instances to change configuration and commit changes.
- */
-public final class MutableConfigurationQuery implements ConfigQuery<MutableConfiguration> {
-
-    /**
-     * URIs used by this query instance to identify the backends to use for write operations.
-     */
-    private final MutableConfigurationBackendSpi target;
-
-    private ValueVisibilityPolicy valueVisibilityPolicy;
-
-    /** Singleton constructor. */
-    private MutableConfigurationQuery(MutableConfigurationBackendSpi target, ValueVisibilityPolicy valueVisibilityPolicy){
-        this.target = Objects.requireNonNull(target);
-        this.valueVisibilityPolicy = valueVisibilityPolicy;
-    }
-
-    @Override
-    public MutableConfiguration query(Configuration config) {
-        return new DefaultMutableConfiguration(target, valueVisibilityPolicy, config);
-    }
-
-    /**
-     * Creates a new {@link MutableConfigurationQuery} for the given configuration target.
-     *
-     * @param configurationTarget the configuration targets (String to create URIs) to use to write the changes/config. By passing multiple
-     *                             URIs you can write back changes into multiple configuration backends, e.g.
-     *                             one for redistributing changes using multicast mechanism, a local property file
-     *                             for failover as well as the shared etcd server.
-     * @return a new ChangeRequest
-     * @throws org.apache.tamaya.ConfigException if the given configurationSource cannot be edited.
-     */
-    public static MutableConfigurationQuery of(String configurationTarget){
-        return of(configurationTarget, ValueVisibilityPolicy.CONFIG);
-    }
-
-    /**
-     * Creates a new {@link MutableConfigurationQuery} for the given configuration target and visibility policy.
-     *
-     * @param configurationTarget the configuration targets (String to create URIs) to use to write the changes/config. By passing multiple
-     *                             URIs you can write back changes into multiple configuration backends, e.g.
-     *                             one for redistributing changes using multicast mechanism, a local property file
-     *                             for failover as well as the shared etcd server.
-     * @param valueVisibilityPolicy the policy that defines how values edited, added or removed are reflected in the read
-     *                         accesses of the {@link MutableConfiguration} created.
-     * @return a new ChangeRequest
-     * @throws org.apache.tamaya.ConfigException if the given configurationSource cannot be edited.
-     */
-    public static MutableConfigurationQuery of(String configurationTarget, ValueVisibilityPolicy valueVisibilityPolicy){
-        try {
-            URI uri = new URI(configurationTarget);
-            return of(uri, valueVisibilityPolicy);
-        } catch(URISyntaxException e){
-            throw new ConfigException("Invalid URI " + configurationTarget);
-        }
-    }
-
-    /**
-     * Creates a new {@link MutableConfigurationQuery} for the given configuration target.
-     *
-     * @param configurationTarget the configuration targets to use to write the changes/config. By passing multiple
-     *                             URIs you can write back changes into multiple configuration backends, e.g.
-     *                             one for redistributing changes using multicast mechanism, a local property file
-     *                             for failover as well as the shared etcd server.
-     * @return a new ChangeRequest
-     * @throws org.apache.tamaya.ConfigException if the given configurationSource cannot be edited.
-     */
-    public static MutableConfigurationQuery of(URI configurationTarget){
-        return of(configurationTarget, ValueVisibilityPolicy.CONFIG);
-    }
-    /**
-     * Creates a new {@link MutableConfigurationQuery} for the given configuration target and visibility policy.
-     *
-     * @param configurationTarget the configuration targets to use to write the changes/config. By passing multiple
-     *                             URIs you can write back changes into multiple configuration backends, e.g.
-     *                             one for redistributing changes using multicast mechanism, a local property file
-     *                             for failover as well as the shared etcd server.
-     * @param valueVisibilityPolicy the policy that defines how values edited, added or removed are reflected in the read
-     *                         accesses of the {@link MutableConfiguration} created.
-     * @return a new ChangeRequest
-     * @throws org.apache.tamaya.ConfigException if the given configurationSource cannot be edited.
-     */
-    public static MutableConfigurationQuery of(URI configurationTarget, ValueVisibilityPolicy valueVisibilityPolicy){
-        MutableConfigurationBackendSpi target = null;
-        for(MutableConfigurationBackendProviderSpi spi:ServiceContextManager.getServiceContext()
-                .getServices(MutableConfigurationBackendProviderSpi.class)){
-            MutableConfigurationBackendSpi req = spi.getBackend(Objects.requireNonNull(configurationTarget));
-            if (req != null) {
-                target = req;
-                break;
-            }
-        }
-        if(target==null) {
-            throw new ConfigException("Not an editable configuration target: " +
-                    configurationTarget);
-        }
-        return new MutableConfigurationQuery(target, Objects.requireNonNull(valueVisibilityPolicy));
-    }
-
-
-
-    /**
-     * Creates a new {@link MutableConfiguration} for the given configuration target.
-     *
-     * @param configurationTarget the configuration targets (String to create URIs) to use to write the changes/config. By passing multiple
-     *                             URIs you can write back changes into multiple configuration backends, e.g.
-     *                             one for redistributing changes using multicast mechanism, a local property file
-     *                             for failover as well as the shared etcd server.
-     * @return a new ChangeRequest
-     * @throws org.apache.tamaya.ConfigException if the given configurationSource cannot be edited.
-     */
-    public static MutableConfiguration createMutableConfiguration(String configurationTarget){
-        return createMutableConfiguration(configurationTarget, ValueVisibilityPolicy.CONFIG);
-    }
-
-    /**
-     * Creates a new {@link MutableConfiguration} for the given configuration target and visibility policy.
-     *
-     * @param configurationTarget the configuration targets (String to create URIs) to use to write the changes/config. By passing multiple
-     *                             URIs you can write back changes into multiple configuration backends, e.g.
-     *                             one for redistributing changes using multicast mechanism, a local property file
-     *                             for failover as well as the shared etcd server.
-     * @param valueVisibilityPolicy the policy that defines how values edited, added or removed are reflected in the read
-     *                         accesses of the {@link MutableConfiguration} created.
-     * @return a new ChangeRequest
-     * @throws org.apache.tamaya.ConfigException if the given configurationSource cannot be edited.
-     */
-    public static MutableConfiguration createMutableConfiguration(String configurationTarget,
-                                                                  ValueVisibilityPolicy valueVisibilityPolicy){
-        try {
-            URI uri = new URI(configurationTarget);
-            return createMutableConfiguration(uri, valueVisibilityPolicy);
-        } catch(URISyntaxException e){
-            throw new ConfigException("Invalid URI " + configurationTarget);
-        }
-    }
-
-    /**
-     * Creates a new {@link MutableConfiguration} for the given configuration target.
-     *
-     * @param configurationTarget the configuration targets to use to write the changes/config. By passing multiple
-     *                             URIs you can write back changes into multiple configuration backends, e.g.
-     *                             one for redistributing changes using multicast mechanism, a local property file
-     *                             for failover as well as the shared etcd server.
-     * @return a new ChangeRequest
-     * @throws org.apache.tamaya.ConfigException if the given configurationSource cannot be edited.
-     */
-    public static MutableConfiguration createMutableConfiguration(URI configurationTarget){
-        return createMutableConfiguration(configurationTarget, ValueVisibilityPolicy.CONFIG);
-    }
-    /**
-     * Creates a new {@link MutableConfiguration} for the given configuration target and visibility policy.
-     *
-     * @param configurationTarget the configuration targets to use to write the changes/config. By passing multiple
-     *                             URIs you can write back changes into multiple configuration backends, e.g.
-     *                             one for redistributing changes using multicast mechanism, a local property file
-     *                             for failover as well as the shared etcd server.
-     * @param valueVisibilityPolicy the policy that defines how values edited, added or removed are reflected in the read
-     *                         accesses of the {@link MutableConfiguration} created.
-     * @return a new ChangeRequest
-     * @throws org.apache.tamaya.ConfigException if the given configurationSource cannot be edited.
-     */
-    public static MutableConfiguration createMutableConfiguration(URI configurationTarget,
-                                                                  ValueVisibilityPolicy valueVisibilityPolicy){
-        return Configuration.EMPTY.query(of(configurationTarget, valueVisibilityPolicy));
-    }
-
-
-    /**
-     * Compound request that contains internally multiple change requests. Changes are committed to all members.
-     */
-    private static final class DefaultMutableConfiguration extends AbstractMutableConfiguration
-            implements MutableConfiguration {
-
-        private final MutableConfigurationBackendSpi target;
-        private final Configuration config;
-        private ValueVisibilityPolicy valueVisibilityPolicy;
-
-        DefaultMutableConfiguration(MutableConfigurationBackendSpi target, ValueVisibilityPolicy valueVisibilityPolicy, Configuration config){
-            this.target = Objects.requireNonNull(target);
-            this.config = Objects.requireNonNull(config);
-            this.valueVisibilityPolicy = valueVisibilityPolicy;
-        }
-
-        @Override
-        public URI getBackendURI() {
-            return target.getBackendURI();
-        }
-
-        @Override
-        public boolean isWritable(String keyExpression) {
-            return target.isWritable(keyExpression);
-        }
-
-        @Override
-        public boolean isRemovable(String keyExpression) {
-            return target.isRemovable(keyExpression);
-        }
-
-        @Override
-        public boolean isExisting(String keyExpression) {
-            return target.isExisting(keyExpression);
-        }
-
-        @Override
-        public MutableConfiguration put(String key, String value) {
-            if(target.isWritable(key)){
-                target.put(key, value);
-            }
-            return this;
-        }
-
-        @Override
-        public MutableConfiguration putAll(Map<String, String> properties) {
-            for(Map.Entry<String,String> en:properties.entrySet()) {
-                if (target.isWritable(en.getKey())) {
-                    target.put(en.getKey(), en.getValue());
-                }
-            }
-            return super.putAll(properties);
-        }
-
-        @Override
-        public MutableConfiguration remove(String... keys) {
-            for(String key:keys){
-                if (target.isRemovable(key)) {
-                    target.remove(key);
-                }
-            }
-            return super.remove(keys);
-        }
-
-        @Override
-        public MutableConfiguration remove(Collection<String> keys) {
-            for(String key:keys){
-                if (target.isRemovable(key)) {
-                    target.remove(key);
-                }
-            }
-            return super.remove(keys);
-        }
-
-        @Override
-        protected void commitInternal() {
-            target.commit();
-        }
-
-        @Override
-        public String get(String key) {
-            String addedOrUpdated = this.addedProperties.get(key);
-            switch(valueVisibilityPolicy){
-                case CHANGES:
-                    boolean removed = this.removedProperties.contains(key);
-                    if(removed){
-                        return null;
-                    }
-                    return addedOrUpdated!=null?addedOrUpdated:getInternal(key);
-                case CONFIG:
-                default:
-                    String val = getInternal(key);
-                    return val == null?addedOrUpdated:val;
-            }
-        }
-
-        private String getInternal(String key) {
-           Map<String,String> props = this.config.getProperties();
-            if(props.isEmpty()){
-                PropertyValue val = this.target.getBackendPropertySource().get(key);
-                if(val!=null){
-                    return val.getValue();
-                }
-            }
-            return this.config.get(key);
-        }
-
-        @Override
-        public String getOrDefault(String key, String defaultValue) {
-            String val = get(key);
-            return val == null? defaultValue: val;
-        }
-
-        @Override
-        public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
-            return (T)getOrDefault(key, TypeLiteral.of(type), defaultValue);
-        }
-
-        @Override
-        public <T> T get(String key, Class<T> type) {
-            return getOrDefault(key, type, (T)null);
-        }
-
-        @Override
-        public <T> T get(String key, TypeLiteral<T> type) {
-            return getOrDefault(key, type, (T)null);
-        }
-
-        @Override
-        public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) {
-            String val = get(key);
-            if(val==null) {
-                return defaultValue;
-            }
-            for(PropertyConverter conv: ConfigurationProvider.getConfigurationContext().getPropertyConverters(type)){
-                Object o = conv.convert(val, new ConversionContext.Builder(key, type).setConfiguration(config).build());
-                if(o!=null){
-                    return (T) o;
-                }
-            }
-            return defaultValue;
-        }
-
-        @Override
-        public Map<String, String> getProperties() {
-            Map<String, String> configProps = new HashMap<>();
-            if(config.getProperties().isEmpty()) {
-                configProps.putAll(target.getBackendPropertySource().getProperties());
-            }else{
-                configProps.putAll(config.getProperties());
-            }
-            switch(valueVisibilityPolicy){
-                case CHANGES:
-                    for(String key:removedProperties){
-                        configProps.remove(key);
-                    }
-                    configProps.putAll(addedProperties);
-                    return configProps;
-                case CONFIG:
-                default:
-                    Map<String, String> props = new HashMap<>(addedProperties);
-                    for(String key:removedProperties){
-                        props.remove(key);
-                    }
-                    props.putAll(configProps);
-                    return props;
-            }
-        }
-
-        @Override
-        public Configuration with(ConfigOperator operator) {
-            return operator.operate(this);
-        }
-
-        @Override
-        public <T> T query(ConfigQuery<T> query) {
-            if(query instanceof MutableConfigurationQuery){
-                throw new ConfigException("Cannot query a mutable configuration, already is one!");
-            }
-            return query.query(this);
-        }
-
-        @Override
-        public String toString() {
-            return "DefaultMutableConfiguration{" +
-                    "config=" + config +
-                    ", target=" + target +
-                    '}';
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8e9a3cc5/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ValueVisibilityPolicy.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ValueVisibilityPolicy.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ValueVisibilityPolicy.java
deleted file mode 100644
index 841a65d..0000000
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ValueVisibilityPolicy.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.mutableconfig;
-
-/**
- * Policy that can be passed when creating a {@link MutableConfigurationQuery} to define how existing values from
- * the base configuration should be handled. The corresponding behaviour is immedeately active, it does not
- * require a {@code commit()}. Nevertheless cleaning up all changes will reverse any changes and also related
- * effects.
- */
-public enum ValueVisibilityPolicy {
-
-    /**
-     * Entries added are also added to the mutable configuration for read access before committed. This is also
-     * the default policy used.
-     */
-    CONFIG,
-
-    /**
-     * Entries from the base configuration are hidden or overridden by the entries edited. This gives you the best
-     * control on your changes applied, but probably will not match the behaviour of your default configuration,
-     * since the effective ordinals of your PropertySources may determine other overriding behaviour.
-     */
-    CHANGES
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8e9a3cc5/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/BasePropertySource.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/BasePropertySource.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/BasePropertySource.java
deleted file mode 100644
index 2fe87df..0000000
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/BasePropertySource.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.mutableconfig.internal;
-
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertyValue;
-import org.apache.tamaya.spi.PropertyValueBuilder;
-
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Abstract {@link PropertySource} that allows to set a default ordinal that will be used, if no
- * ordinal is provided with the config.
- */
-abstract class BasePropertySource implements PropertySource{
-    /** default ordinal that will be used, if no ordinal is provided with the config. */
-    private final int defaultOrdinal;
-
-    /**
-     * Constructor.
-     * @param defaultOrdinal default ordinal that will be used, if no ordinal is provided with the config.
-     */
-    protected BasePropertySource(int defaultOrdinal){
-        this.defaultOrdinal = defaultOrdinal;
-    }
-
-    /**
-     * Constructor, using a default ordinal of 0.
-     */
-    protected BasePropertySource(){
-        this(0);
-    }
-
-    @Override
-    public String getName() {
-        return getClass().getSimpleName();
-    }
-
-    @Override
-    public int getOrdinal() {
-        PropertyValue configuredOrdinal = get(TAMAYA_ORDINAL);
-
-        if(configuredOrdinal!=null){
-            try {
-                return Integer.parseInt(configuredOrdinal.getValue());
-            } catch (Exception e) {
-                Logger.getLogger(getClass().getName()).log(Level.WARNING,
-                        "Configured Ordinal is not an int number: " + configuredOrdinal.getValue(), e);
-            }
-        }
-        return getDefaultOrdinal();
-    }
-
-    /**
-     * Returns the  default ordinal used, when no ordinal is set, or the ordinal was not parseable to an int value.
-     * @return the  default ordinal used, by default 0.
-     */
-    public int getDefaultOrdinal(){
-        return defaultOrdinal;
-    }
-
-    @Override
-    public PropertyValue get(String key) {
-        Map<String,String> properties = getProperties();
-        String val = properties.get(key);
-        if(val==null){
-            return null;
-        }
-        PropertyValueBuilder b = new PropertyValueBuilder(key, val, getName());
-        String metaKeyStart = "_" + key + ".";
-        for(Map.Entry<String,String> en:properties.entrySet()) {
-            if(en.getKey().startsWith(metaKeyStart)){
-                b.addContextData(en.getKey().substring(metaKeyStart.length()), en.getValue());
-            }
-        }
-        return b.build();
-    }
-
-    @Override
-    public boolean isScannable(){
-        return true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8e9a3cc5/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultConfigurationBackendSpi.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultConfigurationBackendSpi.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultConfigurationBackendSpi.java
deleted file mode 100644
index cfdfe29..0000000
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultConfigurationBackendSpi.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.mutableconfig.internal;
-
-import org.apache.tamaya.mutableconfig.spi.MutableConfigurationBackendSpi;
-import org.apache.tamaya.mutableconfig.spi.MutableConfigurationBackendProviderSpi;
-
-import java.io.File;
-import java.net.URI;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Mutable Config Request factory that tries to convert given URIs to file references, if successful, it returns
- * ConfigChangeRequests fir .properties and .xml files.
- */
-public class DefaultConfigurationBackendSpi implements MutableConfigurationBackendProviderSpi {
-
-    private static final Logger LOG = Logger.getLogger(DefaultConfigurationBackendSpi.class.getName());
-
-    @Override
-    public MutableConfigurationBackendSpi getBackend(URI uri) {
-        try{
-            File f = new File(uri);
-            if(f.getName().endsWith(".properties")){
-                return new PropertiesFileConfigBackendSpi(f);
-            }else if(f.getName().endsWith(".xml")){
-                return new XmlPropertiesFileConfigBackendSpi(f);
-            }
-        } catch(Exception e){
-            LOG.log(Level.FINEST, "URI not convertible to file, ignoring " + uri, e);
-        }
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8e9a3cc5/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfiguration.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfiguration.java
new file mode 100644
index 0000000..83a983d
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfiguration.java
@@ -0,0 +1,323 @@
+/*
+ * 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.mutableconfig.internal;
+
+import org.apache.tamaya.ConfigOperator;
+import org.apache.tamaya.ConfigQuery;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.mutableconfig.ChangePropagationPolicy;
+import org.apache.tamaya.mutableconfig.MutableConfiguration;
+import org.apache.tamaya.mutableconfig.MutableConfigurationProvider;
+import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.PropertySource;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.logging.Logger;
+
+
+/**
+ * Default implementation of a {@link MutableConfiguration}.
+ */
+public class DefaultMutableConfiguration implements MutableConfiguration {
+    private static final Logger LOG = Logger.getLogger(DefaultMutableConfiguration.class.getName());
+    private final Configuration config;
+    private ChangePropagationPolicy changePropagationPolicy =
+            MutableConfigurationProvider.getApplyAllChangePolicy();
+    private UUID transactionId;
+    private boolean autoCommit = false;
+
+    public DefaultMutableConfiguration(Configuration config){
+        this.config = Objects.requireNonNull(config);
+        this.autoCommit = false;
+    }
+
+    @Override
+    public void setChangePropagationPolicy(ChangePropagationPolicy changePropagationPolicy){
+        this.changePropagationPolicy = Objects.requireNonNull(changePropagationPolicy);
+    }
+
+    @Override
+    public ChangePropagationPolicy getChangePropagationPolicy(){
+        return changePropagationPolicy;
+    }
+
+    @Override
+    public void setAutoCommit(boolean autoCommit) {
+        if(transactionId!=null){
+            throw new IllegalStateException("Cannot change autoCommit within a transaction, perform a " +
+                    "commit or rollback first.");
+        }
+        this.autoCommit = autoCommit;
+    }
+
+    @Override
+    public UUID getTransactionId() {
+        return transactionId;
+    }
+
+    @Override
+    public boolean getAutoCommit() {
+        return autoCommit;
+    }
+
+    @Override
+    public List<MutablePropertySource> getMutablePropertySources() {
+        List<MutablePropertySource> result = new ArrayList<>();
+        ConfigurationContext context = ConfigurationProvider.getConfigurationContext(this.config);
+        for(PropertySource propertySource:context.getPropertySources()) {
+            if(propertySource instanceof  MutablePropertySource){
+                result.add((MutablePropertySource)propertySource);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public boolean isWritable(String keyExpression) {
+        for(MutablePropertySource target:getMutablePropertySources()) {
+            if( target.isWritable(keyExpression)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public List<MutablePropertySource> getPropertySourcesThatCanWrite(String keyExpression) {
+        List<MutablePropertySource> result = new ArrayList<>();
+        for(MutablePropertySource propertySource:getMutablePropertySources()) {
+            if(propertySource.isWritable(keyExpression)){
+                result.add(propertySource);
+            }
+        }
+        return result;
+    }
+
+    @Override
+        public boolean isRemovable(String keyExpression) {
+            for(MutablePropertySource target:getMutablePropertySources()) {
+                if( target.isRemovable(keyExpression)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+    @Override
+    public List<MutablePropertySource> getPropertySourcesThatCanRemove(String keyExpression) {
+        List<MutablePropertySource> result = new ArrayList<>();
+        for(MutablePropertySource propertySource:getMutablePropertySources()) {
+            if(propertySource.isRemovable(keyExpression)){
+                result.add(propertySource);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public boolean isExisting(String keyExpression) {
+        for(MutablePropertySource target:getMutablePropertySources()) {
+            if(target.get(keyExpression)!=null) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public List<MutablePropertySource> getPropertySourcesThatKnow(String keyExpression) {
+        List<MutablePropertySource> result = new ArrayList<>();
+        for(MutablePropertySource propertySource:getMutablePropertySources()) {
+            if(propertySource.get(keyExpression)!=null){
+                result.add(propertySource);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public MutableConfiguration put(String key, String value) {
+        UUID taID = startTransaction();
+        changePropagationPolicy.applyChange(getPropertySources(), taID, key, value);
+        if(autoCommit){
+            commitTransaction();
+        }
+        return this;
+    }
+
+    @Override
+    public MutableConfiguration putAll(Map<String, String> properties) {
+        UUID taID = startTransaction();
+        changePropagationPolicy.applyChanges(getPropertySources(), taID, properties);
+        if(autoCommit){
+            commitTransaction();
+        }
+        return this;
+    }
+
+    @Override
+    public MutableConfiguration remove(String... keys) {
+        UUID taID = startTransaction();
+        changePropagationPolicy.applyRemove(getPropertySources(), taID, keys);
+        for(String key:keys){
+            for(MutablePropertySource target:getMutablePropertySources()) {
+                if (target.isRemovable(key)) {
+                    target.remove(taID, key);
+                }
+            }
+        }
+        if(autoCommit){
+            commitTransaction();
+        }
+        return this;
+    }
+
+    @Override
+    public UUID startTransaction() {
+        UUID taID = transactionId;
+        if(taID!=null){
+            return taID;
+        }
+        taID = UUID.randomUUID();
+        transactionId = taID;
+        try {
+            for (MutablePropertySource target : getMutablePropertySources()) {
+                target.startTransaction(taID);
+            }
+        }catch(Exception e){
+            rollbackTransaction();
+        }
+        return taID;
+    }
+
+    @Override
+    public void commitTransaction() {
+        UUID taID = transactionId;
+        if(taID==null){
+            LOG.warning("No active transaction on this thread, ignoring commit.");
+            return;
+        }
+        try {
+            for (MutablePropertySource target : getMutablePropertySources()) {
+                target.commitTransaction(taID);
+            }
+            this.transactionId = null;
+        }catch(Exception e){
+            rollbackTransaction();
+        }
+    }
+
+    @Override
+    public void rollbackTransaction() {
+        UUID taID = transactionId;
+        if(taID==null){
+            LOG.warning("No active transaction on this thread, ignoring rollback.");
+            return;
+        }
+        try {
+            for (MutablePropertySource target : getMutablePropertySources()) {
+                target.rollbackTransaction(taID);
+            }
+        }finally{
+            this.transactionId = null;
+        }
+    }
+
+    @Override
+    public MutableConfiguration remove(Collection<String> keys) {
+        UUID taID = startTransaction();
+        for(String key:keys){
+            for(MutablePropertySource target:getMutablePropertySources()) {
+                if (target.isRemovable(key)) {
+                    target.remove(taID, key);
+                }
+            }
+        }
+        if(autoCommit){
+            commitTransaction();
+        }
+        return this;
+    }
+
+    @Override
+    public String get(String key) {
+        return this.config.get(key);
+    }
+
+    @Override
+    public String getOrDefault(String key, String defaultValue) {
+        return this.config.getOrDefault(key, defaultValue);
+    }
+
+    @Override
+    public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
+        return this.config.getOrDefault(key, type, defaultValue);
+    }
+
+    @Override
+    public <T> T get(String key, Class<T> type) {
+        return this.config.get(key, type);
+    }
+
+    @Override
+    public <T> T get(String key, TypeLiteral<T> type) {
+        return this.config.get(key, type);
+    }
+
+    @Override
+    public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) {
+        return this.config.getOrDefault(key, type, defaultValue);
+    }
+
+        @Override
+    public Map<String, String> getProperties() {
+        return this.config.getProperties();
+    }
+
+    @Override
+    public Configuration with(ConfigOperator operator) {
+        return operator.operate(this);
+    }
+
+    @Override
+    public <T> T query(ConfigQuery<T> query) {
+        return query.query(this);
+    }
+
+    @Override
+    public String toString() {
+        return "DefaultMutableConfiguration{" +
+                "config=" + config +
+                ", autoCommit=" + autoCommit +
+                '}';
+    }
+
+    private Collection<PropertySource> getPropertySources() {
+        ConfigurationContext context = ConfigurationProvider.getConfigurationContext(this.config);
+        return context.getPropertySources();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8e9a3cc5/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfigurationSpi.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfigurationSpi.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfigurationSpi.java
new file mode 100644
index 0000000..178e21f
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfigurationSpi.java
@@ -0,0 +1,36 @@
+/*
+ * 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.mutableconfig.internal;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.mutableconfig.MutableConfiguration;
+import org.apache.tamaya.mutableconfig.spi.MutableConfigurationProviderSpi;
+
+
+/**
+ * SPI implementation that creates instances of {@link DefaultMutableConfiguration}, hereby for
+ * each instance of {@link Configuration} a new instance has to be returned.
+ */
+public class DefaultMutableConfigurationSpi implements MutableConfigurationProviderSpi{
+
+    @Override
+    public MutableConfiguration createMutableConfiguration(Configuration configuration) {
+        return new DefaultMutableConfiguration(configuration);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8e9a3cc5/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendSpi.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendSpi.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendSpi.java
deleted file mode 100644
index 39bd0cf..0000000
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendSpi.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.mutableconfig.internal;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.mutableconfig.spi.AbstractMutableConfigurationBackendSpi;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Date;
-import java.util.Map;
-import java.util.Properties;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Change Request implementation based on .properties file.
- */
-class PropertiesFileConfigBackendSpi extends AbstractMutableConfigurationBackendSpi {
-
-    private static final Logger LOG = Logger.getLogger(PropertiesFileConfigBackendSpi.class.getName());
-
-    private final File file;
-
-    private final Properties properties = new Properties();
-
-    /**
-     * Instantiates a new Properties file config change request.
-     *
-     * @param file the file
-     */
-    PropertiesFileConfigBackendSpi(File file){
-        super(file.toURI(), new SimplePropertySource(file));
-        this.file = file;
-        if(file.exists()) {
-            try (InputStream is = getBackendURI().toURL().openStream()) {
-                properties.load(is);
-            } catch (Exception e) {
-                LOG.log(Level.SEVERE, "Failed to load properties from " + file, e);
-            }
-        }
-    }
-
-    @Override
-    public boolean isExisting(String keyExpression) {
-        if(properties.containsKey(keyExpression)){
-            return true;
-        }
-        for(Object key:properties.keySet()){
-            if(key.toString().matches(keyExpression)){
-                return true;
-            }
-        }
-        return false;
-    }
-
-
-    @Override
-    protected void commitInternal() {
-        if(!file.exists()){
-            try {
-                if(!file.createNewFile()){
-                    throw new ConfigException("Failed to create config file " + file);
-                }
-            } catch (IOException e) {
-                throw new ConfigException("Failed to create config file " + file, e);
-            }
-        }
-        for(Map.Entry<String,String> en:super.addedProperties.entrySet()){
-            int index = en.getKey().indexOf('?');
-            if(index>0){
-                this.properties.put(en.getKey().substring(0, index), en.getValue());
-            }else{
-                this.properties.put(en.getKey(), en.getValue());
-            }
-        }
-        for(String rmKey:super.removedProperties){
-            this.properties.remove(rmKey);
-        }
-        try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))){
-            properties.store(bos, "Properties written from Tamaya on : " + new Date());
-            bos.flush();
-        }
-        catch(Exception e){
-            throw new ConfigException("Failed to write config to " + file, e);
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "PropertiesFileConfigBackend{" +
-                "file=" + file +
-                '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8e9a3cc5/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/SimplePropertySource.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/SimplePropertySource.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/SimplePropertySource.java
deleted file mode 100644
index 68b6745..0000000
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/SimplePropertySource.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.mutableconfig.internal;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Simple implementation of a {@link org.apache.tamaya.spi.PropertySource} for properties-files.
- */
-class SimplePropertySource extends BasePropertySource {
-
-    /**
-     * The logger.
-     */
-    private static final Logger LOG = Logger.getLogger(SimplePropertySource.class.getName());
-    /**
-     * Default update interval is 1 minute.
-     */
-    private static final long DEFAULT_UPDATE_INTERVAL = 60000L;
-
-    /**
-     * The property source name.
-     */
-    private String name;
-
-    /**
-     * The configuration resource's URL.
-     */
-    private URL resource;
-
-    /**
-     * Timestamp of last read.
-     */
-    private long lastRead;
-
-    /**
-     * Interval, when the resource should try to update its contents.
-     */
-    private long updateInterval = DEFAULT_UPDATE_INTERVAL;
-    /**
-     * The current properties.
-     */
-    private Map<String, String> properties;
-
-    /**
-     * Creates a new Properties based PropertySource based on the given URL.
-     *
-     * @param propertiesLocation the URL encoded location, not null.
-     */
-    public SimplePropertySource(File propertiesLocation) {
-        super(0);
-        this.name = propertiesLocation.toString();
-        try {
-            this.resource = propertiesLocation.toURI().toURL();
-            load();
-        } catch (MalformedURLException e) {
-            LOG.log(Level.SEVERE, "Cannot convert file to URL: " + 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(0);
-        this.name = propertiesLocation.toString();
-        this.resource = propertiesLocation;
-        load();
-    }
-
-    /**
-     * 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) {
-        super(0);
-        this.name = Objects.requireNonNull(name);
-        this.properties = new HashMap<>(properties);
-    }
-
-    /**
-     * 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(0);
-        this.name = Objects.requireNonNull(name);
-        this.resource = propertiesLocation;
-        load();
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public Map<String, String> getProperties() {
-        checkLoad();
-        return this.properties;
-    }
-
-    private void checkLoad() {
-        if(resource!=null && (lastRead+updateInterval)<System.currentTimeMillis()){
-            load();
-        }
-    }
-
-    /**
-     * loads the Properties from the given URL
-     *
-     * @return loaded {@link Properties}
-     * @throws IllegalStateException in case of an error while reading properties-file
-     */
-    private void load() {
-        Map<String, String> properties = new HashMap<>();
-        try (InputStream stream = resource.openStream()) {
-            Properties props = new Properties();
-            if (stream != null) {
-                props.load(stream);
-            }
-            for (String key : props.stringPropertyNames()) {
-                properties.put(key, props.getProperty(key));
-            }
-            this.lastRead = System.currentTimeMillis();
-            this.properties = properties;
-            LOG.log(Level.FINEST, "Loaded properties from " + resource);
-        } catch (IOException e) {
-            LOG.log(Level.FINEST, "Cannot load properties from " + resource, e);
-            this.properties = Collections.emptyMap();
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8e9a3cc5/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/XmlPropertiesFileConfigBackendSpi.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/XmlPropertiesFileConfigBackendSpi.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/XmlPropertiesFileConfigBackendSpi.java
deleted file mode 100644
index 68f7e8f..0000000
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/XmlPropertiesFileConfigBackendSpi.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.mutableconfig.internal;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.mutableconfig.spi.AbstractMutableConfigurationBackendSpi;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Date;
-import java.util.Map;
-import java.util.Properties;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Change Request implementation based on .xml properties file.
- */
-class XmlPropertiesFileConfigBackendSpi extends AbstractMutableConfigurationBackendSpi {
-
-    private static final Logger LOG = Logger.getLogger(XmlPropertiesFileConfigBackendSpi.class.getName());
-
-    private final File file;
-
-    private final Properties properties = new Properties();
-
-    /**
-     * Instantiates a new Xml properties file config change request.
-     *
-     * @param file the file
-     */
-    XmlPropertiesFileConfigBackendSpi(File file){
-        super(file.toURI(), new SimplePropertySource(file));
-        this.file = file;
-        if(file.exists()) {
-            try (InputStream is = getBackendURI().toURL().openStream()) {
-                properties.loadFromXML(is);
-            } catch (Exception e) {
-                LOG.log(Level.SEVERE, "Failed to load properties from " + file, e);
-            }
-        }
-    }
-
-    @Override
-    public boolean isExisting(String keyExpression) {
-        if(properties.containsKey(keyExpression)){
-            return true;
-        }
-        for(Object key:properties.keySet()){
-            if(key.toString().matches(keyExpression)){
-                return true;
-            }
-        }
-        return false;
-    }
-
-
-    @Override
-    protected void commitInternal() {
-        if(!file.exists()){
-            try {
-                if(!file.createNewFile()){
-                    throw new ConfigException("Failed to create config file " + file);
-                }
-            } catch (IOException e) {
-                throw new ConfigException("Failed to create config file " + file, e);
-            }
-        }
-        for(Map.Entry<String,String> en:super.addedProperties.entrySet()){
-            int index = en.getKey().indexOf('?');
-            if(index>0){
-                this.properties.put(en.getKey().substring(0, index), en.getValue());
-            }else{
-                this.properties.put(en.getKey(), en.getValue());
-            }
-        }
-        for(String rmKey:super.removedProperties){
-            this.properties.remove(rmKey);
-        }
-        try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))){
-            properties.storeToXML(bos, "Properties written from Tamaya on " + new Date());
-            bos.flush();
-        }
-        catch(Exception e){
-            throw new ConfigException("Failed to write config to " + file, e);
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "XmlPropertiesFileConfigBackend{" +
-                "file=" + file +
-                '}';
-    }
-}