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 2015/12/18 02:45:32 UTC
[04/10] incubator-tamaya git commit: Simplified events module,
adapted documentation as well. Removed model dependency from events,
since events is the more general module here.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/delta/ConfigurationChangeBuilder.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/delta/ConfigurationChangeBuilder.java b/modules/events/src/main/java/org/apache/tamaya/events/delta/ConfigurationChangeBuilder.java
deleted file mode 100644
index ff5e26b..0000000
--- a/modules/events/src/main/java/org/apache/tamaya/events/delta/ConfigurationChangeBuilder.java
+++ /dev/null
@@ -1,262 +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.delta;
-
-import org.apache.tamaya.Configuration;
-
-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 org.apache.tamaya.spi.PropertySource}. Consumers of these events
- * can observing 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 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 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.
- */
- 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.
- *
- * @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 current all changes
- * that must be appied 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(Configuration map1, Configuration map2) {
- List<PropertyChangeEvent> changes = new ArrayList<>();
- for (Map.Entry<String, String> en : map1.getProperties().entrySet()) {
- String val = map2.get(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.get(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()));
- }
- }
- 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 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(newState, this.source)) {
- 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 chining.
- */
- 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) {
- changes.putAll(changes);
- 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);
- }
-
- /*
- * (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "ConfigurationChangeSetBuilder [config=" + source + ", " +
- ", delta=" + delta + "]";
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/delta/ConfigurationContextChange.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/delta/ConfigurationContextChange.java b/modules/events/src/main/java/org/apache/tamaya/events/delta/ConfigurationContextChange.java
deleted file mode 100644
index 0aef2fd..0000000
--- a/modules/events/src/main/java/org/apache/tamaya/events/delta/ConfigurationContextChange.java
+++ /dev/null
@@ -1,192 +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.delta;
-
-import org.apache.tamaya.spi.PropertySource;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-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 org.apache.tamaya.events.delta.PropertySourceChangeBuilder}.
- *
- * Created by Anatole on 22.10.2014.
- */
-public final class ConfigurationContextChange implements Serializable{
-
- private static final long serialVersionUID = 1L;
- /** The base property provider/configuration. */
- private List<PropertySourceChange> changedPropertySources = new ArrayList<>();
- /** 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();
-
- /**
- * Get an empty change set for the given provider.
- * @return an empty ConfigurationChangeSet instance.
- */
- public static ConfigurationContextChange emptyChangeSet(){
- return ConfigurationContextChangeBuilder.of().build();
- }
-
- /**
- * Constructor used by {@link org.apache.tamaya.events.delta.PropertySourceChangeBuilder}.
- * @param builder The builder used, not null.
- */
- ConfigurationContextChange(ConfigurationContextChangeBuilder builder) {
- this.changedPropertySources.addAll(builder.changedPropertySources);
- if(builder.version!=null){
- this.version = builder.version;
- }
- if(builder.timestamp!=null){
- this.timestamp = builder.timestamp;
- }
- }
-
- /**
- * Get the base version, usable for optimistic locking.
- * @return the base version.
- */
- 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.
- */
- public long getTimestamp(){
- return timestamp;
- }
-
- /**
- * Get the changes recorded.
- * @return the recorded changes, never null.
- */
- public Collection<PropertySourceChange> getPropertySourceChanges(){
- return Collections.unmodifiableCollection(this.changedPropertySources);
- }
-
- /**
- * Get the property source updates.
- * @return the recorded changes, never null.
- */
- public Collection<PropertySourceChange> getPropertySourceUpdates(){
- List<PropertySourceChange> result = new ArrayList<>();
- for (PropertySourceChange pc : this.changedPropertySources) {
- if (pc.getChangeType() == ChangeType.UPDATED) {
- result.add(pc);
- }
- }
- return result;
-// return Collections.unmodifiableCollection(this.changedPropertySources).stream()
-// .filter(pc -> pc.getChangeType()==ChangeType.UPDATED).collect(Collectors.toList());
- }
-
- /**
- * Get the property sources to be removed.
- * @return the recorded changes, never null.
- */
- public Collection<PropertySource> getRemovedPropertySources(){
- List<PropertySource> result = new ArrayList<>();
- for (PropertySourceChange pc : this.changedPropertySources) {
- if (pc.getChangeType() == ChangeType.DELETED) {
- result.add(pc.getResource());
- }
- }
- return result;
-// return getPropertySourceChanges().stream().filter(pc -> pc.getChangeType()==ChangeType.DELETED).
-// map(ps -> ps.getPropertySource()).collect(Collectors.toList());
- }
-
- /**
- * Get the property sources to be added.
- * @return the recorded changes, never null.
- */
- public Collection<PropertySource> getAddedPropertySources(){
- List<PropertySource> result = new ArrayList<>();
- for (PropertySourceChange pc : this.changedPropertySources) {
- if (pc.getChangeType() == ChangeType.NEW) {
- result.add(pc.getResource());
- }
- }
- return result;
-// return getPropertySourceChanges().stream().filter(pc -> pc.getChangeType()==ChangeType.NEW).
-// map(ps -> ps.getPropertySource()).collect(Collectors.toList());
- }
-
- /**
- * Get the property sources to be updated.
- * @return the recorded changes, never null.
- */
- public Collection<PropertySource> getUpdatedPropertySources(){
- List<PropertySource> result = new ArrayList<>();
- for (PropertySourceChange pc : this.changedPropertySources) {
- if (pc.getChangeType() == ChangeType.UPDATED) {
- result.add(pc.getResource());
- }
- }
- return result;
-// return getPropertySourceChanges().stream().filter(pc -> pc.getChangeType()==ChangeType.UPDATED).
-// map(ps -> ps.getPropertySource()).collect(Collectors.toList());
- }
-
- /**
- * Checks if the given propertySource is affected (added, changed or removed).
- * @param propertySource the propertySource, not null.
- * @return true, if the given propertySource ia affected.
- */
- public boolean isAffected(PropertySource propertySource) {
- for (PropertySourceChange ps : this.changedPropertySources) {
- if (ps.getResource() == propertySource ||
- ps.getResource().getName().equals(propertySource.getName())) {
- return true;
- }
- }
- return false;
-// return this.changedPropertySources.stream().filter(ps -> ps.getPropertySource()==propertySource ||
-// ps.getPropertySource().getName().equals(propertySource.getName())).findAny().isPresent();
- }
-
- /**
- * CHecks if the current change set does not contain any changes.
- * @return tru, if the change set is empty.
- */
- public boolean isEmpty(){
- return this.changedPropertySources.isEmpty();
- }
-
-
- @Override
- public String toString() {
- return "ConfigurationContextChange{" +
- "changedPropertySources=" + changedPropertySources +
- ", version='" + version + '\'' +
- ", timestamp=" + timestamp +
- '}';
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/delta/ConfigurationContextChangeBuilder.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/delta/ConfigurationContextChangeBuilder.java b/modules/events/src/main/java/org/apache/tamaya/events/delta/ConfigurationContextChangeBuilder.java
deleted file mode 100644
index 3e21635..0000000
--- a/modules/events/src/main/java/org/apache/tamaya/events/delta/ConfigurationContextChangeBuilder.java
+++ /dev/null
@@ -1,159 +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.delta;
-
-import org.apache.tamaya.spi.PropertySource;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Models a set current changes applied to a {@link org.apache.tamaya.spi.PropertySource}. Consumers of these events
- * can observing 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 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 org.apache.tamaya.Configuration} to create a change
- * event on configuration level.
- * </ol>
- */
-public final class ConfigurationContextChangeBuilder {
- /**
- * The recorded changes.
- */
- final List<PropertySourceChange> changedPropertySources = new ArrayList<>();
- /**
- * The version configured, or null, for generating a default.
- */
- String version;
- /**
- * The optional timestamp in millis of this epoch.
- */
- Long timestamp;
-
- /**
- * Constructor.
- */
- private ConfigurationContextChangeBuilder() {
- }
-
- /**
- * Creates a new instance current this builder.
- *
- * @return the builder for chaining.
- */
- public static ConfigurationContextChangeBuilder of() {
- return new ConfigurationContextChangeBuilder();
- }
-
- /*
- * 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 ConfigurationContextChangeBuilder 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 ConfigurationContextChangeBuilder 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 propertySource the new target state, not null.
- * @return the builder for chaining.
- */
- public ConfigurationContextChangeBuilder newPropertySource(PropertySource propertySource) {
- this.changedPropertySources.add(PropertySourceChange.ofAdded(propertySource));
- return this;
- }
-
- /**
- * This method records all changes to be applied to the base property provider/configuration to
- * achieve the given target state.
- *
- * @param propertySource the new target state, not null.
- * @return the builder for chaining.
- */
- public ConfigurationContextChangeBuilder removedPropertySource(PropertySource propertySource) {
- this.changedPropertySources.add(PropertySourceChange.ofDeleted(propertySource));
- return this;
- }
-
- /**
- * This method records all changes to be applied to the base property provider/configuration to
- * achieve the given target state.
- *
- * @param propertySourceChange the change state, not null.
- * @return the builder for chaining.
- */
- public ConfigurationContextChangeBuilder changedPropertySource(PropertySourceChange propertySourceChange) {
- this.changedPropertySources.add(Objects.requireNonNull(propertySourceChange));
- 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.changedPropertySources.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.changedPropertySources.clear();
- }
-
- /**
- * Builds the corresponding change set.
- *
- * @return the new change set, never null.
- */
- public ConfigurationContextChange build() {
- return new ConfigurationContextChange(this);
- }
-
- /*
- * (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "ConfigurationContextChangeBuilder [propertySources=" + changedPropertySources + "]";
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/delta/PropertySourceChange.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/delta/PropertySourceChange.java b/modules/events/src/main/java/org/apache/tamaya/events/delta/PropertySourceChange.java
deleted file mode 100644
index 330f3b0..0000000
--- a/modules/events/src/main/java/org/apache/tamaya/events/delta/PropertySourceChange.java
+++ /dev/null
@@ -1,236 +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.delta;
-
-import org.apache.tamaya.events.ChangeNotification;
-import org.apache.tamaya.events.FrozenPropertySource;
-import org.apache.tamaya.spi.PropertySource;
-
-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 org.apache.tamaya.events.delta.PropertySourceChangeBuilder}.
- *
- * Created by Anatole on 22.10.2014.
- */
-public final class PropertySourceChange implements ChangeNotification<PropertySource>, Serializable{
-
- private static final long serialVersionUID = 1L;
- /** The base property provider/configuration. */
- private FrozenPropertySource propertySource;
- /** 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 Map<String,PropertyChangeEvent> changes = new HashMap<>();
- /** The overall type of change. */
- private ChangeType changeType;
-
- /**
- * Constructor used by {@link org.apache.tamaya.events.delta.PropertySourceChangeBuilder}.
- * @param builder The builder used, not null.
- */
- PropertySourceChange(PropertySourceChangeBuilder builder) {
- this.propertySource = FrozenPropertySource.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;
- }
- this.changeType = builder.changeType;
- }
-
- /**
- * Gets the type of change for this PropertySource.
- * @return the type of change for this PropertySource, never null.
- */
- public ChangeType getChangeType(){
- return this.changeType;
- }
-
- /**
- * Get the underlying property provider/configuration.
- * @return the underlying property provider/configuration, or null, if the change instance was deserialized.
- */
- public PropertySource getResource(){
- return this.propertySource;
- }
-
- /**
- * Get the base version, usable for optimistic locking.
- * @return the base version.
- */
- 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.
- */
- 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();
- }
-
-
- /**
- * Create a change event for a new PropertySource that was added.
- * @param propertySource the new property source, not null.
- * @return a new PropertySourceChange, representing a PropertySource that was added.
- */
- public static PropertySourceChange ofAdded(PropertySource propertySource) {
- return PropertySourceChangeBuilder.of(propertySource, ChangeType.NEW).build();
- }
-
- /**
- * Create a change event for a deleted PropertySource.
- * @param propertySource the deleted property source, not null.
- * @return a new PropertySourceChange, representing a PropertySource that was deleted.
- */
- public static PropertySourceChange ofDeleted(PropertySource propertySource) {
- return PropertySourceChangeBuilder.of(propertySource, ChangeType.DELETED).build();
- }
-
- @Override
- public String toString() {
- return "PropertySourceChange{" +
- "changeType=" + changeType +
- ", propertySource=" + propertySource +
- ", version='" + version + '\'' +
- ", timestamp=" + timestamp +
- '}';
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/delta/PropertySourceChangeBuilder.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/delta/PropertySourceChangeBuilder.java b/modules/events/src/main/java/org/apache/tamaya/events/delta/PropertySourceChangeBuilder.java
deleted file mode 100644
index a0c0027..0000000
--- a/modules/events/src/main/java/org/apache/tamaya/events/delta/PropertySourceChangeBuilder.java
+++ /dev/null
@@ -1,258 +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.delta;
-
-import org.apache.tamaya.spi.PropertySource;
-
-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 org.apache.tamaya.spi.PropertySource}. Consumers of these events
- * can observing 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 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 org.apache.tamaya.Configuration} to create a change
- * event on configuration level.
- * </ol>
- */
-public final class PropertySourceChangeBuilder {
- /**
- * The recorded changes.
- */
- final SortedMap<String, PropertyChangeEvent> delta = new TreeMap<>();
- /**
- * The underlying configuration/provider.
- */
- PropertySource source;
- /**
- * The version configured, or null, for generating a default.
- */
- String version;
- /**
- * The optional timestamp in millis of this epoch.
- */
- Long timestamp;
-
- /** The type of change. */
- ChangeType changeType;
-
- /**
- * Constructor.
- *
- * @param source the underlying configuration/provider, not null.
- */
- private PropertySourceChangeBuilder(PropertySource source, ChangeType changeType) {
- this.source = Objects.requireNonNull(source);
- this.changeType = Objects.requireNonNull(changeType);
- }
-
- /**
- * Creates a new instance current this builder.
- *
- * @param source the underlying property provider/configuration, not null.
- * @return the builder for chaining.
- */
- public static PropertySourceChangeBuilder of(PropertySource source, ChangeType changeType) {
- return new PropertySourceChangeBuilder(source, changeType);
- }
-
- /**
- * Compares the two property config/configurations and creates a collection current all changes
- * that must be appied 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(PropertySource map1, PropertySource map2) {
- List<PropertyChangeEvent> changes = new ArrayList<>();
- for (Map.Entry<String, String> en : map1.getProperties().entrySet()) {
- String val = map2.get(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.get(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 PropertySourceChangeBuilder 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 PropertySourceChangeBuilder 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 PropertySourceChangeBuilder addChanges(PropertySource newState) {
- Collection<PropertyChangeEvent> events = PropertySourceChangeBuilder.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 PropertySourceChangeBuilder remove(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 PropertySourceChangeBuilder putAll(Map<String, String> changes) {
- changes.putAll(changes);
- 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 PropertySourceChangeBuilder 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();
- }
-
- public PropertySourceChangeBuilder setChangeType(ChangeType changeType) {
- this.changeType = changeType;
- return this;
- }
-
- /**
- * Builds the corresponding change set.
- *
- * @return the new change set, never null.
- */
- public PropertySourceChange build() {
- return new PropertySourceChange(this);
- }
-
- /*
- * (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "PropertiesChangeBuilder [source=" + source + ", " +
- ", delta=" + delta + "]";
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/folderobserver/FileChangeListener.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/folderobserver/FileChangeListener.java b/modules/events/src/main/java/org/apache/tamaya/events/folderobserver/FileChangeListener.java
index dd64145..af51063 100644
--- a/modules/events/src/main/java/org/apache/tamaya/events/folderobserver/FileChangeListener.java
+++ b/modules/events/src/main/java/org/apache/tamaya/events/folderobserver/FileChangeListener.java
@@ -19,6 +19,7 @@
package org.apache.tamaya.events.folderobserver;
import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.events.PropertySourceChange;
import java.io.IOException;
import java.nio.file.FileSystem;
@@ -34,7 +35,7 @@ import java.util.logging.Logger;
/**
* Class that has the responsibility to watch the folder and then publish the changes to a
- * {@link org.apache.tamaya.events.delta.PropertySourceChange}.
+ * {@link PropertySourceChange}.
* @see ObservingPropertySourceProvider
* This listener will wait to events and wait to one second to watch again.
* <p>If new file was created or modified will commit from this file.</p>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/folderobserver/ObservingPropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/folderobserver/ObservingPropertySourceProvider.java b/modules/events/src/main/java/org/apache/tamaya/events/folderobserver/ObservingPropertySourceProvider.java
index 9b88c0a..14692f4 100644
--- a/modules/events/src/main/java/org/apache/tamaya/events/folderobserver/ObservingPropertySourceProvider.java
+++ b/modules/events/src/main/java/org/apache/tamaya/events/folderobserver/ObservingPropertySourceProvider.java
@@ -19,9 +19,11 @@
package org.apache.tamaya.events.folderobserver;
import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.ConfigurationProvider;
import org.apache.tamaya.events.ConfigEventManager;
-import org.apache.tamaya.events.delta.ConfigurationContextChange;
-import org.apache.tamaya.events.delta.ConfigurationContextChangeBuilder;
+import org.apache.tamaya.events.PropertySourceChange;
+import org.apache.tamaya.events.ConfigurationContextChange;
+import org.apache.tamaya.events.ConfigurationContextChangeBuilder;
import org.apache.tamaya.format.ConfigurationData;
import org.apache.tamaya.format.ConfigurationFormat;
import org.apache.tamaya.format.FlattenedDefaultPropertySource;
@@ -50,7 +52,7 @@ import java.util.logging.Logger;
* This implementation run in a folder taking up all file compatible with the given
* ConfigurationFormats. When a file is added, deleted or modified the PropertySourceProvider
* will adapt the changes automatically and trigger according
- * {@link org.apache.tamaya.events.delta.PropertySourceChange} events.
+ * {@link PropertySourceChange} events.
* The default folder is META-INF/config, but you can change using the absolute path in
* "-Dtamaya.configdir" parameter.
*/
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigChangeObserver.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigChangeObserver.java b/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigChangeObserver.java
new file mode 100644
index 0000000..8903566
--- /dev/null
+++ b/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigChangeObserver.java
@@ -0,0 +1,107 @@
+/*
+ * 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.internal;
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.events.*;
+
+import java.util.*;
+import java.util.logging.Logger;
+
+/**
+ * Timer task that regularly checks the configuration for changes.
+ */
+public class DefaultConfigChangeObserver {
+
+ private static final long START_DELAY = 5000L;
+
+ private static final Logger LOG = Logger.getLogger(DefaultConfigChangeObserver.class.getName());
+
+ private Timer timer = new Timer("DefaultConfigChangeObserver", true);
+
+ private long checkPeriod = 2000L;
+
+ private volatile FrozenConfiguration lastConfig;
+
+ private volatile boolean running;
+
+ /**
+ * Constructor. Also loads all registered listeners.
+ */
+ public DefaultConfigChangeObserver() {
+ LOG.info("Registering config change observer, rechecking config changes every " + checkPeriod + " ms.");
+ timer.scheduleAtFixedRate(new TimerTask() {
+ @Override
+ public void run() {
+ if(running) {
+ checkConfigurationUpdate();
+ }
+ }
+ }, START_DELAY, checkPeriod);
+ }
+
+
+ public void checkConfigurationUpdate() {
+ LOG.finest("Checking configuration for changes...");
+ FrozenConfiguration newConfig = FrozenConfiguration.of(ConfigurationProvider.getConfiguration());
+ ConfigurationChange changes = null;
+ if(lastConfig==null){
+ changes = ConfigurationChangeBuilder.of(newConfig).putAll(newConfig.getProperties())
+ .build();
+ }else{
+ changes = ConfigurationChangeBuilder.of(lastConfig).addChanges(newConfig)
+ .build();
+ }
+ if(!changes.isEmpty()) {
+ LOG.info("Identified configuration changes, publishing change event...");
+ ConfigEventManager.fireEvent(changes);
+ }
+ }
+
+ public long getCheckPeriod() {
+ return checkPeriod;
+ }
+
+ public boolean isMonitoring(){
+ return running;
+ }
+
+ public void enableMonitoring(boolean enable){
+ this.running = true;
+ }
+
+ /**
+ * Sets the new check period, cancels the currently running timer and schedules a new task with the new checkperiod
+ * and a startup delay of 500ms.
+ * @param checkPeriod
+ */
+ public void setCheckPeriod(long checkPeriod) {
+ LOG.finest("Resetting check period to " + checkPeriod + " ms, reregistering timer.");
+ this.checkPeriod = checkPeriod;
+ timer.cancel();
+ timer.scheduleAtFixedRate(new TimerTask() {
+ @Override
+ public void run() {
+ if(running) {
+ checkConfigurationUpdate();
+ }
+ }
+ }, 500L, checkPeriod);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigEventManagerSpi.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigEventManagerSpi.java b/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigEventManagerSpi.java
index 6773c7d..75f2c91 100644
--- a/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigEventManagerSpi.java
+++ b/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigEventManagerSpi.java
@@ -18,18 +18,15 @@
*/
package org.apache.tamaya.events.internal;
-import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.events.ConfigEvent;
import org.apache.tamaya.events.ConfigEventListener;
import org.apache.tamaya.events.spi.ConfigEventManagerSpi;
import org.apache.tamaya.spi.ServiceContextManager;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -41,14 +38,18 @@ public class DefaultConfigEventManagerSpi implements ConfigEventManagerSpi {
private static final Logger LOG = Logger.getLogger(DefaultConfigEventManagerSpi.class.getName());
- private Map<Type, List<ConfigEventListener<?>>> listenerMap = new ConcurrentHashMap<>();
+ private Map<Class,List<ConfigEventListener>> listeners = new ConcurrentHashMap<>();
+
+ private ExecutorService publisher = Executors.newCachedThreadPool();
+
+ private DefaultConfigChangeObserver changeObserver = new DefaultConfigChangeObserver();
/**
* Constructor. Also loads all registered listeners.
*/
public DefaultConfigEventManagerSpi() {
try {
- for (ConfigEventListener<?> l : ServiceContextManager.getServiceContext().getServices(ConfigEventListener.class)) {
+ for (ConfigEventListener l : ServiceContextManager.getServiceContext().getServices(ConfigEventListener.class)) {
try {
addListener(l);
} catch (Exception e) {
@@ -61,37 +62,76 @@ public class DefaultConfigEventManagerSpi implements ConfigEventManagerSpi {
}
@Override
- public <T> void addListener(ConfigEventListener<T> l) {
- Type type = TypeLiteral.getGenericInterfaceTypeParameters(l.getClass(), ConfigEventListener.class)[0];
- List<ConfigEventListener<?>> listeners = listenerMap.get(type);
- if (listeners == null) {
- listeners = Collections.synchronizedList(new ArrayList<ConfigEventListener<?>>());
- listenerMap.put(type, listeners);
+ public void addListener(ConfigEventListener l){
+ addListener(l, ConfigEvent.class);
+ }
+
+ @Override
+ public <T extends ConfigEvent> void addListener(ConfigEventListener l, Class<T> eventType){
+ List<ConfigEventListener> ls = listeners.get(eventType);
+ if(ls==null){
+ ls = Collections.synchronizedList(new ArrayList<ConfigEventListener>());
+ listeners.put(eventType, ls);
}
- synchronized (listeners) {
- if (!listeners.contains(l)) {
- listeners.add(l);
+ synchronized (ls){
+ if(!ls.contains(l)){
+ ls.add(l);
}
}
}
@Override
- public <T> void removeListener(ConfigEventListener<T> l) {
- Type type = TypeLiteral.getGenericInterfaceTypeParameters(l.getClass(), ConfigEventListener.class)[0];
- List<ConfigEventListener<?>> listeners = listenerMap.get(type);
- if (listeners != null) {
- synchronized (listeners) {
- listeners.remove(l);
+ public void removeListener(ConfigEventListener l){
+ removeListener(l, ConfigEvent.class);
+ }
+
+ @Override
+ public <T extends ConfigEvent> void removeListener(ConfigEventListener l, Class<T> eventType) {
+ List<ConfigEventListener> targets = this.listeners.get(eventType);
+ if(targets!=null) {
+ // forward to explicit listeners
+ synchronized (targets) {
+ targets.remove(l);
}
}
}
@Override
- public <T> void fireEvent(T event, Class<T> eventType) {
- List<ConfigEventListener<?>> listeners = listenerMap.get(eventType);
- if (listeners != null) {
- synchronized (listeners) {
- for (ConfigEventListener l : listeners) {
+ public Collection<? extends ConfigEventListener> getListeners(Class<? extends ConfigEvent> eventType) {
+ List<ConfigEventListener> targets = this.listeners.get(eventType);
+ if(targets!=null){
+ synchronized(targets){
+ return new ArrayList<>(targets);
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public Collection<? extends ConfigEventListener> getListeners() {
+ Set<ConfigEventListener> targets = new HashSet<>();
+ for(List<ConfigEventListener> l:this.listeners.values()){
+ targets.addAll(l);
+ }
+ return targets;
+ }
+
+ @Override
+ public void fireEvent(ConfigEvent<?> event) {
+ List<ConfigEventListener> targets = this.listeners.get(event.getClass());
+ if(targets!=null) {
+ // forward to explicit listeners
+ synchronized (targets) {
+ for (ConfigEventListener l : targets) {
+ l.onConfigEvent(event);
+ }
+ }
+ }
+ // forward to global listeners
+ targets = this.listeners.get(ConfigEvent.class);
+ if(targets!=null) {
+ synchronized (targets) {
+ for (ConfigEventListener l : targets) {
l.onConfigEvent(event);
}
}
@@ -99,12 +139,64 @@ public class DefaultConfigEventManagerSpi implements ConfigEventManagerSpi {
}
@Override
- public <T> Collection<ConfigEventListener<T>> getListeners(Class<T> eventType) {
- List<ConfigEventListener<?>> listeners =
- listenerMap.get(eventType);
- if (listeners != null) {
- return Collection.class.cast(listeners);
+ public void fireEventAsynch(ConfigEvent<?> event) {
+ List<ConfigEventListener> targets = this.listeners.get(event.getClass());
+ if(targets!=null) {
+ // forward to explicit listeners
+ synchronized (targets) {
+ for (ConfigEventListener l : targets) {
+ publisher.execute(new PublishConfigChangeTask(l, event));
+ }
+ }
+ }
+ // forward to global listeners
+ targets = this.listeners.get(ConfigEvent.class);
+ if(targets!=null) {
+ synchronized (targets) {
+ for (ConfigEventListener l : targets) {
+ publisher.execute(new PublishConfigChangeTask(l, event));
+ }
+ }
+ }
+ }
+
+ @Override
+ public long getChangeMonitoringPeriod() {
+ return changeObserver.getCheckPeriod();
+ }
+
+ @Override
+ public void setChangeMonitoringPeriod(long millis){
+ changeObserver.setCheckPeriod(millis);
+ }
+
+ @Override
+ public boolean isChangeMonitorActive() {
+ return changeObserver.isMonitoring();
+ }
+
+ @Override
+ public void enableChangeMonitor(boolean enable) {
+ changeObserver.enableMonitoring(enable);
+ }
+
+
+ /**
+ * Tasks to inform observers on detected configuration changes.
+ */
+ private static final class PublishConfigChangeTask implements Runnable{
+
+ private ConfigEventListener l;
+ private ConfigEvent<?> changes;
+
+ public PublishConfigChangeTask(ConfigEventListener l, ConfigEvent<?> changes) {
+ this.l = Objects.requireNonNull(l);
+ this.changes = Objects.requireNonNull(changes);
+ }
+
+ @Override
+ public void run() {
+ l.onConfigEvent(changes);
}
- return Collections.emptyList();
}
}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigObserverSpi.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigObserverSpi.java b/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigObserverSpi.java
deleted file mode 100644
index 6bcb44c..0000000
--- a/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigObserverSpi.java
+++ /dev/null
@@ -1,158 +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.internal;
-
-import org.apache.tamaya.ConfigurationProvider;
-import org.apache.tamaya.events.ConfigEventManager;
-import org.apache.tamaya.events.ConfigListener;
-import org.apache.tamaya.events.FrozenConfiguration;
-import org.apache.tamaya.events.delta.ConfigurationChange;
-import org.apache.tamaya.events.delta.ConfigurationChangeBuilder;
-import org.apache.tamaya.events.spi.ConfigObserverSpi;
-import org.apache.tamaya.spi.ServiceContextManager;
-
-import java.beans.PropertyChangeEvent;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Default implementation of {@link org.apache.tamaya.events.spi.ConfigObserverSpi} just forwarding all
- * events synchronously to the listeners.
- */
-public class DefaultConfigObserverSpi implements ConfigObserverSpi {
-
- private static final long START_DELAY = 5000L;
-
- private static final Logger LOG = Logger.getLogger(DefaultConfigObserverSpi.class.getName());
-
- private Set<String> keys = new HashSet<>();
-
- private Timer timer = new Timer("ConfigurationObserver", true);
-
- private long checkPeriod = 2000L;
-
- private volatile FrozenConfiguration lastConfig;
-
- private ExecutorService publisher = Executors.newCachedThreadPool();
-
- private volatile boolean running;
-
- /**
- * Constructor. Also loads all registered listeners.
- */
- public DefaultConfigObserverSpi() {
- try {
- // Load and register ConfigListener from the current ServiceContext
- for (ConfigListener l : ServiceContextManager.getServiceContext().getServices(ConfigListener.class)) {
- ConfigEventManager.addListener(l);
- }
- } catch (Exception e) {
- LOG.log(Level.WARNING, "Failed to load configured listeners.", e);
- }
- timer.scheduleAtFixedRate(new TimerTask() {
- @Override
- public void run() {
- if(running) {
- checkConfigurationUpdate();
- }
- }
- }, START_DELAY, checkPeriod);
- }
-
- public void checkConfigurationUpdate() {
- LOG.finest("Checking configuration for changes...");
- FrozenConfiguration newConfig = FrozenConfiguration.of(ConfigurationProvider.getConfiguration());
- ConfigurationChange changes = null;
- if(lastConfig==null){
- changes = ConfigurationChangeBuilder.of(newConfig).putAll(newConfig.getProperties())
- .build();
- }else{
- changes = ConfigurationChangeBuilder.of(lastConfig).addChanges(newConfig)
- .build();
- }
- Set<ConfigListener> affected = new HashSet<>();
- for(PropertyChangeEvent evt: changes.getChanges()) {
- for (String key : keys) {
- if (evt.getPropertyName().matches(key)) {
- ConfigEventManager.fireEvent(changes);
- return;
- }
- }
- }
- }
-
- @Override
- public synchronized <T> void addObservedKeys(Collection<String> keys) {
- this.keys.addAll(keys);
- }
-
- @Override
- public synchronized <T> void removeObservedKeys(Collection<String> keys) {
- this.keys.removeAll(keys);
- }
-
-
- @Override
- public synchronized Set<String> getObservedKeys() {
- return Collections.unmodifiableSet(this.keys);
- }
-
- @Override
- public long getCheckPeriod() {
- return checkPeriod;
- }
-
- @Override
- public boolean isRunning(){
- return running;
- }
-
- @Override
- public void enableObservation(boolean enable){
- this.running = true;
- }
-
- /**
- * Tasks to inform observers on detected configuration changes.
- */
- private static final class PublishConfigChangeTask implements Runnable{
-
- private ConfigListener l;
- private ConfigurationChange changes;
-
- public PublishConfigChangeTask(ConfigListener l, ConfigurationChange changes) {
- this.l = Objects.requireNonNull(l);
- this.changes = Objects.requireNonNull(changes);
- }
-
- @Override
- public void run() {
- l.onConfigEvent(changes);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigurationContextChangeListener.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigurationContextChangeListener.java b/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigurationContextChangeListener.java
index fed5e40..e49856d 100644
--- a/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigurationContextChangeListener.java
+++ b/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigurationContextChangeListener.java
@@ -19,13 +19,17 @@
package org.apache.tamaya.events.internal;
import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.events.ConfigEvent;
import org.apache.tamaya.events.ConfigEventListener;
-import org.apache.tamaya.events.delta.ConfigurationContextChange;
+import org.apache.tamaya.events.ConfigurationContextChange;
import org.apache.tamaya.spi.ConfigurationContext;
import org.apache.tamaya.spi.ConfigurationContextBuilder;
import org.apache.tamaya.spi.PropertySource;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -33,35 +37,38 @@ import java.util.logging.Logger;
* Default ConfigEventListener for ConfigurationContextChange events that updates the current context, if resources were
* affected.
*/
-public class DefaultConfigurationContextChangeListener implements ConfigEventListener<ConfigurationContextChange> {
+public class DefaultConfigurationContextChangeListener implements ConfigEventListener {
private static final Logger LOG = Logger.getLogger(DefaultConfigurationContextChangeListener.class.getName());
@Override
- public void onConfigEvent(ConfigurationContextChange event) {
- ConfigurationContext context = ConfigurationProvider.getConfigurationContext();
- List<PropertySource> affectedPropertySources = new ArrayList<>();
- for (PropertySource ps : context.getPropertySources()) {
- if (event.isAffected(ps)) {
- affectedPropertySources.add(ps);
+ public void onConfigEvent(ConfigEvent<?> event) {
+ if(event.getClass() == ConfigurationContextChange.class) {
+ ConfigurationContextChange contextChange = (ConfigurationContextChange) event;
+ ConfigurationContext context = ConfigurationProvider.getConfigurationContext();
+ List<PropertySource> affectedPropertySources = new ArrayList<>();
+ for (PropertySource ps : context.getPropertySources()) {
+ if (contextChange.isAffected(ps)) {
+ affectedPropertySources.add(ps);
+ }
}
- }
- ConfigurationContextBuilder newContextBuilder = ConfigurationProvider.getConfigurationContextBuilder()
- .setContext(context);
- if (!affectedPropertySources.isEmpty()) {
- Set<String> propertySourceNames = new HashSet<>();
- for (PropertySource removed : event.getRemovedPropertySources()) {
- propertySourceNames.add(removed.getName());
+ ConfigurationContextBuilder newContextBuilder = ConfigurationProvider.getConfigurationContextBuilder()
+ .setContext(context);
+ if (!affectedPropertySources.isEmpty()) {
+ Set<String> propertySourceNames = new HashSet<>();
+ for (PropertySource removed : contextChange.getRemovedPropertySources()) {
+ propertySourceNames.add(removed.getName());
+ }
+ newContextBuilder.removePropertySources(propertySourceNames);
+ }
+ newContextBuilder.addPropertySources(contextChange.getAddedPropertySources());
+ newContextBuilder.addPropertySources(contextChange.getUpdatedPropertySources());
+ ConfigurationContext newContext = newContextBuilder.build();
+ try {
+ ConfigurationProvider.setConfigurationContext(newContext);
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "Failed to update the current ConfigurationContext due to config model changes", e);
}
- newContextBuilder.removePropertySources(propertySourceNames);
- }
- newContextBuilder.addPropertySources(event.getAddedPropertySources());
- newContextBuilder.addPropertySources(event.getUpdatedPropertySources());
- ConfigurationContext newContext = newContextBuilder.build();
- try {
- ConfigurationProvider.setConfigurationContext(newContext);
- } catch (Exception e) {
- LOG.log(Level.INFO, "Failed to update the current ConfigurationContext due to config model changes", e);
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/internal/LoggingConfigListener.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/internal/LoggingConfigListener.java b/modules/events/src/main/java/org/apache/tamaya/events/internal/LoggingConfigListener.java
index 43b2700..41d6924 100644
--- a/modules/events/src/main/java/org/apache/tamaya/events/internal/LoggingConfigListener.java
+++ b/modules/events/src/main/java/org/apache/tamaya/events/internal/LoggingConfigListener.java
@@ -18,20 +18,24 @@
*/
package org.apache.tamaya.events.internal;
-import org.apache.tamaya.events.ConfigListener;
-import org.apache.tamaya.events.delta.ConfigurationChange;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.events.ConfigEvent;
+import org.apache.tamaya.events.ConfigEventListener;
+import org.apache.tamaya.events.ConfigurationChange;
import java.util.logging.Logger;
/**
* Simple ConfigListener that simply logs any detected config changes to INFO level.
*/
-public class LoggingConfigListener implements ConfigListener{
+public class LoggingConfigListener implements ConfigEventListener {
private static final Logger LOG = Logger.getLogger(LoggingConfigListener.class.getName());
@Override
- public void onConfigEvent(ConfigurationChange event) {
- LOG.info("Configuration changed: " + event);
+ public void onConfigEvent(ConfigEvent<?> event) {
+ if(event.getResourceType()== Configuration.class) {
+ LOG.info("Configuration changed: " + event);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/package-info.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/package-info.java b/modules/events/src/main/java/org/apache/tamaya/events/package-info.java
index 33f5f25..e175ceb 100644
--- a/modules/events/src/main/java/org/apache/tamaya/events/package-info.java
+++ b/modules/events/src/main/java/org/apache/tamaya/events/package-info.java
@@ -18,6 +18,7 @@
*/
/**
* This package provides the main building blocks for handling configuration changes, such as
- * {@link org.apache.tamaya.events.ConfigEventManager}, {@link org.apache.tamaya.events.ConfigEventListener}.
+ * {@link org.apache.tamaya.events.ConfigEventManager}, {@link org.apache.tamaya.events.ConfigEventListener} and
+ * artifacts to describe the changes (delta) of a Configuration or a PropertySource.
*/
package org.apache.tamaya.events;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/spi/BaseConfigEvent.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/spi/BaseConfigEvent.java b/modules/events/src/main/java/org/apache/tamaya/events/spi/BaseConfigEvent.java
new file mode 100644
index 0000000..15f3dfd
--- /dev/null
+++ b/modules/events/src/main/java/org/apache/tamaya/events/spi/BaseConfigEvent.java
@@ -0,0 +1,69 @@
+/*
+ * 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.spi;
+
+import org.apache.tamaya.events.ConfigEvent;
+
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * Abstract base class for implementing your own configuration events.
+ * @param <T> the vent type
+ */
+public abstract class BaseConfigEvent<T> implements ConfigEvent<T> {
+ private long timestamp = System.currentTimeMillis();
+ protected String version = UUID.randomUUID().toString();
+ protected T paylod;
+ private Class<T> type;
+
+ public BaseConfigEvent(T paylod, Class<T> type){
+ this.paylod = Objects.requireNonNull(paylod);
+ this.type = Objects.requireNonNull(type);
+ }
+
+ @Override
+ public Class<T> getResourceType() {
+ return type;
+ }
+
+ @Override
+ public T getResource() {
+ return paylod;
+ }
+
+ @Override
+ public String getVersion() {
+ return version;
+ }
+
+ @Override
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + '{' +
+ "timestamp=" + timestamp +
+ ", version='" + version + '\'' +
+ ", paylod='" + paylod + '\'' +
+ '}';
+ }
+ }
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/spi/ConfigEventManagerSpi.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/spi/ConfigEventManagerSpi.java b/modules/events/src/main/java/org/apache/tamaya/events/spi/ConfigEventManagerSpi.java
index 7cb47a0..1ac1055 100644
--- a/modules/events/src/main/java/org/apache/tamaya/events/spi/ConfigEventManagerSpi.java
+++ b/modules/events/src/main/java/org/apache/tamaya/events/spi/ConfigEventManagerSpi.java
@@ -18,9 +18,11 @@
*/
package org.apache.tamaya.events.spi;
+import org.apache.tamaya.events.ConfigEvent;
import org.apache.tamaya.events.ConfigEventListener;
import java.util.Collection;
+import java.util.Set;
/**
* SPI interface to implement the {@link org.apache.tamaya.events.ConfigEventManager} singleton.
@@ -35,29 +37,88 @@ public interface ConfigEventManagerSpi {
*
* @param l the listener not null.
*/
- <T> void addListener(ConfigEventListener<T> l);
+ <T> void addListener(ConfigEventListener l);
+ /**
+ * Adds a listener for observing events of a given type.
+ *
+ * @param l the listener not null.
+ * @param eventType the type of concrete configuration event this listeners should be informed about. All other
+ * event types will never be delivered toe this listener instance.
+ */
+ <T extends ConfigEvent> void addListener(ConfigEventListener l, Class<T> eventType);
/**
* Removes a listener for observing events.
*
* @param l the listener not null.
*/
- <T> void removeListener(ConfigEventListener<T> l);
+ void removeListener(ConfigEventListener l);
+
+ /**
+ * Removes a listener for observing events of a certain type.
+ *
+ * @param l the listener not null.
+ * @param eventType the type of concrete configuration event this listeners should be informed about. All other
+ * event types will never be delivered toe this listener instance.
+ */
+ <T extends ConfigEvent> void removeListener(ConfigEventListener l, Class<T> eventType);
/**
- * Publishes an event to all interested listeners.
+ * Access all globally registered listeners.
*
- * @param event the event, not null.
- * @param eventType the event type.
+ * @return the listeners found, never null.
+ */
+ Collection<? extends ConfigEventListener> getListeners();
+
+ /**
+ * Access all listeners listening for a certain event type, including any global listeners.
+ * @param eventType the type of concrete configuration event this listeners should be informed about. All other
+ * event types will never be delivered toe this listener instance.
+ * @return the listeners found, never null.
*/
- <T> void fireEvent(T event, Class<T> eventType);
+ Collection<? extends ConfigEventListener> getListeners(Class<? extends ConfigEvent> eventType);
/**
- * Access all known listeners for a given targe type.
- * @param type the type.
- * @param <T> the listener type.
- * @return the items found, never null.
+ * Publishes an event to all interested listeners, hereby executing all registered listeners sequentually and
+ * synchronously.,
+ *
+ * @param event the event, not null.
*/
- <T> Collection<? extends ConfigEventListener<T>> getListeners(Class<T> type);
+ void fireEvent(ConfigEvent<?> event);
+
+ /**
+ * Publishes an event to all interested listeners, hereby publishing the change events asynchrously and in
+ * parallel (multithreaded).
+ *
+ * @param event the event, not null.
+ */
+ void fireEventAsynch(ConfigEvent<?> event);
+
+ /**
+ * Get the current check period to check for configuration changes.
+ *
+ * @return the check period in ms.
+ */
+ long getChangeMonitoringPeriod();
+
+ void setChangeMonitoringPeriod(long millis);
+
+ /**
+ * Check if the observer is running currently.
+ *
+ * @return true, if the change monitoring service is currently running.
+ */
+ boolean isChangeMonitorActive();
+
+ /**
+ * Start/Stop the change monitoring service, which will observe/reevaluate the current configuration regularly
+ * and triggers ConfigurationChange events is 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 remotedly. FOr handling corresponding {@link ConfigEventListener} have
+ * to be registered, e.g. listening on {@link org.apache.tamaya.events.ConfigurationChange} events.
+ */
+ void enableChangeMonitor(boolean enable);
+
+
}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/java/org/apache/tamaya/events/spi/ConfigObserverSpi.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/spi/ConfigObserverSpi.java b/modules/events/src/main/java/org/apache/tamaya/events/spi/ConfigObserverSpi.java
deleted file mode 100644
index 95eb6e7..0000000
--- a/modules/events/src/main/java/org/apache/tamaya/events/spi/ConfigObserverSpi.java
+++ /dev/null
@@ -1,71 +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.spi;
-
-import java.util.Collection;
-import java.util.Set;
-
-/**
- * SPI interface to implement the {@link org.apache.tamaya.events.ConfigurationObserver} singleton.
- * Implementations of this interface must be registered with the current {@link org.apache.tamaya.spi.ServiceContext},
- * by default this equals to registering it with {@link java.util.ServiceLoader}. Add {@link javax.annotation.Priority}
- * annotations for overriding (higher values overriden lower values).
- */
-public interface ConfigObserverSpi {
- /**
- * Add key expressions for generating ConfigurationChange events.
- *
- * @param keys the keys to be observed for changes.
- */
- <T> void addObservedKeys(Collection<String> keys);
-
- /**
- * Remove key expressions for generating ConfigurationChange events.
- *
- * @param keys the keys to be observed for changes.
- */
- <T> void removeObservedKeys(Collection<String> keys);
-
- /**
- * Get all registered key expressions for generating ConfigurationChange events.
- *
- * @return a set with the keys found, never null.
- */
- Set<String> getObservedKeys();
-
- /**
- * Get the current check period to check for configuration changes.
- *
- * @return the check period in ms.
- */
- long getCheckPeriod();
-
- /**
- * Check if the observer is running currently.
- *
- * @return true, if the observer is running.
- */
- boolean isRunning();
-
- /**
- * Start/Stop the observer container.
- */
- void enableObservation(boolean enable);
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
----------------------------------------------------------------------
diff --git a/modules/events/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener b/modules/events/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
index f675fd6..f9942c1 100644
--- a/modules/events/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
+++ b/modules/events/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
@@ -16,4 +16,4 @@
# specific language governing permissions and limitations
# under the License.
#
-org.apache.tamaya.events.internal.DefaultConfigurationContextChangeListener
\ No newline at end of file
+org.apache.tamaya.events.internal.DefaultConfigurationContextChangeListener
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/main/resources/META-INF/services/org.apache.tamaya.events.spi.ConfigObserverSpi
----------------------------------------------------------------------
diff --git a/modules/events/src/main/resources/META-INF/services/org.apache.tamaya.events.spi.ConfigObserverSpi b/modules/events/src/main/resources/META-INF/services/org.apache.tamaya.events.spi.ConfigObserverSpi
index de5ee6f..99670e3 100644
--- a/modules/events/src/main/resources/META-INF/services/org.apache.tamaya.events.spi.ConfigObserverSpi
+++ b/modules/events/src/main/resources/META-INF/services/org.apache.tamaya.events.spi.ConfigObserverSpi
@@ -16,4 +16,4 @@
# specific language governing permissions and limitations
# under the License.
#
-org.apache.tamaya.events.internal.DefaultConfigObserverSpi
\ No newline at end of file
+org.apache.tamaya.events.internal.DefaultConfigChangeObserver
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b5805ed/modules/events/src/test/java/org/apache/tamaya/events/ChangeableGlobalPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/events/src/test/java/org/apache/tamaya/events/ChangeableGlobalPropertySource.java b/modules/events/src/test/java/org/apache/tamaya/events/ChangeableGlobalPropertySource.java
new file mode 100644
index 0000000..c93b2ca
--- /dev/null
+++ b/modules/events/src/test/java/org/apache/tamaya/events/ChangeableGlobalPropertySource.java
@@ -0,0 +1,62 @@
+/*
+ * 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.core.propertysource.BasePropertySource;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * PropertySource implementation that accesses properties that are statically stored.
+ */
+public class ChangeableGlobalPropertySource extends BasePropertySource{
+
+ private static Map<String,String> STORED_ENTRIES = new ConcurrentHashMap<>();
+
+ @Override
+ public String getName() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return null;
+ }
+
+ /**
+ * Put a value (globally) into this property source.
+ * @param key the key, not null
+ * @param value the value, not null
+ * @return the entry replaced, or null.
+ */
+ public static String put(String key, String value){
+ return STORED_ENTRIES.put(key,value);
+ }
+
+ /**
+ * Put all the properties, overriding any existing ones with the same key.
+ * @param properties the properties, not null.
+ */
+ public static void putAll(Map<String,String> properties){
+ STORED_ENTRIES.putAll(properties);
+ }
+
+}