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 2014/12/21 01:36:34 UTC
incubator-tamaya git commit: TAMAYA-34: - Aligned callbacks and
method config injections with fallback configuration features. - Added TODOs
for possible caching hook points for template methods. - Removed unused
listener predicates. - Added central Weak
Repository: incubator-tamaya
Updated Branches:
refs/heads/master 238c07f16 -> 26e7f2e95
TAMAYA-34:
- Aligned callbacks and method config injections with fallback configuration features.
- Added TODOs for possible caching hook points for template methods.
- Removed unused listener predicates.
- Added central WeakHashmap that maps instances to its listeners weakly.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/26e7f2e9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/26e7f2e9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/26e7f2e9
Branch: refs/heads/master
Commit: 26e7f2e959dd072c992b9d64d8168a7b325cc04c
Parents: 238c07f
Author: anatole <an...@apache.org>
Authored: Sun Dec 21 01:36:21 2014 +0100
Committer: anatole <an...@apache.org>
Committed: Sun Dec 21 01:36:21 2014 +0100
----------------------------------------------------------------------
.../java/org/apache/tamaya/Configuration.java | 10 +-
.../org/apache/tamaya/ConfigurationManager.java | 10 +-
.../spi/ConfigurationManagerSingletonSpi.java | 6 +-
.../tamaya/TestConfigServiceSingletonSpi.java | 4 +-
...DefaultConfigurationManagerSingletonSpi.java | 31 +----
.../tamaya/core/internal/config/Store.java | 98 ----------------
.../config/WeakConfigListenerManager.java | 82 -------------
.../inject/ConfigChangeCallbackMethod.java | 17 ++-
.../inject/ConfigTemplateInvocationHandler.java | 11 ++
.../core/internal/inject/ConfiguredMethod.java | 53 ++++++---
.../core/internal/inject/ConfiguredType.java | 45 +++----
.../inject/WeakConfigListenerManager.java | 116 +++++++++++++++++++
.../tamaya/core/config/MutableConfigTest.java | 8 +-
13 files changed, 224 insertions(+), 267 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/api/src/main/java/org/apache/tamaya/Configuration.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/Configuration.java b/api/src/main/java/org/apache/tamaya/Configuration.java
index 4248d3c..775078b 100644
--- a/api/src/main/java/org/apache/tamaya/Configuration.java
+++ b/api/src/main/java/org/apache/tamaya/Configuration.java
@@ -340,20 +340,18 @@ public interface Configuration extends PropertySource {
/**
* Add a ConfigChangeListener to the given PropertySource instance.
- * @param predicate the event filtering predicate
* @param l the listener, not null.
*/
- public static void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l){
- ConfigurationManager.addChangeListener(predicate, l);
+ public static void addChangeListener(Consumer<ConfigChangeSet> l){
+ ConfigurationManager.addChangeListener(l);
}
/**
* Removes a ConfigChangeListener from the given PropertySource instance.
- * @param predicate the event filtering predicate
* @param l the listener, not null.
*/
- public static void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l){
- ConfigurationManager.removeChangeListener(predicate, l);
+ public static void removeChangeListener(Consumer<ConfigChangeSet> l){
+ ConfigurationManager.removeChangeListener(l);
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/ConfigurationManager.java b/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
index 6c3c009..c753b22 100644
--- a/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
+++ b/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
@@ -112,20 +112,18 @@ final class ConfigurationManager{
/**
* Add a ConfigChangeSet listener to the given configuration instance.
- * @param predicate the event filtering predicate, or null, for selecting all changes.
* @param l the listener, not null.
*/
- public static void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
- ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).addChangeListener(predicate, Objects.requireNonNull(l));
+ public static void addChangeListener(Consumer<ConfigChangeSet> l) {
+ ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).addChangeListener(Objects.requireNonNull(l));
}
/**
* Removes a ConfigChangeSet listener from the given configuration instance.
- * @param predicate the event filtering predicate, or null, for selecting all changes.
* @param l the listener, not null.
*/
- public static void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
- ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).removeChangeListener(predicate, Objects.requireNonNull(l));
+ public static void removeChangeListener(Consumer<ConfigChangeSet> l) {
+ ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).removeChangeListener(Objects.requireNonNull(l));
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java b/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
index 2bbc180..6be15a8 100644
--- a/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
+++ b/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
@@ -95,17 +95,15 @@ public interface ConfigurationManagerSingletonSpi{
/**
* Add a ConfigChangeSet listener to the given configuration instance.
- * @param predicate the event filtering predicate, or null, for selecting all changes.
* @@param l the listener, not null.
*/
- void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l);
+ void addChangeListener(Consumer<ConfigChangeSet> l);
/**
* Removes a ConfigChangeSet listener from the given configuration instance.
- * @param predicate the event filtering predicate, or null, for selecting all changes.
* @param l the listener, not null.
*/
- void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l);
+ void removeChangeListener(Consumer<ConfigChangeSet> l);
/**
* Method to publish changes on a {@link org.apache.tamaya.Configuration} to all interested parties.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java b/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
index 2d0694f..89f8078 100644
--- a/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
+++ b/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
@@ -89,12 +89,12 @@ public class TestConfigServiceSingletonSpi implements ConfigurationManagerSingle
}
@Override
- public void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
+ public void addChangeListener(Consumer<ConfigChangeSet> l) {
// ignore
}
@Override
- public void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
+ public void removeChangeListener(Consumer<ConfigChangeSet> l) {
// ignore
}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java b/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
index cb096e8..2b0a471 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
@@ -35,6 +35,7 @@ import org.apache.tamaya.PropertySource;
import org.apache.tamaya.core.internal.el.DefaultExpressionEvaluator;
import org.apache.tamaya.core.internal.inject.ConfigTemplateInvocationHandler;
import org.apache.tamaya.core.internal.inject.ConfigurationInjector;
+import org.apache.tamaya.core.internal.inject.WeakConfigListenerManager;
import org.apache.tamaya.core.spi.ConfigurationProviderSpi;
import org.apache.tamaya.core.spi.ExpressionEvaluator;
import org.apache.tamaya.spi.ConfigurationManagerSingletonSpi;
@@ -51,8 +52,6 @@ public class DefaultConfigurationManagerSingletonSpi implements ConfigurationMan
private Map<String, ConfigurationProviderSpi> configProviders = new ConcurrentHashMap<>();
- private Map<Consumer<ConfigChangeSet>, List<Predicate<PropertySource>>> listenerMap = new ConcurrentHashMap<>();
-
private ExpressionEvaluator expressionEvaluator = loadEvaluator();
private ExpressionEvaluator loadEvaluator() {
@@ -94,36 +93,18 @@ public class DefaultConfigurationManagerSingletonSpi implements ConfigurationMan
}
@Override
- public void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
- List<Predicate<PropertySource>> predicates = listenerMap.computeIfAbsent(l,
- cs -> Collections.synchronizedList(new ArrayList<>()));
- if (predicate == null) {
- predicates.add(p -> true); // select all events!
- } else {
- predicates.add(predicate);
- }
+ public void addChangeListener(Consumer<ConfigChangeSet> l) {
+ WeakConfigListenerManager.of().registerConsumer(l,l);
}
@Override
- public void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
- List<Predicate<PropertySource>> predicates = listenerMap.get(l);
- if (predicate == null) {
- listenerMap.remove(l); // select all events!
- } else {
- predicates.add(predicate);
- }
+ public void removeChangeListener(Consumer<ConfigChangeSet> l) {
+ WeakConfigListenerManager.of().unregisterConsumer(l);
}
@Override
public void publishChange(ConfigChangeSet configChangeSet) {
- listenerMap.entrySet().forEach(
- (en) -> {
- if (en.getValue().stream()
- .filter(v -> v.test(configChangeSet.getPropertySource())).findAny().isPresent()) {
- en.getKey().accept(configChangeSet);
- }
- }
- );
+ WeakConfigListenerManager.of().publishChangeEvent(configChangeSet);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/config/Store.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/config/Store.java b/core/src/main/java/org/apache/tamaya/core/internal/config/Store.java
deleted file mode 100644
index 815e0f3..0000000
--- a/core/src/main/java/org/apache/tamaya/core/internal/config/Store.java
+++ /dev/null
@@ -1,98 +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.core.internal.config;
-
-import java.lang.ref.WeakReference;
-import java.util.*;
-
-/**
- * This store encapsulates an list current WeakReferences to items.
- * It cleans up the list fromMap null references, when an item is removed, or an Iterator is created.
- * Created by Anatole on 10.04.2014.
- */
-public class Store<T>implements Iterable<T> {
-
- private List<WeakReference<T>> weakItems = new ArrayList<>();
-
- private List<T> items = new ArrayList<>();
-
- private final Object LOCK = new Object();
-
- public void add(T item){
- Objects.requireNonNull(item);
- this.items.add(item);
- }
-
- public void addWeak(T item){
- Objects.requireNonNull(item);
- this.weakItems.add(new WeakReference<>(item));
- }
-
- public void remove(T item){
- Objects.requireNonNull(item);
- synchronized(LOCK){
- for(Iterator<WeakReference<T>> iter = weakItems.iterator(); iter.hasNext();iter.next()){
- WeakReference<T> wr = iter.next();
- T t = wr.get();
- if(t==null || t.equals(item)){
- iter.remove();
- }
- }
- for(Iterator<T> iter = items.iterator(); iter.hasNext();iter.next()){
- T t = iter.next();
- if(t==null || t.equals(item)){
- iter.remove();
- }
- }
- }
- }
-
- public List<T> toList(){
- List<T> newList = new ArrayList<>();
- synchronized(LOCK){
- Iterator<T> iter = items.iterator();
- while(iter.hasNext()){
- T t = iter.next();
- newList.add(t);
- }
- for (WeakReference<T> wr : weakItems) {
- T t = wr.get();
- if (t == null) {
- iter.remove();
- } else {
- newList.add(t);
- }
- }
- }
- return newList;
- }
-
- @Override
- public Iterator<T> iterator(){
- return toList().iterator();
- }
-
- @Override
- public String toString(){
- return "Store{" +
- "items=" + items +
- ", weakItems=" + weakItems +
- '}';
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/config/WeakConfigListenerManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/config/WeakConfigListenerManager.java b/core/src/main/java/org/apache/tamaya/core/internal/config/WeakConfigListenerManager.java
deleted file mode 100644
index 7cc6a15..0000000
--- a/core/src/main/java/org/apache/tamaya/core/internal/config/WeakConfigListenerManager.java
+++ /dev/null
@@ -1,82 +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.core.internal.config;
-
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Simple listener container that only holds weak references on the listeners.
- */
-public class WeakConfigListenerManager{
-
- private static final Logger LOG = Logger.getLogger(WeakConfigListenerManager.class.getName());
- private Map<String,Store<PropertyChangeListener>> changeListeners = new ConcurrentHashMap<>();
-
-
- private void publishPropertyChangeEventToGlobalListeners(PropertyChangeEvent evt){
- Store<PropertyChangeListener> items = changeListeners.get("_globalConfigChangeListeners");
- if(items != null){
- synchronized(items){
- for(PropertyChangeListener l : items){
- try{
- l.propertyChange(evt);
- }
- catch(Exception e){
- LOG.log(Level.SEVERE, e, () -> "Error thrown by PropertyChangeListener: " + l);
- }
- }
-
- }
- }
- }
-
-
- public void publishPropertyChangeEvent(PropertyChangeEvent evt, String configId){
- Store<PropertyChangeListener> items = changeListeners.get(configId);
- if(items != null){
- synchronized(items){
- for(PropertyChangeListener l : items){
- try{
- l.propertyChange(evt);
- }
- catch(Exception e){
- LOG.log(Level.SEVERE, e, () -> "Error thrown by ConfigChangeListener: " + l);
- }
- }
-
- }
- }
- publishPropertyChangeEventToGlobalListeners(evt);
- }
-
-
- @Override
- public String toString(){
- return "WeakConfigListenerManager{" +
- "changeListeners=" + changeListeners +
- '}';
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigChangeCallbackMethod.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigChangeCallbackMethod.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigChangeCallbackMethod.java
index 8bf951a..882d68b 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigChangeCallbackMethod.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigChangeCallbackMethod.java
@@ -18,10 +18,14 @@
*/
package org.apache.tamaya.core.internal.inject;
+import org.apache.tamaya.ConfigChangeSet;
+import org.apache.tamaya.Configuration;
+
import java.beans.PropertyChangeEvent;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.Optional;
+import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -43,7 +47,18 @@ public final class ConfigChangeCallbackMethod {
m.getParameterTypes()[0].equals(PropertyChangeEvent.class)).get();
}
- public void call(Object instance, PropertyChangeEvent configChangeEvent) {
+ public Consumer<ConfigChangeSet> createConsumer(Object instance, Configuration... configurations){
+ return event -> {
+ for(Configuration cfg:configurations){
+ if(event.getPropertySource().getMetaInfo().getName().equals(cfg.getMetaInfo().getName())){
+ return;
+ }
+ }
+ call(instance, event);
+ };
+ }
+
+ public void call(Object instance, ConfigChangeSet configChangeEvent) {
try {
callbackMethod.setAccessible(true);
callbackMethod.invoke(instance, configChangeEvent);
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigTemplateInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigTemplateInvocationHandler.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigTemplateInvocationHandler.java
index 70070c5..ff2c309 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigTemplateInvocationHandler.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigTemplateInvocationHandler.java
@@ -30,6 +30,17 @@ import java.util.Objects;
* Invocation handler that handles request against a configuration template.
*/
public final class ConfigTemplateInvocationHandler implements InvocationHandler {
+
+ /*
+ TODO
+ the given method (in case of a template) can use different caching strategies:
+ 1) no caching (always evaluate the values completely) - slow.
+ 2) instance caching (a cache per instance).
+ 3) classloader caching...
+ 4) global shared cache.
+ */
+
+
/**
* Any overriding configurations.
*/
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
index 8c1e0af..c3dda19 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
@@ -22,20 +22,20 @@ import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Objects;
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
import org.apache.tamaya.annotation.ConfiguredProperties;
import org.apache.tamaya.annotation.ConfiguredProperty;
import org.apache.tamaya.annotation.DefaultAreas;
import org.apache.tamaya.core.internal.Utils;
/**
- * Small class that contains and manages all information anc access to a configured field and a concrete instance current
- * it (referenced by a weak reference). It also implements all aspects current keys filtering, conversiong any applying the
+ * Small class that contains and manages all information and access to a configured field and a concrete instance current
+ * it (referenced by a weak reference). It also implements all aspects current keys filtering, conversions any applying the
* final keys by reflection.
- * Created by Anatole on 01.10.2014.
*/
public class ConfiguredMethod {
-
/**
* The configured field instance.
*/
@@ -51,7 +51,43 @@ public class ConfiguredMethod {
}
+ /**
+ * Evaluate the initial keys fromMap the configuration and applyChanges it to the field.
+ *
+ * @param target the target instance.
+ * @param configurations Configuration instances that replace configuration served by services. This allows
+ * more easily testing and adaption.
+ * @throws ConfigException if evaluation or conversion failed.
+ */
+ public void applyInitialValue(Object target, Configuration... configurations) throws ConfigException {
+ String configValue = InjectionUtils.getConfigValue(this.annotatedMethod, configurations);
+ applyValue(target, configValue, false, configurations);
+ }
+ /**
+ * This method reapplies a changed configuration keys to the field.
+ *
+ * @param target the target instance, not null.
+ * @param configValue the new keys to be applied, null will trigger the evaluation current the configured default keys.
+ * @param resolve set to true, if expression resolution should be applied on the keys passed.
+ * @throws org.apache.tamaya.ConfigException if the configuration required could not be resolved or converted.
+ */
+ public void applyValue(Object target, String configValue, boolean resolve, Configuration... configurations) throws ConfigException {
+ Objects.requireNonNull(target);
+ try {
+ if (resolve && configValue != null) {
+ // net step perform exression resolution, if any
+ configValue = Configuration.evaluateValue(configValue, configurations);
+ }
+ // Check for adapter/filter
+ Object value = InjectionUtils.adaptValue(this.annotatedMethod, this.annotatedMethod.getParameterTypes()[0], configValue);
+ annotatedMethod.setAccessible(true);
+ annotatedMethod.invoke(target, value);
+ } catch (Exception e) {
+ throw new ConfigException("Failed to annotation configured method: " + this.annotatedMethod.getDeclaringClass()
+ .getName() + '.' + annotatedMethod.getName(), e);
+ }
+ }
@@ -76,14 +112,5 @@ public class ConfiguredMethod {
}
-// /**
-// * This method reapplies a changed configuration keys to the field.
-// *
-// * @throws org.apache.tamaya.ConfigException if the configuration required could not be resolved or converted.
-// */
-// public Object getValue(Object[] args, Configuration... configurations) throws ConfigException {
-// // TODO do something with additional args?
-// return InjectionUtils.adaptValue(this.annotatedMethod, this.annotatedMethod.getReturnType(), configValue);
-// }
}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
index eef9923..491041d 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
@@ -21,11 +21,7 @@ package org.apache.tamaya.core.internal.inject;
import java.beans.PropertyChangeEvent;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
import org.apache.tamaya.ConfigException;
import org.apache.tamaya.Configuration;
@@ -34,6 +30,7 @@ import org.apache.tamaya.annotation.ConfiguredProperties;
import org.apache.tamaya.annotation.ConfiguredProperty;
import org.apache.tamaya.annotation.DefaultAreas;
import org.apache.tamaya.annotation.ObservesConfigChange;
+import org.apache.tamaya.core.internal.Utils;
/**
* Structure that contains and manages configuration related things for a configured type registered.
@@ -44,7 +41,7 @@ public class ConfiguredType {
/** A list with all annotated instance variables. */
private List<ConfiguredField> configuredFields = new ArrayList<>();
/** A list with all annotated methods (templates). */
- private Map<Method, ConfiguredMethod> configuredMethods = new HashMap<>();
+ private List<ConfiguredMethod> configuredMethods = new ArrayList<>();
/** A list with all callback methods listening to config changes. */
private List<ConfigChangeCallbackMethod> callbackMethods = new ArrayList<>();
/** The basic type. */
@@ -82,26 +79,15 @@ public class ConfiguredType {
m.getDeclaringClass().getName() + '.' + m.getName(), e);
}
} else {
- ConfiguredProperties propertiesAnnot = m.getAnnotation(ConfiguredProperties.class);
- if (propertiesAnnot != null) {
+ Collection<ConfiguredProperty> propertiesAnnots = Utils.getAnnotations(m, ConfiguredProperty.class, ConfiguredProperties.class);
+ if (!propertiesAnnots.isEmpty()) {
try {
ConfiguredMethod configuredMethod = new ConfiguredMethod(m);
- configuredMethods.put(m, configuredMethod);
+ configuredMethods.add(configuredMethod);
} catch (Exception e) {
throw new ConfigException("Failed to initialized configured method: " +
m.getDeclaringClass().getName() + '.' + m.getName(), e);
}
- } else {
- ConfiguredProperty propertyAnnot = m.getAnnotation(ConfiguredProperty.class);
- if (propertyAnnot != null) {
- try {
- ConfiguredMethod configuredMethod = new ConfiguredMethod(m);
- configuredMethods.put(m, configuredMethod);
- } catch (Exception e) {
- throw new ConfigException("Failed to initialized configured method: " +
- m.getDeclaringClass().getName() + '.' + m.getName(), e);
- }
- }
}
}
}
@@ -142,18 +128,20 @@ public class ConfiguredType {
*/
public void configure(Object instance, Configuration... configurations) {
for (ConfiguredField field : configuredFields) {
- field.applyInitialValue(instance);
+ field.applyInitialValue(instance, configurations);
+ // TODO, if reinjection on changes should be done, corresponding callbacks could be registered here
}
- }
-
- public void triggerConfigUpdate(PropertyChangeEvent evt, Object instance) {
- // TODO do check for right config ;)
- configuredFields.stream().filter(field -> field.matchesKey(getName(evt.getSource()), evt.getPropertyName())).forEach(field -> field.applyValue(instance, (String) evt.getNewValue(), false));
- for (ConfigChangeCallbackMethod callBack : this.callbackMethods) {
- callBack.call(instance, evt);
+ for (ConfiguredMethod method : configuredMethods) {
+ method.applyInitialValue(instance, configurations);
+ // TODO, if method should be recalled on changes, corresponding callbacks could be registered here
+ }
+ // Register callbacks for this intance (weakly)
+ for(ConfigChangeCallbackMethod callback: callbackMethods){
+ WeakConfigListenerManager.of().registerConsumer(instance, callback.createConsumer(instance, configurations));
}
}
+
private String getName(Object source){
if(source instanceof PropertySource){
PropertySource ps = (PropertySource)source;
@@ -162,6 +150,7 @@ public class ConfiguredType {
return "N/A";
}
+
public boolean isConfiguredBy(Configuration configuration) {
// TODO implement this
return true;
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/inject/WeakConfigListenerManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/WeakConfigListenerManager.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/WeakConfigListenerManager.java
new file mode 100644
index 0000000..6f19bbe
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/WeakConfigListenerManager.java
@@ -0,0 +1,116 @@
+/*
+ * 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.core.internal.inject;
+
+import org.apache.tamaya.ConfigChangeSet;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.StampedLock;
+import java.util.function.Consumer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Simple listener container that only holds weak references on the listeners.
+ */
+public final class WeakConfigListenerManager{
+
+ private static final WeakConfigListenerManager INSTANCE = new WeakConfigListenerManager();
+
+ private static final Logger LOG = Logger.getLogger(WeakConfigListenerManager.class.getName());
+ private StampedLock lock = new StampedLock();
+ private Map<Object,Consumer<ConfigChangeSet>> listenerReferences = new WeakHashMap<>();
+
+ /** Private singleton constructor. */
+ private WeakConfigListenerManager(){}
+
+ public static WeakConfigListenerManager of(){
+ return INSTANCE;
+ }
+
+ /**
+ * Registers the given consumer for the instance. If a consumer already exists for this instance the given
+ * consumer is appended.
+ * @param instance the instance, not null.
+ * @param listener the consumer.
+ */
+ public void registerConsumer(Object instance, Consumer<ConfigChangeSet> listener){
+ Lock writeLock = lock.asWriteLock();
+ try {
+ writeLock.lock();
+ Consumer<ConfigChangeSet> l = listenerReferences.get(instance);
+ if (l == null) {
+ listenerReferences.put(instance, listener);
+ } else {
+ listenerReferences.put(instance, l.andThen(listener));
+ }
+ }
+ finally{
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Unregisters all consumers for the given instance.
+ * @param instance the instance, not null.
+ */
+ public void unregisterConsumer(Object instance) {
+ Lock writeLock = lock.asWriteLock();
+ try {
+ writeLock.lock();
+ listenerReferences.remove(instance);
+ }
+ finally{
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Publishes a change event to all consumers registered.
+ * @param change the change event, not null.
+ */
+ public void publishChangeEvent(ConfigChangeSet change){
+ Lock readLock = lock.asReadLock();
+ try{
+ readLock.lock();
+ listenerReferences.values().parallelStream().forEach(l -> {
+ try{
+ l.accept(change);
+ }
+ catch(Exception e){
+ LOG.log(Level.SEVERE, "ConfigChangeListener failed: " + l.getClass().getName(), e);
+ }
+ });
+ }
+ finally{
+ readLock.unlock();
+ }
+ }
+
+
+ @Override
+ public String toString(){
+ return "WeakConfigListenerManager{" +
+ "listenerReferences=" + listenerReferences +
+ '}';
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/test/java/org/apache/tamaya/core/config/MutableConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/tamaya/core/config/MutableConfigTest.java b/core/src/test/java/org/apache/tamaya/core/config/MutableConfigTest.java
index 0f81a10..215da35 100644
--- a/core/src/test/java/org/apache/tamaya/core/config/MutableConfigTest.java
+++ b/core/src/test/java/org/apache/tamaya/core/config/MutableConfigTest.java
@@ -35,12 +35,16 @@ import static org.junit.Assert.assertFalse;
public class MutableConfigTest {
@Test
- public void accessMutableConfig(){
+ public void accessMutableConfig() {
Configuration config = Configuration.current("mutableTestConfig");
ConfigChangeSet changeSet = ConfigChangeSetBuilder.of(config).put("testCase", "accessMutableConfig")
.put("execTime", System.currentTimeMillis()).put("execution", "once").build();
List<PropertyChangeEvent> changes = new ArrayList<>();
- Configuration.addChangeListener(cfg -> cfg == config, change -> changes.addAll(change.getEvents()));
+ Configuration.addChangeListener(change -> {
+ if (change.getPropertySource() == config) {
+ changes.addAll(change.getEvents());
+ }
+ });
config.applyChanges(changeSet);
assertFalse(changes.isEmpty());
System.out.println(changes);