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 2018/01/03 00:09:05 UTC
[09/18] incubator-tamaya-extensions git commit: Adapted to comply
with JSR API.
Adapted to comply with JSR API.
Signed-off-by: Anatole Tresch <an...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/commit/4869d946
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/tree/4869d946
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/diff/4869d946
Branch: refs/heads/configjsr
Commit: 4869d946cb8a5730feb74c8dea379d9462427b5e
Parents: 36b4466
Author: Anatole Tresch <an...@apache.org>
Authored: Thu Dec 28 02:27:43 2017 +0100
Committer: Anatole Tresch <an...@apache.org>
Committed: Thu Dec 28 02:27:43 2017 +0100
----------------------------------------------------------------------
modules/events/pom.xml | 15 +-
.../org/apache/tamaya/events/ConfigChange.java | 229 +++++++++++++++
.../tamaya/events/ConfigChangeBuilder.java | 274 ++++++++++++++++++
.../tamaya/events/ConfigEventManager.java | 9 +-
.../tamaya/events/ConfigSourceChange.java | 211 ++++++++++++++
.../events/ConfigSourceChangeBuilder.java | 250 +++++++++++++++++
.../tamaya/events/ConfigurationChange.java | 230 ---------------
.../events/ConfigurationChangeBuilder.java | 278 -------------------
.../org/apache/tamaya/events/FrozenConfig.java | 197 +++++++++++++
.../tamaya/events/FrozenConfigSource.java | 129 +++++++++
.../tamaya/events/FrozenConfiguration.java | 227 ---------------
.../tamaya/events/FrozenPropertySource.java | 135 ---------
.../tamaya/events/PropertySourceChange.java | 212 --------------
.../events/PropertySourceChangeBuilder.java | 252 -----------------
.../internal/DefaultConfigChangeObserver.java | 20 +-
.../events/internal/LoggingConfigListener.java | 4 +-
.../events/spi/ConfigEventManagerSpi.java | 3 +-
.../events/ChangeableGlobalConfigSource.java | 62 +++++
.../events/ChangeableGlobalPropertySource.java | 62 -----
.../ChangeableThreadLocalPropertySource.java | 7 +-
.../tamaya/events/ConfigChangeBuilderTest.java | 134 +++++++++
.../apache/tamaya/events/ConfigChangeTest.java | 161 +++++++++++
.../tamaya/events/ConfigSourceChangeTest.java | 180 ++++++++++++
.../events/ConfigurationChangeBuilderTest.java | 131 ---------
.../tamaya/events/ConfigurationChangeTest.java | 162 -----------
.../tamaya/events/FrozenConfigSourceTest.java | 108 +++++++
.../tamaya/events/FrozenConfigurationTest.java | 23 +-
.../tamaya/events/FrozenPropertySourceTest.java | 109 --------
.../tamaya/events/ObservedConfigTest.java | 4 +-
.../tamaya/events/PropertySourceChangeTest.java | 180 ------------
.../tamaya/events/RandomConfigSource.java | 59 ++++
.../tamaya/events/RandomPropertySource.java | 65 -----
.../apache/tamaya/events/TestConfigView.java | 126 ++-------
.../folderobserver/FileChangeListener.java | 6 +-
.../ObservingPropertySourceProvider.java | 58 ++--
.../DefaultConfigChangeObserverTest.java | 6 +-
.../org.apache.tamaya.spi.PropertySource | 2 +-
37 files changed, 2094 insertions(+), 2226 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/4869d946/modules/events/pom.xml
----------------------------------------------------------------------
diff --git a/modules/events/pom.xml b/modules/events/pom.xml
index aaa650f..33904d0 100644
--- a/modules/events/pom.xml
+++ b/modules/events/pom.xml
@@ -34,25 +34,20 @@ under the License.
<dependencies>
<dependency>
- <groupId>org.apache.tamaya</groupId>
- <artifactId>tamaya-api</artifactId>
- <version>${tamaya-apicore.version}</version>
- </dependency>
- <dependency>
<groupId>org.apache.tamaya.ext</groupId>
<artifactId>tamaya-functions</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tamaya</groupId>
- <artifactId>tamaya-spisupport</artifactId>
- <version>${project.version}</version>
+ <artifactId>tamaya-core</artifactId>
+ <version>${tamaya-apicore.version}</version>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tamaya</groupId>
- <artifactId>tamaya-core</artifactId>
- <version>${tamaya-apicore.version}</version>
- <scope>runtime</scope>
+ <artifactId>tamaya-base</artifactId>
+ <version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/4869d946/modules/events/src/main/java/org/apache/tamaya/events/ConfigChange.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/ConfigChange.java b/modules/events/src/main/java/org/apache/tamaya/events/ConfigChange.java
new file mode 100644
index 0000000..01074b5
--- /dev/null
+++ b/modules/events/src/main/java/org/apache/tamaya/events/ConfigChange.java
@@ -0,0 +1,229 @@
+/*
+ * 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.events;
+
+import javax.config.Config;
+import java.beans.PropertyChangeEvent;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Event that contains a set current changes that were applied or could be applied.
+ * This class is immutable and thread-safe. To create instances use
+ * {@link ConfigSourceChangeBuilder}.
+ *
+ * Created by Anatole on 22.10.2014.
+ */
+public final class ConfigChange implements ConfigEvent<Config>, Serializable{
+
+ private static final long serialVersionUID = 1L;
+ /** The base property provider/configuration. */
+ private final FrozenConfig configuration;
+ /** The base version, usable for optimistic locking. */
+ private String version = UUID.randomUUID().toString();
+ /** The timestamp of the change set in millis from the epoch. */
+ private long timestamp = System.currentTimeMillis();
+ /** The recorded changes. */
+ private final Map<String,PropertyChangeEvent> changes = new HashMap<>();
+
+ /**
+ * Get an empty change set for the given provider.
+ * @param configuration The configuration changed, not null.
+ * @return an empty ConfigurationChangeSet instance.
+ */
+ public static ConfigChange emptyChangeSet(Config configuration){
+ return ConfigChangeBuilder.of(configuration).build();
+ }
+
+ /**
+ * Constructor used by {@link ConfigSourceChangeBuilder}.
+ * @param builder The builder used, not null.
+ */
+ ConfigChange(ConfigChangeBuilder builder) {
+ this.configuration = FrozenConfig.of(builder.source);
+ for(PropertyChangeEvent ev:builder.delta.values()){
+ this.changes.put(ev.getPropertyName(), ev);
+ }
+ if(builder.version!=null){
+ this.version = builder.version;
+ }
+ if(builder.timestamp!=null){
+ this.timestamp = builder.timestamp;
+ }
+ }
+
+ @Override
+ public Class<Config> getResourceType() {
+ return Config.class;
+ }
+
+ /**
+ * Get the underlying property provider/configuration.
+ * @return the underlying property provider/configuration, never null.
+ */
+ @Override
+ public Config getResource(){
+ return this.configuration;
+ }
+
+ /**
+ * Get the base version, usable for optimistic locking.
+ * @return the base version.
+ */
+ @Override
+ public String getVersion(){
+ return version;
+ }
+
+ /**
+ * Get the timestamp in millis from the current epoch. it is expected that the timestamp and the version are unique to
+ * identify a changeset.
+ * @return the timestamp, when this changeset was created.
+ */
+ @Override
+ public long getTimestamp(){
+ return timestamp;
+ }
+
+ /**
+ * Get the changes recorded.
+ * @return the recorded changes, never null.
+ */
+ public Collection<PropertyChangeEvent> getChanges(){
+ return Collections.unmodifiableCollection(this.changes.values());
+ }
+
+ /**
+ * Access the number current removed entries.
+ * @return the number current removed entries.
+ */
+ public int getRemovedSize() {
+ int removedCount = 0;
+ for(PropertyChangeEvent ev:this.changes.values()){
+ if(ev.getPropertyName().startsWith("_")){
+ continue;
+ }
+ if(ev.getNewValue() == null){
+ removedCount++;
+ }
+ }
+ return removedCount;
+ }
+
+ /**
+ * Access the number current added entries.
+ * @return the number current added entries.
+ */
+ public int getAddedSize() {
+ int addedCount = 0;
+ for(PropertyChangeEvent ev:this.changes.values()){
+ if(ev.getPropertyName().startsWith("_")){
+ continue;
+ }
+ if(ev.getOldValue() == null &&
+ ev.getNewValue() != null){
+ addedCount++;
+ }
+ }
+ return addedCount;
+ }
+
+ /**
+ * Access the number current updated entries.
+ * @return the number current updated entries.
+ */
+ public int getUpdatedSize() {
+ int updatedCount = 0;
+ for(PropertyChangeEvent ev:this.changes.values()){
+ if(ev.getPropertyName().startsWith("_")){
+ continue;
+ }
+ if( ev.getOldValue()!=null && ev.getNewValue()!=null){
+ updatedCount++;
+ }
+ }
+ return updatedCount;
+ }
+
+
+ /**
+ * Checks if the given key was removed.
+ * @param key the target key, not null.
+ * @return true, if the given key was removed.
+ */
+ public boolean isRemoved(String key) {
+ PropertyChangeEvent change = this.changes.get(key);
+ return change != null && change.getNewValue() == null;
+ }
+
+ /**
+ * Checks if the given key was added.
+ * @param key the target key, not null.
+ * @return true, if the given key was added.
+ */
+ public boolean isAdded(String key) {
+ PropertyChangeEvent change = this.changes.get(key);
+ return change != null && change.getOldValue() == null;
+ }
+
+ /**
+ * Checks if the given key was updated.
+ * @param key the target key, not null.
+ * @return true, if the given key was updated.
+ */
+ public boolean isUpdated(String key) {
+ PropertyChangeEvent change = this.changes.get(key);
+ return change != null && change.getOldValue() != null && change.getNewValue() != null;
+ }
+
+ /**
+ * Checks if the given key is added, or updated AND NOT removed.
+ * @param key the target key, not null.
+ * @return true, if the given key was added, or updated BUT NOT removed.
+ */
+ public boolean isKeyAffected(String key) {
+ PropertyChangeEvent change = this.changes.get(key);
+ return change != null && change.getNewValue() != null;
+ }
+
+ /**
+ * CHecks if the current change set does not contain any changes.
+ * @return tru, if the change set is empty.
+ */
+ public boolean isEmpty(){
+ return this.changes.isEmpty();
+ }
+
+
+ @Override
+ public String toString() {
+ return "ConfigurationChange{" +
+ "\n config-id = " + configuration.getOptionalValue("_id",String.class).orElse("-") +
+ "\n change-id = " + version +
+ "\n timestamp = " + timestamp +
+ "\n added = " + this.getAddedSize() +
+ "\n updated = " + this.getUpdatedSize() +
+ "\n removed = " + this.getRemovedSize() + '\n' +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/4869d946/modules/events/src/main/java/org/apache/tamaya/events/ConfigChangeBuilder.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/ConfigChangeBuilder.java b/modules/events/src/main/java/org/apache/tamaya/events/ConfigChangeBuilder.java
new file mode 100644
index 0000000..a170ab4
--- /dev/null
+++ b/modules/events/src/main/java/org/apache/tamaya/events/ConfigChangeBuilder.java
@@ -0,0 +1,274 @@
+/*
+ * 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.events;
+
+import javax.config.Config;
+import javax.config.ConfigProvider;
+import java.beans.PropertyChangeEvent;
+import java.util.*;
+
+/**
+ * Models a set current changes applied to a {@link org.apache.tamaya.spi.PropertySource}. Consumers of these events
+ * can observe changes to property sources and
+ * <ol>
+ * <li>Check if their current configuration instance ({@link org.apache.tamaya.spi.ConfigurationContext}
+ * contains the changed {@link org.apache.tamaya.spi.PropertySource} (Note: the reference to a property source is never affected by a
+ * change, its only the data of the property source).</li>
+ * <li>If so corresponding actions might be taken, such as reevaluating the configuration values (depending on
+ * the update policy) or reevaluating the complete {@link org.apache.tamaya.Configuration} to create a change
+ * event on configuration level.
+ * </ol>
+ */
+public final class ConfigChangeBuilder {
+ /**
+ * The recorded changes.
+ */
+ final SortedMap<String, PropertyChangeEvent> delta = new TreeMap<>();
+ /**
+ * The underlying configuration/provider.
+ */
+ final Config source;
+ /**
+ * The version configured, or null, for generating a default.
+ */
+ String version;
+ /**
+ * The optional timestamp in millis of this epoch.
+ */
+ Long timestamp;
+
+ /**
+ * Constructor.
+ *
+ * @param configuration the underlying configuration, not null.
+ */
+ private ConfigChangeBuilder(Config configuration) {
+ this.source = Objects.requireNonNull(configuration);
+ }
+
+ /**
+ * Creates a new instance current this builder using the current COnfiguration as root resource.
+ *
+ * @return the builder for chaining.
+ */
+ public static ConfigChangeBuilder of() {
+ return new ConfigChangeBuilder(ConfigProvider.getConfig());
+ }
+
+ /**
+ * Creates a new instance current this builder.
+ *
+ * @param configuration the configuration changed, not null.
+ * @return the builder for chaining.
+ */
+ public static ConfigChangeBuilder of(Config configuration) {
+ return new ConfigChangeBuilder(configuration);
+ }
+
+ /**
+ * Compares the two property config/configurations and creates a collection with all changes
+ * that must be applied to render {@code previous} into {@code target}.
+ *
+ * @param previous the previous map, not null.
+ * @param current the target map, not null.
+ * @return a collection current change events, never {@code null}.
+ */
+ public static Collection<PropertyChangeEvent> compare(Config previous, Config current) {
+ TreeMap<String, PropertyChangeEvent> events = new TreeMap<>();
+
+ for (String key : previous.getPropertyNames()) {
+ String previousValue = previous.getValue(key, String.class);
+ Optional<String> currentValue = current.getOptionalValue(key, String.class);
+ if(Objects.equals(currentValue.orElse(null), previousValue)){
+ continue;
+ }else {
+ PropertyChangeEvent event = new PropertyChangeEvent(previous, key, previousValue, currentValue.orElse(null));
+ events.put(key, event);
+ }
+ }
+
+ for (String key : current.getPropertyNames()){
+ Optional<String> previousValue = previous.getOptionalValue(key, String.class);
+ String currentValue = current.getOptionalValue(key, String.class).orElse(null);
+ if(Objects.equals(currentValue, previousValue.orElse(null))){
+ continue;
+ }else{
+ if (!previousValue.isPresent()) {
+ PropertyChangeEvent event = new PropertyChangeEvent(current, key, null, currentValue);
+ events.put(key, event);
+ }
+ // the other cases were already covered by the previous loop.
+ }
+ }
+ return events.values();
+ }
+
+ /*
+ * Apply a version/UUID to the set being built.
+ * @param version the version to apply, or null, to let the system generate a version for you.
+ * @return the builder for chaining.
+ */
+ public ConfigChangeBuilder setVersion(String version) {
+ this.version = version;
+ return this;
+ }
+
+ /*
+ * Apply given timestamp to the set being built.
+ * @param version the version to apply, or null, to let the system generate a version for you.
+ * @return the builder for chaining.
+ */
+ public ConfigChangeBuilder setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ return this;
+ }
+
+ /**
+ * This method records all changes to be applied to the base property provider/configuration to
+ * achieve the given target state.
+ *
+ * @param newState the new target state, not null.
+ * @return the builder for chaining.
+ */
+ public ConfigChangeBuilder addChanges(Config newState) {
+ for (PropertyChangeEvent c : compare(this.source, newState)) {
+ this.delta.put(c.getPropertyName(), c);
+ }
+ return this;
+ }
+
+ /**
+ * Applies a single key/value change.
+ *
+ * @param key the changed key
+ * @param value the new value.
+ * @return this instance for chaining.
+ */
+ public ConfigChangeBuilder addChange(String key, String value) {
+ this.delta.put(key, new PropertyChangeEvent(this.source, key,
+ this.source.getOptionalValue(key, String.class).orElse(null),
+ value));
+ return this;
+ }
+
+ /**
+ * Get the current values, also considering any changes recorded within this change set.
+ *
+ * @param key the key current the entry, not null.
+ * @return the keys, or null.
+ */
+ public String get(String key) {
+ PropertyChangeEvent change = this.delta.get(key);
+ if (change != null && !(change.getNewValue() == null)) {
+ return (String) change.getNewValue();
+ }
+ return null;
+ }
+
+ /**
+ * Marks the given key(s) fromMap the configuration/properties to be removed.
+ *
+ * @param key the key current the entry, not null.
+ * @param otherKeys additional keys to be removed (convenience), not null.
+ * @return the builder for chaining.
+ */
+ public ConfigChangeBuilder removeKey(String key, String... otherKeys) {
+ Optional<String> oldValue = this.source.getOptionalValue(key, String.class);
+ if (!oldValue.isPresent()) {
+ this.delta.remove(key);
+ }
+ this.delta.put(key, new PropertyChangeEvent(this.source, key, oldValue, null));
+ for (String addKey : otherKeys) {
+ oldValue = this.source.getOptionalValue(key, String.class);
+ if (!oldValue.isPresent()) {
+ this.delta.remove(addKey);
+ }
+ this.delta.put(addKey, new PropertyChangeEvent(this.source, addKey, oldValue, null));
+ }
+ return this;
+ }
+
+ /**
+ * Apply all the given values to the base configuration/properties.
+ * Note that all values passed must be convertible to String, either
+ * <ul>
+ * <li>the registered codecs provider provides codecs for the corresponding keys, or </li>
+ * <li>default codecs are present for the given type, or</li>
+ * <li>the value is an instanceof String</li>
+ * </ul>
+ *
+ * @param changes the changes to be applied, not null.
+ * @return the builder for chaining.
+ */
+ public ConfigChangeBuilder putAll(Map<String, String> changes) {
+ for (Map.Entry<String, String> en : changes.entrySet()) {
+ this.delta.put(en.getKey(), new PropertyChangeEvent(this.source, en.getKey(), null, en.getValue()));
+ }
+ return this;
+ }
+
+ /**
+ * This method will create a change set that clears all entries fromMap the given base configuration/properties.
+ *
+ * @return the builder for chaining.
+ */
+ public ConfigChangeBuilder removeAllKeys() {
+ this.delta.clear();
+ for (String key : this.source.getPropertyNames()) {
+ this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.getValue(key, String.class),
+ null));
+ }
+// this.source.getProperties().forEach((k, v) ->
+// this.delta.put(k, new PropertyChangeEvent(this.source, k, v, null)));
+ return this;
+ }
+
+ /**
+ * Checks if the change set is empty, i.e. does not contain any changes.
+ *
+ * @return true, if the set is empty.
+ */
+ public boolean isEmpty() {
+ return this.delta.isEmpty();
+ }
+
+ /**
+ * Resets this change set instance. This will clear all changes done to this builder, so the
+ * set will be empty.
+ */
+ public void reset() {
+ this.delta.clear();
+ }
+
+ /**
+ * Builds the corresponding change set.
+ *
+ * @return the new change set, never null.
+ */
+ public ConfigChange build() {
+ return new ConfigChange(this);
+ }
+
+ @Override
+ public String toString() {
+ return "ConfigurationChangeSetBuilder [config=" + source + ", " +
+ ", delta=" + delta + "]";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/4869d946/modules/events/src/main/java/org/apache/tamaya/events/ConfigEventManager.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/ConfigEventManager.java b/modules/events/src/main/java/org/apache/tamaya/events/ConfigEventManager.java
index 96dc9a5..29426a1 100644
--- a/modules/events/src/main/java/org/apache/tamaya/events/ConfigEventManager.java
+++ b/modules/events/src/main/java/org/apache/tamaya/events/ConfigEventManager.java
@@ -18,7 +18,6 @@
*/
package org.apache.tamaya.events;
-import org.apache.tamaya.ConfigException;
import org.apache.tamaya.events.spi.ConfigEventManagerSpi;
import org.apache.tamaya.spi.ServiceContextManager;
@@ -37,7 +36,7 @@ public final class ConfigEventManager {
ConfigEventManagerSpi spi = ServiceContextManager.getServiceContext()
.getService(ConfigEventManagerSpi.class);
if(spi==null){
- throw new ConfigException("No SPI registered for " +
+ throw new IllegalStateException("No SPI registered for " +
ConfigEventManager.class.getName());
}
return spi;
@@ -110,7 +109,7 @@ public final class ConfigEventManager {
}
/**
- * Publishes a {@link ConfigurationChange} synchronously to all interested listeners.
+ * Publishes a {@link ConfigChange} synchronously to all interested listeners.
*
* @param <T> the type of the event.
* @param event the event, not null.
@@ -120,7 +119,7 @@ public final class ConfigEventManager {
}
/**
- * Publishes a {@link ConfigurationChange} asynchronously/multithreaded to all interested listeners.
+ * Publishes a {@link ConfigChange} asynchronously/multithreaded to all interested listeners.
*
* @param <T> the type of the event.
* @param event the event, not null.
@@ -134,7 +133,7 @@ public final class ConfigEventManager {
* and trigger ConfigurationChange events if something changed. This is quite handy for publishing
* configuration changes to whatever systems are interested in. Hereby the origin of a configuration change
* can be on this machine, or also remotely. For handling corresponding {@link ConfigEventListener} have
- * to be registered, e.g. listening on {@link org.apache.tamaya.events.ConfigurationChange} events.
+ * to be registered, e.g. listening on {@link ConfigChange} events.
*
* @param enable whether to enable or disable the change monitoring.
*
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/4869d946/modules/events/src/main/java/org/apache/tamaya/events/ConfigSourceChange.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/ConfigSourceChange.java b/modules/events/src/main/java/org/apache/tamaya/events/ConfigSourceChange.java
new file mode 100644
index 0000000..7bb5395
--- /dev/null
+++ b/modules/events/src/main/java/org/apache/tamaya/events/ConfigSourceChange.java
@@ -0,0 +1,211 @@
+/*
+ * 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.events;
+
+import javax.config.spi.ConfigSource;
+import java.beans.PropertyChangeEvent;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Event that contains a set current changes that were applied or could be applied.
+ * This class is immutable and thread-safe. To create instances use
+ * {@link ConfigSourceChangeBuilder}.
+ *
+ * Created by Anatole on 22.10.2014.
+ */
+public final class ConfigSourceChange implements ConfigEvent<ConfigSource>, Serializable{
+
+ private static final long serialVersionUID = 1L;
+ /** The base property provider/configuration. */
+ private final FrozenConfigSource configSource;
+ /** The base version, usable for optimistic locking. */
+ private String version = UUID.randomUUID().toString();
+ /** The timestamp of the change set in millis from the epoch. */
+ private long timestamp = System.currentTimeMillis();
+ /** The recorded changes. */
+ private final Map<String,PropertyChangeEvent> changes = new HashMap<>();
+
+ /**
+ * Constructor used by {@link ConfigSourceChangeBuilder}.
+ * @param builder The builder used, not null.
+ */
+ ConfigSourceChange(ConfigSourceChangeBuilder builder) {
+ this.configSource = FrozenConfigSource.of(builder.source);
+ for (PropertyChangeEvent c : builder.delta.values()) {
+ this.changes.put(c.getPropertyName(), c);
+ }
+ if(builder.version!=null){
+ this.version = builder.version;
+ }
+ if(builder.timestamp!=null){
+ this.timestamp = builder.timestamp;
+ }
+ }
+
+ @Override
+ public Class<ConfigSource> getResourceType() {
+ return ConfigSource.class;
+ }
+
+ /**
+ * Get the underlying property provider/configuration.
+ * @return the underlying property provider/configuration, or null, if the change instance was deserialized.
+ */
+ @Override
+ public ConfigSource getResource(){
+ return this.configSource;
+ }
+
+ /**
+ * Get the base version, usable for optimistic locking.
+ * @return the base version.
+ */
+ @Override
+ public String getVersion(){
+ return version;
+ }
+
+ /**
+ * Get the timestamp in millis from the current epoch. it is expected that the timestamp and the version are unique to
+ * identify a changeset.
+ * @return the timestamp, when this changeset was created.
+ */
+ @Override
+ public long getTimestamp(){
+ return timestamp;
+ }
+
+ /**
+ * Get the changes recorded.
+ * @return the recorded changes, never null.
+ */
+ public Collection<PropertyChangeEvent> getChanges(){
+ return Collections.unmodifiableCollection(this.changes.values());
+ }
+
+ /**
+ * Access the number current removed entries.
+ * @return the number current removed entries.
+ */
+ public int getRemovedSize() {
+ int removedCount = 0;
+ for (PropertyChangeEvent ev : this.changes.values()) {
+ if (ev.getNewValue() == null) {
+ removedCount++;
+ }
+ }
+ return removedCount;
+// return (int) this.changes.values().stream().filter((e) -> e.getNewValue() == null).count();
+ }
+
+ /**
+ * Access the number current added entries.
+ * @return the number current added entries.
+ */
+ public int getAddedSize() {
+ int addedCount = 0;
+ for (PropertyChangeEvent ev : this.changes.values()) {
+ if (ev.getOldValue() == null &&
+ ev.getNewValue() != null) {
+ addedCount++;
+ }
+ }
+ return addedCount;
+// return (int) this.changes.values().stream().filter((e) -> e.getOldValue() == null).count();
+ }
+
+ /**
+ * Access the number current updated entries.
+ * @return the number current updated entries.
+ */
+ public int getUpdatedSize() {
+ int updatedCount = 0;
+ for (PropertyChangeEvent ev : this.changes.values()) {
+ if (ev.getOldValue() != null && ev.getNewValue() != null) {
+ updatedCount++;
+ }
+ }
+ return updatedCount;
+// return (int) this.changes.values().stream().filter((e) -> e.getOldValue()!=null && e.getNewValue()!=null).count();
+ }
+
+
+ /**
+ * Checks if the given key was removed.
+ * @param key the target key, not null.
+ * @return true, if the given key was removed.
+ */
+ public boolean isRemoved(String key) {
+ PropertyChangeEvent change = this.changes.get(key);
+ return change != null && change.getNewValue() == null;
+ }
+
+ /**
+ * Checks if the given key was added.
+ * @param key the target key, not null.
+ * @return true, if the given key was added.
+ */
+ public boolean isAdded(String key) {
+ PropertyChangeEvent change = this.changes.get(key);
+ return change != null && change.getOldValue() == null;
+ }
+
+ /**
+ * Checks if the given key was updated.
+ * @param key the target key, not null.
+ * @return true, if the given key was updated.
+ */
+ public boolean isUpdated(String key) {
+ PropertyChangeEvent change = this.changes.get(key);
+ return change != null && change.getOldValue() != null && change.getNewValue() != null;
+ }
+
+ /**
+ * Checks if the given key is added, or updated AND NOT removed.
+ * @param key the target key, not null.
+ * @return true, if the given key was added, or updated BUT NOT removed.
+ */
+ public boolean isKeyAffected(String key) {
+ PropertyChangeEvent change = this.changes.get(key);
+ return change != null && change.getNewValue() != null;
+ }
+
+ /**
+ * CHecks if the current change set does not contain any changes.
+ * @return tru, if the change set is empty.
+ */
+ public boolean isEmpty(){
+ return this.changes.isEmpty();
+ }
+
+
+ @Override
+ public String toString() {
+ return "ConfigSourceChange{" +
+ ", configSource=" + configSource +
+ ", version='" + version + '\'' +
+ ", timestamp=" + timestamp +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/4869d946/modules/events/src/main/java/org/apache/tamaya/events/ConfigSourceChangeBuilder.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/ConfigSourceChangeBuilder.java b/modules/events/src/main/java/org/apache/tamaya/events/ConfigSourceChangeBuilder.java
new file mode 100644
index 0000000..684bcf1
--- /dev/null
+++ b/modules/events/src/main/java/org/apache/tamaya/events/ConfigSourceChangeBuilder.java
@@ -0,0 +1,250 @@
+/*
+ * 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.events;
+
+import javax.config.spi.ConfigSource;
+import java.beans.PropertyChangeEvent;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+/**
+ * Models a set current changes applied to a {@link ConfigSource}. Consumers of these events
+ * can observing changes to property sources and
+ * <ol>
+ * <li>Check if their current configuration instance ({@link javax.config.Config}
+ * contains the changed {@link ConfigSource} (Note: the reference tova property source is never affected by a
+ * change, its only the data of the property source).</li>
+ * <li>If so corresponding action may be taken, such as reevaluating the configuration values (depending on
+ * the update policy) or reevaluating the complete {@link javax.config.Config} to create a change
+ * event on configuration level.
+ * </ol>
+ */
+public final class ConfigSourceChangeBuilder {
+ /**
+ * The recorded changes.
+ */
+ final SortedMap<String, PropertyChangeEvent> delta = new TreeMap<>();
+ /**
+ * The underlying configuration/provider.
+ */
+ final ConfigSource source;
+ /**
+ * The version configured, or null, for generating a default.
+ */
+ String version;
+ /**
+ * The optional timestamp in millis of this epoch.
+ */
+ Long timestamp;
+
+ /**
+ * Constructor.
+ *
+ * @param source the underlying configuration/provider, not null.
+ */
+ private ConfigSourceChangeBuilder(ConfigSource source) {
+ this.source = Objects.requireNonNull(source);
+ }
+
+ /**
+ * Creates a new instance of this builder.
+ *
+ * @param source the underlying property provider/configuration, not null.
+ * @return the builder for chaining.
+ */
+ public static ConfigSourceChangeBuilder of(ConfigSource source) {
+ return new ConfigSourceChangeBuilder(source);
+ }
+
+ /**
+ * Compares the two property config/configurations and creates a collection current all changes
+ * that must be applied to render {@code map1} into {@code map2}.
+ *
+ * @param map1 the source map, not null.
+ * @param map2 the target map, not null.
+ * @return a collection current change events, never null.
+ */
+ public static Collection<PropertyChangeEvent> compare(ConfigSource map1, ConfigSource map2) {
+ List<PropertyChangeEvent> changes = new ArrayList<>();
+ for (Map.Entry<String, String> en : map1.getProperties().entrySet()) {
+ String val = map2.getValue(en.getKey());
+ if (val == null) {
+ changes.add(new PropertyChangeEvent(map1, en.getKey(), null, en.getValue()));
+ } else if (!val.equals(en.getValue())) {
+ changes.add(new PropertyChangeEvent(map1, en.getKey(), val, en.getValue()));
+ }
+ }
+ for (Map.Entry<String, String> en : map2.getProperties().entrySet()) {
+ String val = map1.getValue(en.getKey());
+ if (val == null) {
+ changes.add(new PropertyChangeEvent(map1, en.getKey(), en.getValue(), null));
+ } else if (!val.equals(en.getValue())) {
+ changes.add(new PropertyChangeEvent(map1, en.getKey(), en.getValue(), val));
+ }
+ }
+ return changes;
+ }
+
+ /*
+ * Apply a version/UUID to the set being built.
+ * @param version the version to apply, or null, to let the system generate a version for you.
+ * @return the builder for chaining.
+ */
+ public ConfigSourceChangeBuilder setVersion(String version) {
+ this.version = version;
+ return this;
+ }
+
+ /*
+ * Apply given timestamp to the set being built.
+ * @param version the version to apply, or null, to let the system generate a version for you.
+ * @return the builder for chaining.
+ */
+ public ConfigSourceChangeBuilder setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ return this;
+ }
+
+ /**
+ * This method records all changes to be applied to the base property provider/configuration to
+ * achieve the given target state.
+ *
+ * @param newState the new target state, not null.
+ * @return the builder for chaining.
+ */
+ public ConfigSourceChangeBuilder addChanges(ConfigSource newState) {
+ Collection<PropertyChangeEvent> events = ConfigSourceChangeBuilder.compare(newState, this.source);
+ for (PropertyChangeEvent c : events) {
+ this.delta.put(c.getPropertyName(), c);
+ }
+ return this;
+ }
+
+ /**
+ * Get the current values, also considering any changes recorded within this change set.
+ *
+ * @param key the key current the entry, not null.
+ * @return the keys, or null.
+ */
+ public String get(String key) {
+ PropertyChangeEvent change = this.delta.get(key);
+ if (change != null && !(change.getNewValue() == null)) {
+ return (String) change.getNewValue();
+ }
+ return null;
+ }
+
+ /**
+ * Marks the given key(s) fromMap the configuration/properties to be removed.
+ *
+ * @param key the key current the entry, not null.
+ * @param otherKeys additional keys to be removed (convenience), not null.
+ * @return the builder for chaining.
+ */
+ public ConfigSourceChangeBuilder remove(String key, String... otherKeys) {
+ String oldValue = this.source.getValue(key);
+ if (oldValue == null) {
+ this.delta.remove(key);
+ }
+ this.delta.put(key, new PropertyChangeEvent(this.source, key, oldValue, null));
+ for (String addKey : otherKeys) {
+ oldValue = this.source.getValue(addKey);
+ if (oldValue == null) {
+ this.delta.remove(addKey);
+ }
+ this.delta.put(addKey, new PropertyChangeEvent(this.source, addKey, oldValue, null));
+ }
+ return this;
+ }
+
+ /**
+ * Apply all the given values to the base configuration/properties.
+ * Note that all values passed must be convertible to String, either
+ * <ul>
+ * <li>the registered codecs provider provides codecs for the corresponding keys, or </li>
+ * <li>default codecs are present for the given type, or</li>
+ * <li>the value is an instanceof String</li>
+ * </ul>
+ *
+ * @param changes the changes to be applied, not null.
+ * @return the builder for chaining.
+ */
+ public ConfigSourceChangeBuilder putAll(Map<String, String> changes) {
+ for (Map.Entry<String, String> en : this.source.getProperties().entrySet()) {
+ this.delta.put(en.getKey(), new PropertyChangeEvent(this.source, en.getKey(), null, en.getValue()));
+ }
+ return this;
+ }
+
+ /**
+ * This method will create a change set that clears all entries fromMap the given base configuration/properties.
+ *
+ * @return the builder for chaining.
+ */
+ public ConfigSourceChangeBuilder deleteAll() {
+ this.delta.clear();
+ for (Map.Entry<String, String> en : this.source.getProperties().entrySet()) {
+ this.delta.put(en.getKey(), new PropertyChangeEvent(this.source, en.getKey(), en.getValue(), null));
+ }
+ return this;
+ }
+
+ /**
+ * Checks if the change set is empty, i.e. does not contain any changes.
+ *
+ * @return true, if the set is empty.
+ */
+ public boolean isEmpty() {
+ return this.delta.isEmpty();
+ }
+
+ /**
+ * Resets this change set instance. This will clear all changes done to this builder, so the
+ * set will be empty.
+ */
+ public void reset() {
+ this.delta.clear();
+ }
+
+
+ /**
+ * Builds the corresponding change set.
+ *
+ * @return the new change set, never null.
+ */
+ public ConfigSourceChange build() {
+ return new ConfigSourceChange(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "ConfigSourceChangeBuilder [source=" + source + ", " +
+ ", delta=" + delta + "]";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/4869d946/modules/events/src/main/java/org/apache/tamaya/events/ConfigurationChange.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/ConfigurationChange.java b/modules/events/src/main/java/org/apache/tamaya/events/ConfigurationChange.java
deleted file mode 100644
index 9cdd4fc..0000000
--- a/modules/events/src/main/java/org/apache/tamaya/events/ConfigurationChange.java
+++ /dev/null
@@ -1,230 +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.events;
-
-import org.apache.tamaya.Configuration;
-
-import java.beans.PropertyChangeEvent;
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-/**
- * Event that contains a set current changes that were applied or could be applied.
- * This class is immutable and thread-safe. To create instances use
- * {@link PropertySourceChangeBuilder}.
- *
- * Created by Anatole on 22.10.2014.
- */
-public final class ConfigurationChange implements ConfigEvent<Configuration>, Serializable{
-
- private static final long serialVersionUID = 1L;
- /** The base property provider/configuration. */
- private final FrozenConfiguration configuration;
- /** The base version, usable for optimistic locking. */
- private String version = UUID.randomUUID().toString();
- /** The timestamp of the change set in millis from the epoch. */
- private long timestamp = System.currentTimeMillis();
- /** The recorded changes. */
- private final Map<String,PropertyChangeEvent> changes = new HashMap<>();
-
- /**
- * Get an empty change set for the given provider.
- * @param configuration The configuration changed, not null.
- * @return an empty ConfigurationChangeSet instance.
- */
- public static ConfigurationChange emptyChangeSet(Configuration configuration){
- return ConfigurationChangeBuilder.of(configuration).build();
- }
-
- /**
- * Constructor used by {@link PropertySourceChangeBuilder}.
- * @param builder The builder used, not null.
- */
- ConfigurationChange(ConfigurationChangeBuilder builder) {
- this.configuration = FrozenConfiguration.of(builder.source);
- for(PropertyChangeEvent ev:builder.delta.values()){
- this.changes.put(ev.getPropertyName(), ev);
- }
- if(builder.version!=null){
- this.version = builder.version;
- }
- if(builder.timestamp!=null){
- this.timestamp = builder.timestamp;
- }
- }
-
- @Override
- public Class<Configuration> getResourceType() {
- return Configuration.class;
- }
-
- /**
- * Get the underlying property provider/configuration.
- * @return the underlying property provider/configuration, never null.
- */
- @Override
- public Configuration getResource(){
- return this.configuration;
- }
-
- /**
- * Get the base version, usable for optimistic locking.
- * @return the base version.
- */
- @Override
- public String getVersion(){
- return version;
- }
-
- /**
- * Get the timestamp in millis from the current epoch. it is expected that the timestamp and the version are unique to
- * identify a changeset.
- * @return the timestamp, when this changeset was created.
- */
- @Override
- public long getTimestamp(){
- return timestamp;
- }
-
- /**
- * Get the changes recorded.
- * @return the recorded changes, never null.
- */
- public Collection<PropertyChangeEvent> getChanges(){
- return Collections.unmodifiableCollection(this.changes.values());
- }
-
- /**
- * Access the number current removed entries.
- * @return the number current removed entries.
- */
- public int getRemovedSize() {
- int removedCount = 0;
- for(PropertyChangeEvent ev:this.changes.values()){
- if(ev.getPropertyName().startsWith("_")){
- continue;
- }
- if(ev.getNewValue() == null){
- removedCount++;
- }
- }
- return removedCount;
- }
-
- /**
- * Access the number current added entries.
- * @return the number current added entries.
- */
- public int getAddedSize() {
- int addedCount = 0;
- for(PropertyChangeEvent ev:this.changes.values()){
- if(ev.getPropertyName().startsWith("_")){
- continue;
- }
- if(ev.getOldValue() == null &&
- ev.getNewValue() != null){
- addedCount++;
- }
- }
- return addedCount;
- }
-
- /**
- * Access the number current updated entries.
- * @return the number current updated entries.
- */
- public int getUpdatedSize() {
- int updatedCount = 0;
- for(PropertyChangeEvent ev:this.changes.values()){
- if(ev.getPropertyName().startsWith("_")){
- continue;
- }
- if( ev.getOldValue()!=null && ev.getNewValue()!=null){
- updatedCount++;
- }
- }
- return updatedCount;
- }
-
-
- /**
- * Checks if the given key was removed.
- * @param key the target key, not null.
- * @return true, if the given key was removed.
- */
- public boolean isRemoved(String key) {
- PropertyChangeEvent change = this.changes.get(key);
- return change != null && change.getNewValue() == null;
- }
-
- /**
- * Checks if the given key was added.
- * @param key the target key, not null.
- * @return true, if the given key was added.
- */
- public boolean isAdded(String key) {
- PropertyChangeEvent change = this.changes.get(key);
- return change != null && change.getOldValue() == null;
- }
-
- /**
- * Checks if the given key was updated.
- * @param key the target key, not null.
- * @return true, if the given key was updated.
- */
- public boolean isUpdated(String key) {
- PropertyChangeEvent change = this.changes.get(key);
- return change != null && change.getOldValue() != null && change.getNewValue() != null;
- }
-
- /**
- * Checks if the given key is added, or updated AND NOT removed.
- * @param key the target key, not null.
- * @return true, if the given key was added, or updated BUT NOT removed.
- */
- public boolean isKeyAffected(String key) {
- PropertyChangeEvent change = this.changes.get(key);
- return change != null && change.getNewValue() != null;
- }
-
- /**
- * CHecks if the current change set does not contain any changes.
- * @return tru, if the change set is empty.
- */
- public boolean isEmpty(){
- return this.changes.isEmpty();
- }
-
-
- @Override
- public String toString() {
- return "ConfigurationChange{" +
- "\n configuration-id = " + configuration.getOrDefault("_id", "-") +
- "\n change-id = " + version +
- "\n timestamp = " + timestamp +
- "\n added = " + this.getAddedSize() +
- "\n updated = " + this.getUpdatedSize() +
- "\n removed = " + this.getRemovedSize() + '\n' +
- '}';
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/4869d946/modules/events/src/main/java/org/apache/tamaya/events/ConfigurationChangeBuilder.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/ConfigurationChangeBuilder.java b/modules/events/src/main/java/org/apache/tamaya/events/ConfigurationChangeBuilder.java
deleted file mode 100644
index 8becb11..0000000
--- a/modules/events/src/main/java/org/apache/tamaya/events/ConfigurationChangeBuilder.java
+++ /dev/null
@@ -1,278 +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.events;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.ConfigurationProvider;
-
-import java.beans.PropertyChangeEvent;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Objects;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-/**
- * Models a set current changes applied to a {@link org.apache.tamaya.spi.PropertySource}. Consumers of these events
- * can observe changes to property sources and
- * <ol>
- * <li>Check if their current configuration instance ({@link org.apache.tamaya.spi.ConfigurationContext}
- * contains the changed {@link org.apache.tamaya.spi.PropertySource} (Note: the reference to a property source is never affected by a
- * change, its only the data of the property source).</li>
- * <li>If so corresponding actions might be taken, such as reevaluating the configuration values (depending on
- * the update policy) or reevaluating the complete {@link org.apache.tamaya.Configuration} to create a change
- * event on configuration level.
- * </ol>
- */
-public final class ConfigurationChangeBuilder {
- /**
- * The recorded changes.
- */
- final SortedMap<String, PropertyChangeEvent> delta = new TreeMap<>();
- /**
- * The underlying configuration/provider.
- */
- final Configuration source;
- /**
- * The version configured, or null, for generating a default.
- */
- String version;
- /**
- * The optional timestamp in millis of this epoch.
- */
- Long timestamp;
-
- /**
- * Constructor.
- *
- * @param configuration the underlying configuration, not null.
- */
- private ConfigurationChangeBuilder(Configuration configuration) {
- this.source = Objects.requireNonNull(configuration);
- }
-
- /**
- * Creates a new instance current this builder using the current COnfiguration as root resource.
- *
- * @return the builder for chaining.
- */
- public static ConfigurationChangeBuilder of() {
- return new ConfigurationChangeBuilder(ConfigurationProvider.getConfiguration());
- }
-
- /**
- * Creates a new instance current this builder.
- *
- * @param configuration the configuration changed, not null.
- * @return the builder for chaining.
- */
- public static ConfigurationChangeBuilder of(Configuration configuration) {
- return new ConfigurationChangeBuilder(configuration);
- }
-
- /**
- * Compares the two property config/configurations and creates a collection with all changes
- * that must be applied to render {@code previous} into {@code target}.
- *
- * @param previous the previous map, not null.
- * @param current the target map, not null.
- * @return a collection current change events, never {@code null}.
- */
- public static Collection<PropertyChangeEvent> compare(Configuration previous, Configuration current) {
- TreeMap<String, PropertyChangeEvent> events = new TreeMap<>();
-
- for (Map.Entry<String, String> en : previous.getProperties().entrySet()) {
- String key = en.getKey();
- String previousValue = en.getValue();
- String currentValue = current.get(en.getKey());
- if(Objects.equals(currentValue, previousValue)){
- continue;
- }else {
- PropertyChangeEvent event = new PropertyChangeEvent(previous, key, previousValue, currentValue);
- events.put(key, event);
- }
- }
-
- for (Map.Entry<String, String> en : current.getProperties().entrySet()) {
- String key = en.getKey();
- String previousValue = previous.get(en.getKey());
- String currentValue = en.getValue();
- if(Objects.equals(currentValue, previousValue)){
- continue;
- }else{
- if (previousValue == null) {
- PropertyChangeEvent event = new PropertyChangeEvent(current, key, null, currentValue);
- events.put(key, event);
- }
- // the other cases were already covered by the previous loop.
- }
- }
- return events.values();
- }
-
- /*
- * Apply a version/UUID to the set being built.
- * @param version the version to apply, or null, to let the system generate a version for you.
- * @return the builder for chaining.
- */
- public ConfigurationChangeBuilder setVersion(String version) {
- this.version = version;
- return this;
- }
-
- /*
- * Apply given timestamp to the set being built.
- * @param version the version to apply, or null, to let the system generate a version for you.
- * @return the builder for chaining.
- */
- public ConfigurationChangeBuilder setTimestamp(long timestamp) {
- this.timestamp = timestamp;
- return this;
- }
-
- /**
- * This method records all changes to be applied to the base property provider/configuration to
- * achieve the given target state.
- *
- * @param newState the new target state, not null.
- * @return the builder for chaining.
- */
- public ConfigurationChangeBuilder addChanges(Configuration newState) {
- for (PropertyChangeEvent c : compare(this.source, newState)) {
- this.delta.put(c.getPropertyName(), c);
- }
- return this;
- }
-
- /**
- * Applies a single key/value change.
- *
- * @param key the changed key
- * @param value the new value.
- * @return this instance for chaining.
- */
- public ConfigurationChangeBuilder addChange(String key, String value) {
- this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key), value));
- return this;
- }
-
- /**
- * Get the current values, also considering any changes recorded within this change set.
- *
- * @param key the key current the entry, not null.
- * @return the keys, or null.
- */
- public String get(String key) {
- PropertyChangeEvent change = this.delta.get(key);
- if (change != null && !(change.getNewValue() == null)) {
- return (String) change.getNewValue();
- }
- return null;
- }
-
- /**
- * Marks the given key(s) fromMap the configuration/properties to be removed.
- *
- * @param key the key current the entry, not null.
- * @param otherKeys additional keys to be removed (convenience), not null.
- * @return the builder for chaining.
- */
- public ConfigurationChangeBuilder removeKey(String key, String... otherKeys) {
- String oldValue = this.source.get(key);
- if (oldValue == null) {
- this.delta.remove(key);
- }
- this.delta.put(key, new PropertyChangeEvent(this.source, key, oldValue, null));
- for (String addKey : otherKeys) {
- oldValue = this.source.get(addKey);
- if (oldValue == null) {
- this.delta.remove(addKey);
- }
- this.delta.put(addKey, new PropertyChangeEvent(this.source, addKey, oldValue, null));
- }
- return this;
- }
-
- /**
- * Apply all the given values to the base configuration/properties.
- * Note that all values passed must be convertible to String, either
- * <ul>
- * <li>the registered codecs provider provides codecs for the corresponding keys, or </li>
- * <li>default codecs are present for the given type, or</li>
- * <li>the value is an instanceof String</li>
- * </ul>
- *
- * @param changes the changes to be applied, not null.
- * @return the builder for chaining.
- */
- public ConfigurationChangeBuilder putAll(Map<String, String> changes) {
- for (Map.Entry<String, String> en : changes.entrySet()) {
- this.delta.put(en.getKey(), new PropertyChangeEvent(this.source, en.getKey(), null, en.getValue()));
- }
- return this;
- }
-
- /**
- * This method will create a change set that clears all entries fromMap the given base configuration/properties.
- *
- * @return the builder for chaining.
- */
- public ConfigurationChangeBuilder removeAllKeys() {
- this.delta.clear();
- for (Map.Entry<String, String> en : this.source.getProperties().entrySet()) {
- this.delta.put(en.getKey(), new PropertyChangeEvent(this.source, en.getKey(), en.getValue(), null));
- }
-// this.source.getProperties().forEach((k, v) ->
-// this.delta.put(k, new PropertyChangeEvent(this.source, k, v, null)));
- return this;
- }
-
- /**
- * Checks if the change set is empty, i.e. does not contain any changes.
- *
- * @return true, if the set is empty.
- */
- public boolean isEmpty() {
- return this.delta.isEmpty();
- }
-
- /**
- * Resets this change set instance. This will clear all changes done to this builder, so the
- * set will be empty.
- */
- public void reset() {
- this.delta.clear();
- }
-
- /**
- * Builds the corresponding change set.
- *
- * @return the new change set, never null.
- */
- public ConfigurationChange build() {
- return new ConfigurationChange(this);
- }
-
- @Override
- public String toString() {
- return "ConfigurationChangeSetBuilder [config=" + source + ", " +
- ", delta=" + delta + "]";
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/4869d946/modules/events/src/main/java/org/apache/tamaya/events/FrozenConfig.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/FrozenConfig.java b/modules/events/src/main/java/org/apache/tamaya/events/FrozenConfig.java
new file mode 100644
index 0000000..dca2204
--- /dev/null
+++ b/modules/events/src/main/java/org/apache/tamaya/events/FrozenConfig.java
@@ -0,0 +1,197 @@
+/*
+ * 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.events;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.apache.tamaya.base.convert.ConverterManager;
+import org.apache.tamaya.spi.ConfigContext;
+import org.apache.tamaya.spi.ConfigContextSupplier;
+
+import javax.config.Config;
+import javax.config.spi.ConfigSource;
+import javax.config.spi.Converter;
+import java.io.Serializable;
+import java.lang.reflect.Type;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * /**
+ * Configuration implementation that stores all current values of a given (possibly dynamic, contextual and non server
+ * capable instance) and is fully serializable. Note that hereby only the scannable key/value pairs are considered.
+ */
+public final class FrozenConfig implements Config, Serializable {
+ private static final long serialVersionUID = -6373137316556444171L;
+
+ /**
+ * The properties frozen.
+ */
+ private Map<String, String> properties = new HashMap<>();
+ private long frozenAt = System.nanoTime();
+ private UUID id = UUID.randomUUID();
+ private ConverterManager converterManager = new ConverterManager();
+
+ /**
+ * Constructor.
+ *
+ * @param config The base configuration.
+ */
+ private FrozenConfig(Config config) {
+ for(String key:config.getPropertyNames()) {
+ this.properties.put(key, config.getValue(key, String.class));
+ }
+ this.properties = Collections.unmodifiableMap(this.properties);
+ if(config instanceof ConfigContextSupplier){
+ ConfigContext ctx = ((ConfigContextSupplier)config).getConfigContext();
+ for(Map.Entry<Type, List<Converter>> en:ctx.getConverters().entrySet()) {
+ this.converterManager.addConverter(en.getKey(), en.getValue());
+ }
+ }
+ }
+
+ /**
+ * Creates a new FrozenConfiguration instance based on a Configuration given.
+ *
+ * @param config the configuration to be frozen, not null.
+ * @return the frozen Configuration.
+ */
+ public static FrozenConfig of(Config config) {
+ if (config instanceof FrozenConfig) {
+ return (FrozenConfig) config;
+ }
+ return new FrozenConfig(config);
+ }
+
+ public String getValue(String key) {
+ String val = this.properties.get(key);
+ if(val==null){
+ throw new NoSuchElementException("No such config found: " + key);
+ }
+ return val;
+ }
+
+ @Override
+ public <T> Optional<T> getOptionalValue(String key, Class<T> type) {
+ String value = this.properties.get(key);
+ if (value != null) {
+ List<Converter> converters = converterManager.getConverters(type);
+ ConversionContext context = new ConversionContext.Builder(this, key,type).build();
+ ConversionContext.setContext(context);
+ try {
+ for (Converter<T> converter : converters) {
+ try {
+ T t = converter.convert(value);
+ if (t != null) {
+ return Optional.of((T) t);
+ }
+ } catch (Exception e) {
+ Logger.getLogger(getClass().getName())
+ .log(Level.FINEST, "PropertyConverter: " + converter + " failed to convert value: " + value,
+ e);
+ }
+ }
+ }finally{
+ ConversionContext.reset();
+ }
+ if(String.class==type){
+ return Optional.of((T)value);
+ }
+ throw new IllegalArgumentException("Unparseable config value for type: " + type.getName() + ": " + key
+ + ", supported formats: " + context.getSupportedFormats());
+ }
+ return Optional.empty();
+ }
+
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> T getValue(String key, Class<T> type) {
+ return getOptionalValue(key, type)
+ .orElseThrow(() -> new NoSuchElementException("No such config found: " + key));
+ }
+
+ @Override
+ public Iterable<String> getPropertyNames() {
+ return properties.keySet();
+ }
+
+ @Override
+ public List<ConfigSource> getConfigSources() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ FrozenConfig that = (FrozenConfig) o;
+
+ if (frozenAt != that.frozenAt) {
+ return false;
+ }
+ if (properties != null ? !properties.equals(that.properties) : that.properties != null) {
+ return false;
+ }
+ return id != null ? id.equals(that.id) : that.id == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = properties != null ? properties.hashCode() : 0;
+ result = 31 * result + (int) (frozenAt ^ (frozenAt >>> 32));
+ result = 31 * result + (id != null ? id.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "FrozenConfiguration{" +
+ "id=" + getId() + "," +
+ "frozenAt=" + getFrozenAt() + "," +
+ "properties=" + properties +
+ '}';
+ }
+
+ /**
+ * <p>Returns the moment in time when this frozen configuration has been created.</p>
+ *
+ * <p>The time is taken from {@linkplain System#currentTimeMillis()}</p>
+ *
+ * @see System#currentTimeMillis()
+ * @return the moment in time when this configuration has been created
+ */
+ public long getFrozenAt() {
+ return frozenAt;
+ }
+
+ /**
+ * <p>Returns the unique id of this frozen configuration.</p>
+ *
+ * @return the unique id of this frozen configuration, never {@code null}
+ */
+ public UUID getId() {
+ return id;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/4869d946/modules/events/src/main/java/org/apache/tamaya/events/FrozenConfigSource.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/FrozenConfigSource.java b/modules/events/src/main/java/org/apache/tamaya/events/FrozenConfigSource.java
new file mode 100644
index 0000000..4bdd2a7
--- /dev/null
+++ b/modules/events/src/main/java/org/apache/tamaya/events/FrozenConfigSource.java
@@ -0,0 +1,129 @@
+/*
+ * 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.events;
+
+import org.apache.tamaya.base.configsource.ConfigSourceComparator;
+
+import javax.config.spi.ConfigSource;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * PropertySource implementation that stores all current values of a given (possibly dynamic, contextual and non server
+ * capable instance) and is fully serializable. Note that hereby only the scannable key/value pairs are considered.
+ */
+public final class FrozenConfigSource implements ConfigSource, Serializable {
+ private static final long serialVersionUID = -6373137316556444171L;
+ /**
+ * The ordinal.
+ */
+ private final int ordinal;
+ /**
+ * The properties read.
+ */
+ private Map<String, String> properties = new HashMap<>();
+ /**
+ * The PropertySource's name.
+ */
+ private final String name;
+
+ private long frozenAt = System.currentTimeMillis();
+
+ /**
+ * Constructor.
+ *
+ * @param configSource The base ConfigSource.
+ */
+ private FrozenConfigSource(ConfigSource configSource) {
+ this.properties.putAll(configSource.getProperties());
+ this.properties = Collections.unmodifiableMap(this.properties);
+ this.ordinal = ConfigSourceComparator.getOrdinal(configSource);
+ this.name = configSource.getName();
+ }
+
+ /**
+ * Creates a new FrozenPropertySource instance based on a PropertySource given.
+ *
+ * @param configSource the config source to be frozen, not null.
+ * @return the frozen property source.
+ */
+ public static FrozenConfigSource of(ConfigSource configSource) {
+ if (configSource instanceof FrozenConfigSource) {
+ return (FrozenConfigSource) configSource;
+ }
+ return new FrozenConfigSource(configSource);
+ }
+
+ @Override
+ public String getName() {
+ return this.name;
+ }
+
+ public int getOrdinal() {
+ return this.ordinal;
+ }
+
+ /**
+ * Get the creation timestamp of this instance.
+ * @return the creation timestamp
+ */
+ public long getFrozenAt(){
+ return frozenAt;
+ }
+
+ @Override
+ public String getValue(String key) {
+ return this.properties.get(key);
+ }
+
+ @Override
+ public Map<String,String> getProperties() {
+ return Collections.unmodifiableMap(properties);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof FrozenConfigSource)) {
+ return false;
+ }
+ FrozenConfigSource that = (FrozenConfigSource) o;
+ return ordinal == that.ordinal && properties.equals(that.properties);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = ordinal;
+ result = 31 * result + properties.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "FrozenPropertySource{" +
+ "name=" + name +
+ ", ordinal=" + ordinal +
+ ", properties=" + properties +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/4869d946/modules/events/src/main/java/org/apache/tamaya/events/FrozenConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/FrozenConfiguration.java b/modules/events/src/main/java/org/apache/tamaya/events/FrozenConfiguration.java
deleted file mode 100644
index 21ef873..0000000
--- a/modules/events/src/main/java/org/apache/tamaya/events/FrozenConfiguration.java
+++ /dev/null
@@ -1,227 +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.events;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.ConfigOperator;
-import org.apache.tamaya.ConfigQuery;
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.functions.ConfigurationFunctions;
-import org.apache.tamaya.spi.ConfigurationContext;
-import org.apache.tamaya.spi.ConversionContext;
-import org.apache.tamaya.spi.PropertyConverter;
-
-import java.io.Serializable;
-import java.util.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * /**
- * Configuration implementation that stores all current values of a given (possibly dynamic, contextual and non server
- * capable instance) and is fully serializable. Note that hereby only the scannable key/value pairs are considered.
- */
-public final class FrozenConfiguration implements Configuration, Serializable {
- private static final long serialVersionUID = -6373137316556444171L;
-
- /**
- * The properties frozen.
- */
- private Map<String, String> properties = new HashMap<>();
- private long frozenAt = System.nanoTime();
- private UUID id = UUID.randomUUID();
-
- /**
- * Constructor.
- *
- * @param config The base configuration.
- */
- private FrozenConfiguration(Configuration config) {
- this.properties.putAll(config.getProperties());
- this.properties = Collections.unmodifiableMap(this.properties);
- }
-
- /**
- * Creates a new FrozenConfiguration instance based on a Configuration given.
- *
- * @param config the configuration to be frozen, not null.
- * @return the frozen Configuration.
- */
- public static FrozenConfiguration of(Configuration config) {
- if (config instanceof FrozenConfiguration) {
- return (FrozenConfiguration) config;
- }
- return new FrozenConfiguration(config);
- }
-
- @Override
- public String get(String key) {
- return this.properties.get(key);
- }
-
- @Override
- public String getOrDefault(String key, String defaultValue) {
- String val = get(key);
- if(val==null){
- return defaultValue;
- }
- return val;
- }
-
- @Override
- public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
- T val = get(key, type);
- if(val==null){
- return defaultValue;
- }
- return val;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public <T> T get(String key, Class<T> type) {
- return (T) get(key, TypeLiteral.of(type));
- }
-
- /**
- * Accesses the current String value for the given key and tries to convert it
- * using the {@link org.apache.tamaya.spi.PropertyConverter} instances provided by the current
- * {@link org.apache.tamaya.spi.ConfigurationContext}.
- *
- * @param key the property's absolute, or relative path, e.g. @code
- * a/b/c/d.myProperty}.
- * @param type The target type required, not null.
- * @param <T> the value type
- * @return the converted value, never null.
- */
- @Override
- public <T> T get(String key, TypeLiteral<T> type) {
- String value = get(key);
- if (value != null) {
- List<PropertyConverter<T>> converters = getContext()
- .getPropertyConverters(type);
- ConversionContext context = new ConversionContext.Builder(this,
- getContext(), key,type).build();
- for (PropertyConverter<T> converter : converters) {
- try {
- T t = converter.convert(value, context);
- if (t != null) {
- return t;
- }
- } catch (Exception e) {
- Logger.getLogger(getClass().getName())
- .log(Level.FINEST, "PropertyConverter: " + converter + " failed to convert value: " + value,
- e);
- }
- }
- throw new ConfigException("Unparseable config value for type: " + type.getRawType().getName() + ": " + key
- + ", supported formats: " + context.getSupportedFormats());
- }
-
- return null;
- }
-
- @Override
- public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) {
- T val = get(key, type);
- if(val==null){
- return defaultValue;
- }
- return val;
- }
-
- @Override
- public Map<String, String> getProperties() {
- return properties;
- }
-
- @Override
- public Configuration with(ConfigOperator operator) {
- return operator.operate(this);
- }
-
- @Override
- public <T> T query(ConfigQuery<T> query) {
- return query.query(this);
- }
-
- @Override
- public ConfigurationContext getContext() {
- return ConfigurationFunctions.emptyConfigurationContext();
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- FrozenConfiguration that = (FrozenConfiguration) o;
-
- if (frozenAt != that.frozenAt) {
- return false;
- }
- if (properties != null ? !properties.equals(that.properties) : that.properties != null) {
- return false;
- }
- return id != null ? id.equals(that.id) : that.id == null;
- }
-
- @Override
- public int hashCode() {
- int result = properties != null ? properties.hashCode() : 0;
- result = 31 * result + (int) (frozenAt ^ (frozenAt >>> 32));
- result = 31 * result + (id != null ? id.hashCode() : 0);
- return result;
- }
-
- @Override
- public String toString() {
- return "FrozenConfiguration{" +
- "id=" + getId() + "," +
- "frozenAt=" + getFrozenAt() + "," +
- "properties=" + properties +
- '}';
- }
-
- /**
- * <p>Returns the moment in time when this frozen configuration has been created.</p>
- *
- * <p>The time is taken from {@linkplain System#currentTimeMillis()}</p>
- *
- * @see System#currentTimeMillis()
- * @return the moment in time when this configuration has been created
- */
- public long getFrozenAt() {
- return frozenAt;
- }
-
- /**
- * <p>Returns the unique id of this frozen configuration.</p>
- *
- * @return the unique id of this frozen configuration, never {@code null}
- */
- public UUID getId() {
- return id;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/4869d946/modules/events/src/main/java/org/apache/tamaya/events/FrozenPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/FrozenPropertySource.java b/modules/events/src/main/java/org/apache/tamaya/events/FrozenPropertySource.java
deleted file mode 100644
index 0bc71ce..0000000
--- a/modules/events/src/main/java/org/apache/tamaya/events/FrozenPropertySource.java
+++ /dev/null
@@ -1,135 +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.events;
-
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertyValue;
-import org.apache.tamaya.spisupport.PropertySourceComparator;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * PropertySource implementation that stores all current values of a given (possibly dynamic, contextual and non server
- * capable instance) and is fully serializable. Note that hereby only the scannable key/value pairs are considered.
- */
-public final class FrozenPropertySource implements PropertySource, Serializable {
- private static final long serialVersionUID = -6373137316556444171L;
- /**
- * The ordinal.
- */
- private final int ordinal;
- /**
- * The properties read.
- */
- private Map<String, PropertyValue> properties = new HashMap<>();
- /**
- * The PropertySource's name.
- */
- private final String name;
-
- private long frozenAt = System.currentTimeMillis();
-
- /**
- * Constructor.
- *
- * @param propertySource The base PropertySource.
- */
- private FrozenPropertySource(PropertySource propertySource) {
- this.properties.putAll(propertySource.getProperties());
- this.properties = Collections.unmodifiableMap(this.properties);
- this.ordinal = PropertySourceComparator.getOrdinal(propertySource);
- this.name = propertySource.getName();
- }
-
- /**
- * Creates a new FrozenPropertySource instance based on a PropertySource given.
- *
- * @param propertySource the property source to be frozen, not null.
- * @return the frozen property source.
- */
- public static FrozenPropertySource of(PropertySource propertySource) {
- if (propertySource instanceof FrozenPropertySource) {
- return (FrozenPropertySource) propertySource;
- }
- return new FrozenPropertySource(propertySource);
- }
-
- @Override
- public String getName() {
- return this.name;
- }
-
- public int getOrdinal() {
- return this.ordinal;
- }
-
- /**
- * Get the creation timestamp of this instance.
- * @return the creation timestamp
- */
- public long getFrozenAt(){
- return frozenAt;
- }
-
- @Override
- public PropertyValue get(String key) {
- return this.properties.get(key);
- }
-
- @Override
- public Map<String, PropertyValue> getProperties() {
- return properties;
- }
-
- @Override
- public boolean isScannable() {
- return true;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof FrozenPropertySource)) {
- return false;
- }
- FrozenPropertySource that = (FrozenPropertySource) o;
- return ordinal == that.ordinal && properties.equals(that.properties);
- }
-
- @Override
- public int hashCode() {
- int result = ordinal;
- result = 31 * result + properties.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "FrozenPropertySource{" +
- "name=" + name +
- ", ordinal=" + ordinal +
- ", properties=" + properties +
- '}';
- }
-}