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 +
- '}';
- }
-}