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/01 17:47:49 UTC
[03/14] incubator-tamaya git commit: Added support for having backend
data visible in MutableConfig.
Added support for having backend data visible in MutableConfig.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/51260b63
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/51260b63
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/51260b63
Branch: refs/heads/master
Commit: 51260b637c3ef5f4289f118ae4e08e6db45d3712
Parents: 98fe89a
Author: anatole <an...@apache.org>
Authored: Tue Mar 1 09:45:21 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Tue Mar 1 09:45:21 2016 +0100
----------------------------------------------------------------------
.../mutableconfig/MutableConfiguration.java | 4 +-
.../MutableConfigurationQuery.java | 239 +++++++++++--------
.../internal/BasePropertySource.java | 2 +-
.../PropertiesFileConfigBackendSpi.java | 6 +-
.../internal/SimplePropertySource.java | 75 ++++--
.../XmlPropertiesFileConfigBackendSpi.java | 6 +-
.../AbstractMutableConfigurationBackendSpi.java | 33 ++-
.../spi/MutableConfigurationBackendSpi.java | 11 +
.../MutableConfigurationQueryTest.java | 4 +-
.../PropertiesFileConfigBackendTest.java | 37 ---
10 files changed, 249 insertions(+), 168 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/51260b63/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 9b8da41..4ad3d70 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
@@ -39,12 +39,12 @@ import java.util.Map;
public interface MutableConfiguration extends Configuration {
/**
- * Identifies the configuration backends that are targeted by this instance and which are
+ * 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.
*/
- Collection<URI> getBackendURIs();
+ URI getBackendURI();
/**
* Checks if a configuration key is writable (or it can be added).
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/51260b63/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
index 34177c3..fc7f6cc 100644
--- 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
@@ -29,61 +29,58 @@ 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.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
- * Accessor for creating {@link MutableConfiguration} instances to change and commit configuration.
+ * 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 List<MutableConfigurationBackendSpi> targets = new ArrayList<>();
+ private final MutableConfigurationBackendSpi target;
private ValueVisibilityPolicy valueVisibilityPolicy;
/** Singleton constructor. */
- private MutableConfigurationQuery(ValueVisibilityPolicy valueVisibilityPolicy, List<MutableConfigurationBackendSpi> targets){
- this.targets.addAll(targets);
+ private MutableConfigurationQuery(MutableConfigurationBackendSpi target, ValueVisibilityPolicy valueVisibilityPolicy){
+ this.target = Objects.requireNonNull(target);
this.valueVisibilityPolicy = valueVisibilityPolicy;
}
@Override
public MutableConfiguration query(Configuration config) {
- return new DefaultMutableConfiguration(valueVisibilityPolicy, config, targets);
+ return new DefaultMutableConfiguration(target, valueVisibilityPolicy, config);
}
/**
- * Creates a new change request for the given configurationSource
+ * Creates a new {@link MutableConfigurationQuery} for the given configuration target.
*
- * @param configurationTargets the configuration targets (String to create URIs) to use to write the changes/config. By passing multiple
+ * @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... configurationTargets){
- return of(ValueVisibilityPolicy.CONFIG, configurationTargets);
+ public static MutableConfigurationQuery of(String configurationTarget){
+ return of(configurationTarget, ValueVisibilityPolicy.CONFIG);
}
/**
- * Creates a new change request for the given configurationSource
+ * Creates a new {@link MutableConfigurationQuery} for the given configuration target and visibility policy.
*
- * @param configurationTargets the configuration targets (String to create URIs) to use to write the changes/config. By passing multiple
+ * @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.
@@ -92,35 +89,32 @@ public final class MutableConfigurationQuery implements ConfigQuery<MutableConfi
* @return a new ChangeRequest
* @throws org.apache.tamaya.ConfigException if the given configurationSource cannot be edited.
*/
- public static MutableConfigurationQuery of(ValueVisibilityPolicy valueVisibilityPolicy, String... configurationTargets){
+ public static MutableConfigurationQuery of(String configurationTarget, ValueVisibilityPolicy valueVisibilityPolicy){
try {
- URI[] uris = new URI[configurationTargets.length];
- for (int i = 0; i < configurationTargets.length; i++) {
- uris[i] = new URI(configurationTargets[i]);
- }
- return of(valueVisibilityPolicy, uris);
+ URI uri = new URI(configurationTarget);
+ return of(uri, valueVisibilityPolicy);
} catch(URISyntaxException e){
- throw new ConfigException("Invalid URIs encountered in " + Arrays.toString(configurationTargets));
+ throw new ConfigException("Invalid URI " + configurationTarget);
}
}
/**
- * Creates a new change request for the given configurationSource
+ * Creates a new {@link MutableConfigurationQuery} for the given configuration target.
*
- * @param configurationTargets the configuration targets to use to write the changes/config. By passing multiple
+ * @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... configurationTargets){
- return of(ValueVisibilityPolicy.CONFIG, configurationTargets);
+ public static MutableConfigurationQuery of(URI configurationTarget){
+ return of(configurationTarget, ValueVisibilityPolicy.CONFIG);
}
/**
- * Creates a new change request for the given configurationSource
+ * Creates a new {@link MutableConfigurationQuery} for the given configuration target and visibility policy.
*
- * @param configurationTargets the configuration targets to use to write the changes/config. By passing multiple
+ * @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.
@@ -129,25 +123,89 @@ public final class MutableConfigurationQuery implements ConfigQuery<MutableConfi
* @return a new ChangeRequest
* @throws org.apache.tamaya.ConfigException if the given configurationSource cannot be edited.
*/
- public static MutableConfigurationQuery of(ValueVisibilityPolicy valueVisibilityPolicy, URI... configurationTargets){
- if(Objects.requireNonNull(configurationTargets).length==0){
- throw new IllegalArgumentException("At least one target URI is required.");
- }
- List<MutableConfigurationBackendSpi> targets = new ArrayList<>();
+ public static MutableConfigurationQuery of(URI configurationTarget, ValueVisibilityPolicy valueVisibilityPolicy){
+ MutableConfigurationBackendSpi target = null;
for(MutableConfigurationBackendProviderSpi spi:ServiceContextManager.getServiceContext()
.getServices(MutableConfigurationBackendProviderSpi.class)){
- for(URI target:configurationTargets) {
- MutableConfigurationBackendSpi req = spi.getBackend(target);
- if (req != null) {
- targets.add(req);
- }
+ MutableConfigurationBackendSpi req = spi.getBackend(Objects.requireNonNull(configurationTarget));
+ if (req != null) {
+ target = req;
+ break;
}
}
- if(targets.isEmpty()) {
- throw new ConfigException("Not an editable configuration target for: " +
- Arrays.toString(configurationTargets));
+ 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);
}
- return new MutableConfigurationQuery(Objects.requireNonNull(valueVisibilityPolicy), targets);
+ }
+
+ /**
+ * 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));
}
@@ -157,72 +215,49 @@ public final class MutableConfigurationQuery implements ConfigQuery<MutableConfi
private static final class DefaultMutableConfiguration extends AbstractMutableConfiguration
implements MutableConfiguration {
- private final List<MutableConfigurationBackendSpi> targets;
+ private final MutableConfigurationBackendSpi target;
private final Configuration config;
private ValueVisibilityPolicy valueVisibilityPolicy;
- DefaultMutableConfiguration(ValueVisibilityPolicy valueVisibilityPolicy, Configuration config, List<MutableConfigurationBackendSpi> targets){
- this.targets = Objects.requireNonNull(targets);
+ DefaultMutableConfiguration(MutableConfigurationBackendSpi target, ValueVisibilityPolicy valueVisibilityPolicy, Configuration config){
+ this.target = Objects.requireNonNull(target);
this.config = Objects.requireNonNull(config);
this.valueVisibilityPolicy = valueVisibilityPolicy;
}
@Override
- public List<URI> getBackendURIs() {
- List<URI> result = new ArrayList<>(targets.size());
- for(MutableConfigurationBackendSpi backend: targets){
- result.add(backend.getBackendURI());
- }
- return Collections.unmodifiableList(result);
+ public URI getBackendURI() {
+ return target.getBackendURI();
}
@Override
public boolean isWritable(String keyExpression) {
- for(MutableConfigurationBackendSpi req:targets){
- if(req.isWritable(keyExpression)){
- return true;
- }
- }
- return false;
+ return target.isWritable(keyExpression);
}
@Override
public boolean isRemovable(String keyExpression) {
- for(MutableConfigurationBackendSpi req:targets){
- if(req.isRemovable(keyExpression)){
- return true;
- }
- }
- return false;
+ return target.isRemovable(keyExpression);
}
@Override
public boolean isExisting(String keyExpression) {
- for(MutableConfigurationBackendSpi req:targets){
- if(req.isExisting(keyExpression)){
- return true;
- }
- }
- return false;
+ return target.isExisting(keyExpression);
}
@Override
public MutableConfiguration put(String key, String value) {
- for(MutableConfigurationBackendSpi req:targets){
- if(req.isWritable(key)){
- req.put(key, value);
- }
+ if(target.isWritable(key)){
+ target.put(key, value);
}
- return super.put(key, value);
+ return this;
}
@Override
public MutableConfiguration putAll(Map<String, String> properties) {
- for(MutableConfigurationBackendSpi req:targets){
- for(Map.Entry<String,String> en:properties.entrySet()) {
- if (req.isWritable(en.getKey())) {
- req.put(en.getKey(), en.getValue());
- }
+ for(Map.Entry<String,String> en:properties.entrySet()) {
+ if (target.isWritable(en.getKey())) {
+ target.put(en.getKey(), en.getValue());
}
}
return super.putAll(properties);
@@ -230,11 +265,9 @@ public final class MutableConfigurationQuery implements ConfigQuery<MutableConfi
@Override
public MutableConfiguration remove(String... keys) {
- for(MutableConfigurationBackendSpi req:targets){
- for(String key:keys){
- if (req.isRemovable(key)) {
- req.remove(key);
- }
+ for(String key:keys){
+ if (target.isRemovable(key)) {
+ target.remove(key);
}
}
return super.remove(keys);
@@ -242,11 +275,9 @@ public final class MutableConfigurationQuery implements ConfigQuery<MutableConfi
@Override
public MutableConfiguration remove(Collection<String> keys) {
- for(MutableConfigurationBackendSpi req:targets){
- for(String key:keys){
- if (req.isRemovable(key)) {
- req.remove(key);
- }
+ for(String key:keys){
+ if (target.isRemovable(key)) {
+ target.remove(key);
}
}
return super.remove(keys);
@@ -254,9 +285,7 @@ public final class MutableConfigurationQuery implements ConfigQuery<MutableConfi
@Override
protected void commitInternal() {
- for(MutableConfigurationBackendSpi req:targets){
- req.commit();
- }
+ target.commit();
}
@Override
@@ -268,14 +297,25 @@ public final class MutableConfigurationQuery implements ConfigQuery<MutableConfi
if(removed){
return null;
}
- return addedOrUpdated!=null?addedOrUpdated:this.config.get(key);
+ return addedOrUpdated!=null?addedOrUpdated:getInternal(key);
case CONFIG:
default:
- String val = this.config.get(key);
+ 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);
@@ -301,7 +341,7 @@ public final class MutableConfigurationQuery implements ConfigQuery<MutableConfi
public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) {
String val = get(key);
if(val==null) {
- return config.getOrDefault(key, type, defaultValue);
+ return defaultValue;
}
for(PropertyConverter conv: ConfigurationProvider.getConfigurationContext().getPropertyConverters(type)){
Object o = conv.convert(val, new ConversionContext.Builder(key, type).setConfiguration(config).build());
@@ -314,7 +354,12 @@ public final class MutableConfigurationQuery implements ConfigQuery<MutableConfi
@Override
public Map<String, String> getProperties() {
- Map<String, String> configProps = new HashMap<>(config.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){
@@ -350,7 +395,7 @@ public final class MutableConfigurationQuery implements ConfigQuery<MutableConfi
public String toString() {
return "DefaultMutableConfiguration{" +
"config=" + config +
- ", targets=" + targets +
+ ", target=" + target +
'}';
}
}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/51260b63/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
index e3d65f9..2fe87df 100644
--- 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
@@ -30,7 +30,7 @@ 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.
*/
-public abstract class BasePropertySource implements PropertySource{
+abstract class BasePropertySource implements PropertySource{
/** default ordinal that will be used, if no ordinal is provided with the config. */
private final int defaultOrdinal;
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/51260b63/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
index 15a68cb..39bd0cf 100644
--- 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
@@ -19,7 +19,7 @@
package org.apache.tamaya.mutableconfig.internal;
import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.mutableconfig.spi.AbstractMutableConfigurationBackendSpiSpi;
+import org.apache.tamaya.mutableconfig.spi.AbstractMutableConfigurationBackendSpi;
import java.io.BufferedOutputStream;
import java.io.File;
@@ -35,7 +35,7 @@ import java.util.logging.Logger;
/**
* Change Request implementation based on .properties file.
*/
-class PropertiesFileConfigBackendSpi extends AbstractMutableConfigurationBackendSpiSpi {
+class PropertiesFileConfigBackendSpi extends AbstractMutableConfigurationBackendSpi {
private static final Logger LOG = Logger.getLogger(PropertiesFileConfigBackendSpi.class.getName());
@@ -49,7 +49,7 @@ class PropertiesFileConfigBackendSpi extends AbstractMutableConfigurationBackend
* @param file the file
*/
PropertiesFileConfigBackendSpi(File file){
- super(file.toURI());
+ super(file.toURI(), new SimplePropertySource(file));
this.file = file;
if(file.exists()) {
try (InputStream is = getBackendURI().toURL().openStream()) {
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/51260b63/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
index 1e2ab52..68b6745 100644
--- 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
@@ -18,25 +18,48 @@
*/
package org.apache.tamaya.mutableconfig.internal;
-import org.apache.tamaya.ConfigException;
-
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.net.MalformedURLException;
import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
/**
* Simple implementation of a {@link org.apache.tamaya.spi.PropertySource} for properties-files.
*/
-public class SimplePropertySource extends BasePropertySource {
+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.
*/
@@ -49,11 +72,12 @@ public class SimplePropertySource extends BasePropertySource {
*/
public SimplePropertySource(File propertiesLocation) {
super(0);
+ this.name = propertiesLocation.toString();
try {
- this.properties = load(propertiesLocation.toURI().toURL());
- this.name = propertiesLocation.toString();
- } catch (IOException e) {
- throw new ConfigException("Failed to load properties from " + propertiesLocation, e);
+ this.resource = propertiesLocation.toURI().toURL();
+ load();
+ } catch (MalformedURLException e) {
+ LOG.log(Level.SEVERE, "Cannot convert file to URL: " + propertiesLocation, e);
}
}
@@ -64,8 +88,9 @@ public class SimplePropertySource extends BasePropertySource {
*/
public SimplePropertySource(URL propertiesLocation) {
super(0);
- this.properties = load(propertiesLocation);
- this.name = propertiesLocation.toExternalForm();
+ this.name = propertiesLocation.toString();
+ this.resource = propertiesLocation;
+ load();
}
/**
@@ -76,8 +101,8 @@ public class SimplePropertySource extends BasePropertySource {
*/
public SimplePropertySource(String name, Map<String, String> properties) {
super(0);
- this.properties = new HashMap<>(properties);
this.name = Objects.requireNonNull(name);
+ this.properties = new HashMap<>(properties);
}
/**
@@ -88,8 +113,9 @@ public class SimplePropertySource extends BasePropertySource {
*/
public SimplePropertySource(String name, URL propertiesLocation) {
super(0);
- this.properties = load(propertiesLocation);
this.name = Objects.requireNonNull(name);
+ this.resource = propertiesLocation;
+ load();
}
@Override
@@ -99,19 +125,25 @@ public class SimplePropertySource extends BasePropertySource {
@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
*
- * @param propertiesFile {@link URL} to load Properties from
* @return loaded {@link Properties}
* @throws IllegalStateException in case of an error while reading properties-file
*/
- private Map<String, String> load(URL propertiesFile) {
+ private void load() {
Map<String, String> properties = new HashMap<>();
- try (InputStream stream = propertiesFile.openStream()) {
+ try (InputStream stream = resource.openStream()) {
Properties props = new Properties();
if (stream != null) {
props.load(stream);
@@ -119,10 +151,13 @@ public class SimplePropertySource extends BasePropertySource {
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) {
- throw new ConfigException("Error loading properties " + propertiesFile, e);
+ LOG.log(Level.FINEST, "Cannot load properties from " + resource, e);
+ this.properties = Collections.emptyMap();
}
- return properties;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/51260b63/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
index cdca80d..68f7e8f 100644
--- 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
@@ -19,7 +19,7 @@
package org.apache.tamaya.mutableconfig.internal;
import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.mutableconfig.spi.AbstractMutableConfigurationBackendSpiSpi;
+import org.apache.tamaya.mutableconfig.spi.AbstractMutableConfigurationBackendSpi;
import java.io.BufferedOutputStream;
import java.io.File;
@@ -35,7 +35,7 @@ import java.util.logging.Logger;
/**
* Change Request implementation based on .xml properties file.
*/
-class XmlPropertiesFileConfigBackendSpi extends AbstractMutableConfigurationBackendSpiSpi {
+class XmlPropertiesFileConfigBackendSpi extends AbstractMutableConfigurationBackendSpi {
private static final Logger LOG = Logger.getLogger(XmlPropertiesFileConfigBackendSpi.class.getName());
@@ -49,7 +49,7 @@ class XmlPropertiesFileConfigBackendSpi extends AbstractMutableConfigurationBack
* @param file the file
*/
XmlPropertiesFileConfigBackendSpi(File file){
- super(file.toURI());
+ super(file.toURI(), new SimplePropertySource(file));
this.file = file;
if(file.exists()) {
try (InputStream is = getBackendURI().toURL().openStream()) {
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/51260b63/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/AbstractMutableConfigurationBackendSpi.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/AbstractMutableConfigurationBackendSpi.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/AbstractMutableConfigurationBackendSpi.java
index 867f346..d529847 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/AbstractMutableConfigurationBackendSpi.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/AbstractMutableConfigurationBackendSpi.java
@@ -18,6 +18,8 @@
*/
package org.apache.tamaya.mutableconfig.spi;
+import org.apache.tamaya.spi.PropertySource;
+
import java.net.URI;
import java.util.*;
@@ -26,27 +28,47 @@ import java.util.*;
*/
public abstract class AbstractMutableConfigurationBackendSpi implements MutableConfigurationBackendSpi {
+ /** The URI identifying the current backend. */
private final URI backendURI;
/**
- * The Properties.
+ * The property source containing the current backend property data.
+ */
+ private PropertySource backendPropertySource;
+
+ /**
+ * The added or changed properties (uncommitted)..
*/
protected final Map<String,String> addedProperties = new HashMap<>();
/**
- * The Removed.
+ * The removed properties (uncommitted).
*/
protected final Set<String> removedProperties = new HashSet<>();
+ /**
+ * Get the uncommitted removed properties.
+ * @return the uncommitted removed properties, never null.
+ */
protected Set<String> getRemovedProperties() {
return removedProperties;
}
+ /**
+ * Get the uncommitted properties added or updated so far.
+ * @return the uncommitted properties added or updated, never null.
+ */
protected Map<String,String> getAddedProperties() {
return addedProperties;
}
- protected AbstractMutableConfigurationBackendSpi(URI backendURI){
+ /**
+ * Creates a new instance.
+ * @param backendURI the backend URI, not null.
+ * @param backendPropertySource the backend property source, not null.
+ */
+ protected AbstractMutableConfigurationBackendSpi(URI backendURI, PropertySource backendPropertySource){
this.backendURI = Objects.requireNonNull(backendURI);
+ this.backendPropertySource = Objects.requireNonNull(backendPropertySource);
}
@Override
@@ -55,6 +77,11 @@ public abstract class AbstractMutableConfigurationBackendSpi implements MutableC
}
@Override
+ public PropertySource getBackendPropertySource(){
+ return backendPropertySource;
+ }
+
+ @Override
public boolean isWritable(String keyExpression) {
return true;
}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/51260b63/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendSpi.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendSpi.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendSpi.java
index 1541f26..7f93c7d 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendSpi.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationBackendSpi.java
@@ -18,6 +18,9 @@
*/
package org.apache.tamaya.mutableconfig.spi;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
import java.net.URI;
import java.util.Collection;
import java.util.Map;
@@ -79,6 +82,14 @@ public interface MutableConfigurationBackendSpi {
*/
void put(String key, String value);
+
+ /**
+ * Access a {@link org.apache.tamaya.spi.PropertySource} for reading any properties from the write target.
+ * @return the {@link org.apache.tamaya.spi.PropertySource} never {@code null}. In case of a write only
+ * data sink, simply return PropertySource.EMPTY.
+ */
+ PropertySource getBackendPropertySource();
+
/**
* Puts all given configuration entries. This method should check that all given properties are
* basically removable, as defined by #isWritable. If any of the passed keys is not writable during this initial
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/51260b63/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationQueryTest.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationQueryTest.java b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationQueryTest.java
index 6ab394d..f50a85e 100644
--- a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationQueryTest.java
+++ b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationQueryTest.java
@@ -68,7 +68,7 @@ public class MutableConfigurationQueryTest {
@Test(expected=NullPointerException.class)
public void testNullCreateChangeRequest1() throws Exception {
MutableConfiguration req = ConfigurationProvider.getConfiguration().query(
- MutableConfigurationQuery.of((URI[])null));
+ MutableConfigurationQuery.of((URI)null));
}
/**
@@ -79,6 +79,6 @@ public class MutableConfigurationQueryTest {
@Test(expected=NullPointerException.class)
public void testNullCreateChangeRequest2() throws Exception {
MutableConfiguration req = ConfigurationProvider.getConfiguration().query(
- MutableConfigurationQuery.of((String[])null));
+ MutableConfigurationQuery.of((String)null));
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/51260b63/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendTest.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendTest.java b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendTest.java
index 78a6379..9a3e130 100644
--- a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendTest.java
+++ b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendTest.java
@@ -122,41 +122,4 @@ public class PropertiesFileConfigBackendTest {
assertEquals("value4", props.getProperty("key4"));
}
- @Test
- public void testReadWrite_Compound() throws IOException {
- File f1 = File.createTempFile("testReadWrite_Compound",".xml");
- f1.delete();
- File f2 = File.createTempFile("testReadWrite_Compound",".properties");
- f2.delete();
- MutableConfiguration req = ConfigurationProvider.getConfiguration().query(
- MutableConfigurationQuery.of(f1.toURI(), f2.toURI()));
- req.put("key1", "value1");
- Map<String,String> cm = new HashMap<>();
- cm.put("key2", "value2");
- cm.put("key3", "value3");
- req.putAll(cm);
- req.commit();
- assertTrue(f1.exists());
- assertTrue(f2.exists());
- MutableConfiguration req2 = ConfigurationProvider.getConfiguration().query(
- MutableConfigurationQuery.of(f1.toURI(), f2.toURI()));
- assertTrue(req != req2);
- req2.remove("foo");
- req2.remove("key3");
- req2.put("key1", "value1.2");
- req2.put("key4", "value4");
- req2.commit();
- Properties props = new Properties();
- props.load(f2.toURL().openStream());
- assertEquals(3, props.size());
- assertEquals("value1.2", props.getProperty("key1"));
- assertEquals("value2", props.getProperty("key2"));
- assertEquals("value4", props.getProperty("key4"));
- props = new Properties();
- props.loadFromXML(f1.toURL().openStream());
- assertEquals(3, props.size());
- assertEquals("value1.2", props.getProperty("key1"));
- assertEquals("value2", props.getProperty("key2"));
- assertEquals("value4", props.getProperty("key4"));
- }
}
\ No newline at end of file