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 2017/11/15 18:14:09 UTC

incubator-tamaya-extensions git commit: TAMAYA-300 Added tests to improver coverage.

Repository: incubator-tamaya-extensions
Updated Branches:
  refs/heads/master 1aa999966 -> 45d8afdea


TAMAYA-300 Added tests to improver coverage.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/commit/45d8afde
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/tree/45d8afde
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/diff/45d8afde

Branch: refs/heads/master
Commit: 45d8afdea32f6d1fc4d955e484db44d56651ce9d
Parents: 1aa9999
Author: Anatole Tresch <an...@apache.org>
Authored: Wed Nov 15 19:14:02 2017 +0100
Committer: Anatole Tresch <an...@apache.org>
Committed: Wed Nov 15 19:14:02 2017 +0100

----------------------------------------------------------------------
 modules/injection/injection-api/pom.xml         |   6 +
 .../tamaya/inject/spi/BaseDynamicValue.java     | 166 +++++++++++++++++++
 .../tamaya/inject/spi/BaseDynamicValueTest.java | 101 +++++++++++
 3 files changed, 273 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/45d8afde/modules/injection/injection-api/pom.xml
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/pom.xml b/modules/injection/injection-api/pom.xml
index 57972d8..82c89c3 100644
--- a/modules/injection/injection-api/pom.xml
+++ b/modules/injection/injection-api/pom.xml
@@ -45,6 +45,12 @@ under the License.
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-core</artifactId>
+            <version>${tamaya-apicore.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.geronimo.specs</groupId>
             <artifactId>geronimo-atinject_1.0_spec</artifactId>
             <version>${geronimo-atinject-1.0-spec.version}</version>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/45d8afde/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/BaseDynamicValue.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/BaseDynamicValue.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/BaseDynamicValue.java
index 1d0e75e..59e7683 100644
--- a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/BaseDynamicValue.java
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/BaseDynamicValue.java
@@ -18,10 +18,23 @@
  */
 package org.apache.tamaya.inject.spi;
 
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.TypeLiteral;
 import org.apache.tamaya.inject.api.DynamicValue;
+import org.apache.tamaya.inject.api.UpdatePolicy;
 
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import java.io.Serializable;
+import java.lang.reflect.Member;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
 import java.util.function.Supplier;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * Basic abstract implementation skeleton for a {@link DynamicValue}. This can be used to support values that may
@@ -44,6 +57,159 @@ public abstract class BaseDynamicValue<T> implements DynamicValue<T>, Serializab
 
     private static final long serialVersionUID = 1L;
 
+    private static final Logger LOG = Logger.getLogger(DynamicValue.class.getName());
+
+    private UpdatePolicy updatePolicy = UpdatePolicy.NEVER;
+    private TypeLiteral<T> targetType;
+    private T currentValue;
+    private T newValue;
+    private List<String> keys = new ArrayList<>();
+    private List<PropertyChangeListener> listeners = Collections.synchronizedList(new ArrayList<>());
+
+
+    public BaseDynamicValue(TypeLiteral targetType, List<String> keys){
+        if(keys == null || keys.isEmpty()){
+            throw new ConfigException("At least one key is required.");
+        }
+        this.targetType = Objects.requireNonNull(targetType);
+        this.keys.addAll(keys);
+        this.currentValue = evaluateValue();
+    }
+
+    /**
+     * Get the configuration to evaluate.
+     * @return the configuration, never null.
+     */
+    protected abstract Configuration getConfiguration();
+
+    /**
+     * Get the owner of this dynamic value instance.
+     * @return the owner, never null.
+     */
+    protected abstract Object getOwner();
+
+    /**
+     * Get the corresponding property name.
+     * @return
+     */
+    protected abstract String getPropertyName();
+
+    /**
+     * Get the targeted keys, in evaluation order.
+     * @return the keys evaluated.
+     */
+    public List<String> getKeys(){
+        return Collections.unmodifiableList(keys);
+    }
+
+    /**
+     * Get the target type.
+     * @return the target type, not null.
+     */
+    public TypeLiteral<T> getTargetType(){
+        return targetType;
+    }
+
+    @Override
+    public void commit() {
+        if(!Objects.equals(newValue, currentValue)) {
+            T oldValue = this.currentValue;
+            currentValue = newValue;
+            publishChangeEvent(this.currentValue, newValue);
+        }
+    }
+
+    @Override
+    public UpdatePolicy getUpdatePolicy() {
+        return updatePolicy;
+    }
+
+    @Override
+    public void addListener(PropertyChangeListener l) {
+        synchronized(listeners){
+            if(!listeners.contains(l)){
+                listeners.add(l);
+            }
+        }
+    }
+
+    @Override
+    public void removeListener(PropertyChangeListener l) {
+        synchronized(listeners){
+            listeners.remove(l);
+        }
+    }
+
+    @Override
+    public T get() {
+        return currentValue;
+    }
+
+    @Override
+    public boolean updateValue() {
+        Configuration config = getConfiguration();
+        T val = evaluateValue();
+        if(!Objects.equals(val, currentValue)){
+            switch (updatePolicy){
+                case EXPLICIT:
+                    newValue = val;
+                    break;
+                case IMMEDIATE:
+                    this.currentValue = val;
+                    publishChangeEvent(this.currentValue, val);
+                    break;
+                case LOG_ONLY:
+                    LOG.info("New config value for keys " + keys + " detected, but not yet applied.");
+                    break;
+                case NEVER:
+                    LOG.finest("New config value for keys " + keys + " detected, but ignored.");
+                    break;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Publishes a change event to all listeners.
+     * @param newValue the new value
+     * @param oldValue the new old value
+     */
+    protected void publishChangeEvent(T oldValue, T newValue) {
+        PropertyChangeEvent evt = new PropertyChangeEvent(getOwner(), getPropertyName(),oldValue, newValue);
+        synchronized (listeners){
+            listeners.parallelStream().forEach(l -> {
+                try{
+                    l.propertyChange(evt);
+                }catch(Exception e){
+                    LOG.log(Level.SEVERE, "Error in config change listener: " + l, e);
+                }
+            });
+        }
+    }
+
+    @Override
+    public T evaluateValue() {
+        Configuration config = getConfiguration();
+        for(String key:getKeys()){
+            T val = config.getOrDefault(key, targetType, null);
+           if(val!=null){
+               return val;
+           }
+        }
+        return null;
+    }
+
+    @Override
+    public void setUpdatePolicy(UpdatePolicy updatePolicy) {
+        this.updatePolicy = Objects.requireNonNull(updatePolicy);
+    }
+
+    @Override
+    public T getNewValue() {
+        return newValue;
+    }
+
     /**
      * Performs a commit, if necessary, and returns the current value.
      *

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/45d8afde/modules/injection/injection-api/src/test/java/org/apache/tamaya/inject/spi/BaseDynamicValueTest.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/test/java/org/apache/tamaya/inject/spi/BaseDynamicValueTest.java b/modules/injection/injection-api/src/test/java/org/apache/tamaya/inject/spi/BaseDynamicValueTest.java
new file mode 100644
index 0000000..3f8720e
--- /dev/null
+++ b/modules/injection/injection-api/src/test/java/org/apache/tamaya/inject/spi/BaseDynamicValueTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.inject.spi;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.inject.api.UpdatePolicy;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.*;
+
+public class BaseDynamicValueTest {
+
+    @Test
+    public void create(){
+        new MyDynamicValue("a", "b");
+    }
+
+    @Test(expected = ConfigException.class)
+    public void create_nokeys(){
+        new MyDynamicValue();
+    }
+
+    @Test
+    public void commitAndGet() throws Exception {
+        System.setProperty("commitAndGet", "yes");
+        MyDynamicValue dv = new MyDynamicValue("commitAndGet");
+        System.setProperty("commitAndGet", "no");
+        dv.setUpdatePolicy(UpdatePolicy.EXPLICIT);
+        assertTrue(dv.updateValue());
+        assertEquals(dv.commitAndGet(), "no");
+        dv.setUpdatePolicy(UpdatePolicy.IMMEDIATE);
+        System.setProperty("commitAndGet", "yes2");
+        assertTrue(dv.updateValue());
+        assertEquals(dv.get(), "yes2");
+    }
+
+    @Test
+    public void isPresent() throws Exception {
+        assertFalse(new MyDynamicValue("a", "b").isPresent());
+        assertTrue(new MyDynamicValue("java.version").isPresent());
+    }
+
+    @Test
+    public void orElse() throws Exception {
+        assertEquals(new MyDynamicValue("a", "b").orElse("foo"), "foo");
+    }
+
+    @Test
+    public void orElseGet() throws Exception {
+        assertEquals(new MyDynamicValue("a", "b").orElseGet(() -> "foo"), "foo");
+    }
+
+    @Test(expected = NoSuchFieldException.class)
+    public void orElseThrow() throws Throwable {
+        new MyDynamicValue("foo").orElseThrow(() -> new NoSuchFieldException("Test"));
+    }
+
+    private static final class MyDynamicValue extends BaseDynamicValue{
+
+        public MyDynamicValue(String... keys){
+            super(TypeLiteral.of(String.class), Arrays.asList(keys));
+        }
+
+        @Override
+        protected Configuration getConfiguration() {
+            return ConfigurationProvider.getConfiguration();
+        }
+
+        @Override
+        protected Object getOwner() {
+            return this;
+        }
+
+        @Override
+        protected String getPropertyName() {
+            return "this";
+        }
+    }
+
+}
\ No newline at end of file