You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2016/10/30 22:06:23 UTC
[01/15] incubator-tamaya-extensions git commit: Helper commit...
Repository: incubator-tamaya-extensions
Updated Branches:
refs/heads/master 329dd0212 -> 3aca91120
Helper commit...
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/c757d324
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/tree/c757d324
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/diff/c757d324
Branch: refs/heads/master
Commit: c757d324fa2e62da8f810ca2738b00a7654d0ce6
Parents: 329dd02
Author: Oliver B. Fischer <pl...@apache.org>
Authored: Sun Oct 23 22:49:40 2016 +0200
Committer: Oliver B. Fischer <pl...@apache.org>
Committed: Sun Oct 23 22:51:14 2016 +0200
----------------------------------------------------------------------
bla | 0
1 file changed, 0 insertions(+), 0 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/c757d324/bla
----------------------------------------------------------------------
diff --git a/bla b/bla
new file mode 100644
index 0000000..e69de29
[03/15] incubator-tamaya-extensions git commit: TAMAYA-189: Moved
format and injection modules into separate subtrees.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/Utils.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/Utils.java b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/Utils.java
new file mode 100644
index 0000000..2c08467
--- /dev/null
+++ b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/Utils.java
@@ -0,0 +1,128 @@
+/*
+ * 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.internal;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Utility class simplifying some implementation aspects.
+ * Created by Anatole on 11.11.2014.
+ */
+@SuppressWarnings("unchecked")
+public final class Utils {
+
+ private static final Logger LOG = Logger.getLogger(Utils.class.getName());
+
+ private Utils() {
+ }
+
+ /**
+ * Utility method to read out repeatable annotations.
+ *
+ * @param annotated the annotated instance.
+ * @param repeatableAnnotation the repeatable annotation type
+ * @param annotationContainer the container annotation type
+ * @param <T> the repeatable annotation type
+ * @param <R> the repeatable container annotation type
+ * @return a list with the annotations found (could be empty, but never null).
+ */
+ public static <T extends Annotation, R extends Annotation> Collection<T>
+ getAnnotations(AnnotatedElement annotated,
+ Class<T> repeatableAnnotation,
+ Class<R> annotationContainer) {
+ List<T> result = new ArrayList<>();
+ R containerAnnot = annotated.getAnnotation(annotationContainer);
+ if (containerAnnot != null) {
+ Method valueMethod;
+ try {
+ valueMethod = annotationContainer.getMethod("keys");
+ result.addAll(Arrays.asList((T[]) valueMethod.invoke(containerAnnot)));
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE, "Failed to evaluate repeatable annotation.", e);
+ }
+ } else {
+ T annot = annotated.getAnnotation(repeatableAnnotation);
+ if (annot != null) {
+ result.add(annot);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Utility method to read out repeatable annotations.
+ *
+ * @param annotated the annotated instance.
+ * @param repeatableAnnotation the repeatable annotation type
+ * @param annotationContainer the container annotation type
+ * @param <T> the repeatable annotation type
+ * @param <R> the repeatable container annotation type
+ * @return a list with the annotations found (could be empty, but never null).
+ */
+ public static <T extends Annotation, R extends Annotation> Collection<T>
+ getAnnotations(AccessibleObject annotated,
+ Class<T> repeatableAnnotation,
+ Class<R> annotationContainer) {
+ List<T> result = new ArrayList<>();
+ R containerAnnot = annotated.getAnnotation(annotationContainer);
+ if (containerAnnot != null) {
+ Method valueMethod;
+ try {
+ valueMethod = annotationContainer.getMethod("keys");
+ result.addAll(Arrays.asList((T[]) valueMethod.invoke(containerAnnot)));
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE, "Failed to evaluate repeatable annotation.", e);
+ }
+ } else {
+ T annot = annotated.getAnnotation(repeatableAnnotation);
+ if (annot != null) {
+ result.add(annot);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Utility method to read out repeatable annotations.
+ *
+ * @param annotationType the annotation type.
+ * @param objects the accessible objects to be looked up
+ * @param <T> the repeatable annotation type
+ * @return a list with the annotations found (could be empty, but never null).
+ */
+ public static <T extends Annotation> T getAnnotation(
+ Class<T> annotationType, AnnotatedElement... objects) {
+ for (AnnotatedElement obj : objects) {
+ T annot = obj.getAnnotation(annotationType);
+ if (annot != null) {
+ return annot;
+ }
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/package-info.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/package-info.java b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/package-info.java
new file mode 100644
index 0000000..55e8cf6
--- /dev/null
+++ b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+/**
+ * This package provides default implementation of a purely SE based injection mechanism.
+ */
+package org.apache.tamaya.inject.internal;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/package-info.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/package-info.java b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/package-info.java
new file mode 100644
index 0000000..4119248
--- /dev/null
+++ b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+/**
+ * Main SE based injection API.
+ */
+package org.apache.tamaya.inject;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/main/resources/META-INF/services/org.apache.tamaya.inject.ConfigurationInjector
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/main/resources/META-INF/services/org.apache.tamaya.inject.ConfigurationInjector b/modules/injection/standalone/src/main/resources/META-INF/services/org.apache.tamaya.inject.ConfigurationInjector
new file mode 100644
index 0000000..7204749
--- /dev/null
+++ b/modules/injection/standalone/src/main/resources/META-INF/services/org.apache.tamaya.inject.ConfigurationInjector
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.inject.internal.DefaultConfigurationInjector
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/test/java/annottext/AnnotatedConfigBean.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/test/java/annottext/AnnotatedConfigBean.java b/modules/injection/standalone/src/test/java/annottext/AnnotatedConfigBean.java
new file mode 100644
index 0000000..3420977
--- /dev/null
+++ b/modules/injection/standalone/src/test/java/annottext/AnnotatedConfigBean.java
@@ -0,0 +1,78 @@
+/*
+ * 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 annottext;
+
+import org.apache.tamaya.inject.api.DynamicValue;
+import org.apache.tamaya.inject.api.NoConfig;
+import org.apache.tamaya.inject.api.Config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An example showing some basic annotations, using an interface to be proxied by the
+ * configuration system, nevertheless extending the overall Configuration interface.
+ * Created by Anatole on 15.02.14.
+ */
+public class AnnotatedConfigBean {
+
+ @Config(value = {"foo.bar.myprop", "mp", "common.testdata.myProperty"}, defaultValue = "ET")
+ // @ConfigLoadPolicy(listener = MyListener.class)
+ public String myParameter;
+
+ @Config("simple_value")
+ public String simpleValue;
+
+ @Config
+ String anotherValue;
+
+ @Config("host.name")
+ private String hostName;
+
+ @Config("host.name")
+ private DynamicValue<String> dynamicHostname;
+
+ @NoConfig
+ public String javaVersion;
+
+ public String getAnotherValue(){
+ return anotherValue;
+ }
+
+ public String getHostName(){
+ return hostName;
+ }
+
+ public DynamicValue<String> getDynamicValue(){
+ return dynamicHostname;
+ }
+
+ @NoConfig
+ private List<String> events = new ArrayList<>();
+
+ // verify we don't try to inject final fields
+ public static final String CONSTANT = "a constant";
+
+
+ @Config("java.version")
+ void setJavaVersion(String version){
+ this.javaVersion = version;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/test/java/annottext/AnnotatedConfigTemplate.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/test/java/annottext/AnnotatedConfigTemplate.java b/modules/injection/standalone/src/test/java/annottext/AnnotatedConfigTemplate.java
new file mode 100644
index 0000000..8c6d692
--- /dev/null
+++ b/modules/injection/standalone/src/test/java/annottext/AnnotatedConfigTemplate.java
@@ -0,0 +1,47 @@
+/*
+ * 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 annottext;
+
+import org.apache.tamaya.inject.api.DynamicValue;
+import org.apache.tamaya.inject.api.Config;
+
+/**
+ * An example showing some basic annotations, using an interface to be proxied by the
+ * configuration system.
+ * Created by Anatole on 15.02.14.
+ */
+public interface AnnotatedConfigTemplate {
+
+ @Config(value = {"foo.bar.myprop", "mp","common.testdata.myProperty"}, defaultValue = "ET")
+ // @ConfigLoadPolicy(listener = MyListener.class)
+ String myParameter();
+
+ @Config("simple_value")
+ String simpleValue();
+
+ @Config
+ String simplestValue();
+
+ @Config("host.name")
+ String hostName();
+
+ @Config("host.name")
+ DynamicValue<String> getDynamicValue();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/test/java/annottext/NonAnnotatedConfigBean.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/test/java/annottext/NonAnnotatedConfigBean.java b/modules/injection/standalone/src/test/java/annottext/NonAnnotatedConfigBean.java
new file mode 100644
index 0000000..87f8be7
--- /dev/null
+++ b/modules/injection/standalone/src/test/java/annottext/NonAnnotatedConfigBean.java
@@ -0,0 +1,45 @@
+/*
+ * 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 annottext;
+
+import org.apache.tamaya.inject.api.Config;
+import org.apache.tamaya.inject.api.DynamicValue;
+import org.apache.tamaya.inject.api.NoConfig;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An example showing some basic annotations, using an interface to be proxied by the
+ * configuration system, nevertheless extending the overall Configuration interface.
+ * Created by Anatole on 15.02.14.
+ */
+public class NonAnnotatedConfigBean {
+
+ public String simple_value = "Should be overridden!";
+
+ public String fieldKey;
+
+ public String classFieldKey = "Foo";
+
+ public String fullKey;
+
+ public String test2 = "This is not set.";
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TamayaInjectionTest.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TamayaInjectionTest.java b/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TamayaInjectionTest.java
new file mode 100644
index 0000000..d5a26c1
--- /dev/null
+++ b/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TamayaInjectionTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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;
+
+import annottext.AnnotatedConfigBean;
+import annottext.AnnotatedConfigTemplate;
+import annottext.NonAnnotatedConfigBean;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Created by Anatole on 12.01.2015.
+ */
+public class TamayaInjectionTest {
+
+ @Test
+ public void testInjectionNonAnnotatedClass(){
+ assertNotNull(ConfigurationInjection.getConfigurationInjector());
+ NonAnnotatedConfigBean testInstance = new NonAnnotatedConfigBean();
+ assertEquals(testInstance.simple_value, "Should be overridden!");
+ assertEquals(testInstance.classFieldKey, "Foo");
+ assertEquals(testInstance.fieldKey, null);
+ assertEquals(testInstance.fullKey, null);
+ assertEquals(testInstance.test2, "This is not set.");
+ ConfigurationInjection.getConfigurationInjector().configure(testInstance);
+ assertEquals(testInstance.simple_value, "aSimpleValue");
+ assertEquals(testInstance.classFieldKey, "Class-Field-Value");
+ assertEquals(testInstance.fieldKey, "Field-Value");
+ assertEquals(testInstance.fullKey, "Fullkey-Value");
+ assertEquals(testInstance.test2, "This is not set.");
+ }
+
+ @Test
+ public void testInjectionClass(){
+ assertNotNull(ConfigurationInjection.getConfigurationInjector());
+ AnnotatedConfigBean testInstance = new AnnotatedConfigBean();
+ assertEquals(testInstance.getHostName(), null);
+ assertEquals(testInstance.getAnotherValue(), null);
+ assertEquals(testInstance.myParameter, null);
+ assertEquals(testInstance.simpleValue, null);
+ ConfigurationInjection.getConfigurationInjector().configure(testInstance);
+ assertEquals(testInstance.getHostName(), "tamaya01.incubator.apache.org");
+ assertEquals(testInstance.getAnotherValue(), "HALLO!");
+ assertEquals(testInstance.myParameter, "ET");
+ assertEquals(testInstance.simpleValue, "aSimpleValue");
+ assertNotNull(testInstance.getDynamicValue());
+ assertTrue(testInstance.getDynamicValue().isPresent());
+ assertEquals(testInstance.getDynamicValue().get(), "tamaya01.incubator.apache.org");
+ assertEquals(testInstance.getHostName(), testInstance.getDynamicValue().get());
+ assertEquals(testInstance.javaVersion, System.getProperty("java.version"));
+ }
+
+ @Test
+ public void testConfigTemplate(){
+ assertNotNull(ConfigurationInjection.getConfigurationInjector());
+ AnnotatedConfigTemplate testInstance = ConfigurationInjection.getConfigurationInjector()
+ .createTemplate(AnnotatedConfigTemplate.class);
+ assertEquals(testInstance.hostName(), "tamaya01.incubator.apache.org");
+ assertEquals(testInstance.myParameter(), "ET");
+ assertEquals(testInstance.simpleValue(), "aSimpleValue");
+ assertNotNull(testInstance.getDynamicValue());
+ assertTrue(testInstance.getDynamicValue().isPresent());
+ assertEquals(testInstance.getDynamicValue().get(), "tamaya01.incubator.apache.org");
+ assertEquals(testInstance.hostName(), testInstance.getDynamicValue().get());
+// assertEquals(testInstance.simplestValue(), "HALLO!");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TestPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TestPropertySource.java b/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TestPropertySource.java
new file mode 100644
index 0000000..0853fd1
--- /dev/null
+++ b/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/TestPropertySource.java
@@ -0,0 +1,68 @@
+/*
+ * 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;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by Anatole on 12.01.2015.
+ */
+public class TestPropertySource implements PropertySource {
+
+ private Map<String,String> properties = new HashMap<>();
+
+ public TestPropertySource(){
+ properties.put("env.stage", "ET");
+ properties.put("simple_value", "aSimpleValue");
+ properties.put("host.name", "tamaya01.incubator.apache.org");
+ properties.put("anotherValue", "HALLO!");
+ properties.put("NonAnnotatedConfigBean.classFieldKey", "Class-Field-Value");
+ properties.put("NonAnnotatedConfigBean.fieldKey", "Field-Value");
+ properties.put("annottext.NonAnnotatedConfigBean.fullKey", "Fullkey-Value");
+ }
+
+ @Override
+ public int getOrdinal() {
+ return 0;
+ }
+
+ @Override
+ public String getName() {
+ return getClass().getName();
+ }
+
+ @Override
+ public PropertyValue get(String key) {
+ return PropertyValue.of(key,properties.get(key),getName());
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ @Override
+ public boolean isScannable() {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/internal/DefaultDynamicValueTest.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/internal/DefaultDynamicValueTest.java b/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/internal/DefaultDynamicValueTest.java
new file mode 100644
index 0000000..f82d04b
--- /dev/null
+++ b/modules/injection/standalone/src/test/java/org/apache/tamaya/inject/internal/DefaultDynamicValueTest.java
@@ -0,0 +1,315 @@
+/*
+ * 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.internal;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.inject.api.ConfiguredItemSupplier;
+import org.apache.tamaya.inject.api.DynamicValue;
+import org.apache.tamaya.inject.api.Config;
+import org.apache.tamaya.inject.api.UpdatePolicy;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.junit.Test;
+
+import org.apache.tamaya.Configuration;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for {@link org.apache.tamaya.inject.internal.DefaultDynamicValue}.
+ */
+public class DefaultDynamicValueTest {
+
+ @Config("a")
+ String myValue;
+
+ @Config("a")
+ String myValue2;
+
+ @Config("a")
+ void setterMethod(String value){
+
+ }
+
+ private PropertyChangeEvent event;
+
+ private PropertyChangeListener consumer = new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ event = evt;
+ }
+ };
+
+ private Map<String,String> properties = new HashMap<>();
+ private Configuration config = ConfigurationProvider.createConfiguration(
+ ConfigurationProvider.getConfigurationContextBuilder().addPropertySources(
+ new PropertySource() {
+ @Override
+ public int getOrdinal() {
+ return 0;
+ }
+
+ @Override
+ public String getName() {
+ return "test";
+ }
+
+ @Override
+ public PropertyValue get(String key) {
+ return PropertyValue.of(key,properties.get(key),getName());
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ @Override
+ public boolean isScannable() {
+ return false;
+ }
+ }
+ ).build());
+
+ @Test
+ public void testOf_Field() throws Exception {
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
+ ConfigurationProvider.getConfiguration());
+ assertNotNull(val);
+ }
+
+ @Test
+ public void testOf_Method() throws Exception {
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredMethod("setterMethod", String.class),
+ config);
+ assertNotNull(val);
+ }
+
+ @Test
+ public void testCommitAndGet() throws Exception {
+ properties.put("a","aValue");
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
+ config);
+ assertNotNull(val);
+ assertEquals("aValue",val.evaluateValue());
+ }
+
+ @Test
+ public void testCommitAndGets() throws Exception {
+ properties.put("a","aValue");
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
+ config);
+ val.setUpdatePolicy(UpdatePolicy.EXPLCIT);
+ assertNotNull(val);
+ assertEquals("aValue",val.evaluateValue());
+ // change config
+ val.get();
+ this.properties.put("a", "aValue2");
+ assertTrue(val.updateValue());
+ assertEquals("aValue2", val.commitAndGet());
+ }
+
+ @Test
+ public void testCommit() throws Exception {
+ properties.put("a", "aValue");
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
+ config);
+ val.setUpdatePolicy(UpdatePolicy.EXPLCIT);
+ assertNotNull(val);
+ assertEquals("aValue", val.evaluateValue());
+ // change config
+ val.get();
+ this.properties.put("a", "aValue2");
+ assertEquals("aValue2", val.evaluateValue());
+ assertTrue(val.updateValue());
+ val.commit();
+ assertEquals("aValue2", val.get());
+ }
+
+ @Test
+ public void testGetSetUpdatePolicy() throws Exception {
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
+ config);
+ for(UpdatePolicy pol: UpdatePolicy.values()) {
+ val.setUpdatePolicy(pol);
+ assertEquals(pol, val.getUpdatePolicy());
+ }
+ }
+
+ @Test
+ public void testAddRemoveListener() throws Exception {
+ properties.put("a","aValue");
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
+ config);
+ val.setUpdatePolicy(UpdatePolicy.IMMEDEATE);
+ val.addListener(consumer);
+ // change config
+ val.get();
+ this.properties.put("a", "aValue2");
+ val.get();
+ assertNotNull(event);
+ event = null;
+ val.removeListener(consumer);
+ this.properties.put("a", "aValue3");
+ val.updateValue();
+ assertNull(event);
+ }
+
+ @Test
+ public void testGet() throws Exception {
+ properties.put("a", "aValue");
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
+ config);
+ val.setUpdatePolicy(UpdatePolicy.IMMEDEATE);
+ properties.put("a", "aValue2");
+ val.updateValue();
+ assertEquals("aValue2", val.get());
+ }
+
+ @Test
+ public void testUpdateValue() throws Exception {
+ properties.put("a","aValue");
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
+ config);
+ val.setUpdatePolicy(UpdatePolicy.EXPLCIT);
+ assertNotNull(val.get());
+ assertEquals("aValue", val.get());
+ val.updateValue();
+ assertEquals("aValue", val.get());
+ val.setUpdatePolicy(UpdatePolicy.IMMEDEATE);
+ val.updateValue();
+ assertEquals("aValue",val.get());
+ }
+
+ @Test
+ public void testEvaluateValue() throws Exception {
+ properties.put("a","aValue");
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
+ config);
+ val.setUpdatePolicy(UpdatePolicy.EXPLCIT);
+ assertNotNull(val.get());
+ assertEquals("aValue",val.evaluateValue());
+ properties.put("a", "aValue2");
+ assertEquals("aValue2", val.evaluateValue());
+ }
+
+ @Test
+ public void testGetNewValue() throws Exception {
+ properties.put("a","aValue");
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
+ config);
+ val.setUpdatePolicy(UpdatePolicy.EXPLCIT);
+ val.get();
+ assertNull(val.getNewValue());
+ properties.put("a", "aValue2");
+ val.get();
+ assertNotNull(val.getNewValue());
+ assertEquals("aValue2", val.getNewValue());
+ val.commit();
+ assertNull(val.getNewValue());
+ }
+
+ @Test
+ public void testIsPresent() throws Exception {
+
+ }
+
+ @Test
+ public void testIfPresent() throws Exception {
+ properties.put("a","aValue");
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
+ config);
+ val.setUpdatePolicy(UpdatePolicy.IMMEDEATE);
+ assertTrue(val.isPresent());
+ properties.remove("a");
+ val.updateValue();
+ assertFalse(val.isPresent());
+ }
+
+ @Test
+ public void testOrElse() throws Exception {
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
+ config);
+ val.setUpdatePolicy(UpdatePolicy.IMMEDEATE);
+ assertEquals("bla", val.orElse("bla"));
+ properties.put("a","aValue");
+ val.updateValue();
+ assertEquals("aValue", val.orElse("bla"));
+ }
+
+ @Test
+ public void testOrElseGet() throws Exception {
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
+ config);
+ val.setUpdatePolicy(UpdatePolicy.IMMEDEATE);
+ assertEquals("bla", val.orElseGet(new ConfiguredItemSupplier() {
+ @Override
+ public Object get() {
+ return "bla";
+ }
+ }));
+ properties.put("a", "aValue");
+ val.updateValue();
+ assertEquals("aValue", val.orElseGet(new ConfiguredItemSupplier() {
+ @Override
+ public Object get() {
+ return "bla";
+ }
+ }));
+ }
+
+ @Test(expected = ConfigException.class)
+ public void testOrElseThrow() throws Throwable {
+ DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
+ config);
+ val.setUpdatePolicy(UpdatePolicy.EXPLCIT);
+ val.get();
+ properties.put("a", "aValue");
+ assertEquals("aValue", val.orElseThrow(new ConfiguredItemSupplier() {
+ @Override
+ public ConfigException get() {
+ return new ConfigException("bla");
+ }
+ }));
+ properties.remove("a");
+ val.updateValue();
+ assertEquals("aValue", val.orElseThrow(new ConfiguredItemSupplier() {
+ @Override
+ public ConfigException get() {
+ return new ConfigException("bla");
+ }
+ }));
+ }
+
+ private static final class DoublicatingConverter implements PropertyConverter<String>{
+
+ @Override
+ public String convert(String value, ConversionContext context) {
+ return value + value;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource b/modules/injection/standalone/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
new file mode 100644
index 0000000..5dfb894
--- /dev/null
+++ b/modules/injection/standalone/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.inject.TestPropertySource
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/pom.xml
----------------------------------------------------------------------
diff --git a/modules/json/pom.xml b/modules/json/pom.xml
deleted file mode 100644
index 4957986..0000000
--- a/modules/json/pom.xml
+++ /dev/null
@@ -1,149 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.tamaya.ext</groupId>
- <artifactId>tamaya-extensions</artifactId>
- <version>0.3-incubating-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>tamaya-json</artifactId>
- <name>Apache Tamaya JSON Support</name>
- <packaging>bundle</packaging>
- <inceptionYear>2015</inceptionYear>
-
- <properties>
- <jdkVersion>1.7</jdkVersion>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.tamaya</groupId>
- <artifactId>tamaya-api</artifactId>
- <version>${project.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.tamaya</groupId>
- <artifactId>tamaya-core</artifactId>
- <version>${project.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.tamaya.ext</groupId>
- <artifactId>tamaya-formats</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-json_1.0_spec</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.johnzon</groupId>
- <artifactId>johnzon-core</artifactId>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss.arquillian.daemon</groupId>
- <artifactId>arquillian-daemon-container-managed</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss.arquillian.daemon</groupId>
- <artifactId>arquillian-daemon-container-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss.arquillian.daemon</groupId>
- <artifactId>arquillian-daemon-main</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss.arquillian.daemon</groupId>
- <artifactId>arquillian-daemon-protocol-arquillian</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss.arquillian.daemon</groupId>
- <artifactId>arquillian-daemon-protocol-wire</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss.arquillian.daemon</groupId>
- <artifactId>arquillian-daemon-server</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss.arquillian.junit</groupId>
- <artifactId>arquillian-junit-container</artifactId>
- </dependency>
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>java-hamcrest</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>copyMain</id>
- <phase>process-test-sources</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <outputDirectory>${project.build.directory}</outputDirectory>
- <overWriteReleases>false</overWriteReleases>
- <overWriteSnapshots>false</overWriteSnapshots>
- <overWriteIfNewer>true</overWriteIfNewer>
- <stripVersion>true</stripVersion>
- <artifactItems>
- <artifactItem>
- <groupId>org.jboss.arquillian.daemon</groupId>
- <artifactId>arquillian-daemon-main</artifactId>
- </artifactItem>
- </artifactItems>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>
- org.apache.tamaya.json
- </Export-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-
-</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/main/java/org/apache/tamaya/json/JSONFormat.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/tamaya/json/JSONFormat.java b/modules/json/src/main/java/org/apache/tamaya/json/JSONFormat.java
deleted file mode 100644
index 8bdd414..0000000
--- a/modules/json/src/main/java/org/apache/tamaya/json/JSONFormat.java
+++ /dev/null
@@ -1,85 +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.json;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.format.ConfigurationData;
-import org.apache.tamaya.format.ConfigurationDataBuilder;
-import org.apache.tamaya.format.ConfigurationFormat;
-
-import java.io.InputStream;
-import java.net.URL;
-import java.nio.charset.Charset;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-import javax.json.Json;
-import javax.json.JsonException;
-import javax.json.JsonObject;
-import javax.json.JsonReader;
-import javax.json.JsonReaderFactory;
-
-/**
- * Implementation of the {@link org.apache.tamaya.format.ConfigurationFormat}
- * able to read configuration properties represented in JSON
- *
- * @see <a href="http://www.json.org">JSON format specification</a>
- */
-public class JSONFormat implements ConfigurationFormat {
- /** Property that make Johnzon accept commentc. */
- public static final String JOHNZON_SUPPORTS_COMMENTS_PROP = "org.apache.johnzon.supports-comments";
- /** The reader factory used. */
- private final JsonReaderFactory readerFactory;
-
- /**
- * Constructor, itniaitlizing zhe JSON reader factory.
- */
- public JSONFormat(){
- Map<String, Object> config = new HashMap<>();
- config.put(JOHNZON_SUPPORTS_COMMENTS_PROP, true);
- this.readerFactory = Json.createReaderFactory(config);
- }
-
- @Override
- public String getName() {
- return "json";
- }
-
- @Override
- public boolean accepts(URL url) {
- return Objects.requireNonNull(url).getPath().endsWith(".json");
- }
-
- @Override
- public ConfigurationData readConfiguration(String resource, InputStream inputStream) {
-
- try {
- final JsonReader reader = this.readerFactory.createReader(inputStream, Charset.forName("UTF-8"));
- JsonObject root = reader.readObject();
- HashMap<String, String> values = new HashMap<>();
- JSONVisitor visitor = new JSONVisitor(root, values);
- visitor.run();
- return ConfigurationDataBuilder.of(resource, this).addProperties(values)
- .build();
- } catch (JsonException e) {
- throw new ConfigException("Failed to read data from " + resource, e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/main/java/org/apache/tamaya/json/JSONPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/tamaya/json/JSONPropertySource.java b/modules/json/src/main/java/org/apache/tamaya/json/JSONPropertySource.java
deleted file mode 100644
index 43cfa73..0000000
--- a/modules/json/src/main/java/org/apache/tamaya/json/JSONPropertySource.java
+++ /dev/null
@@ -1,149 +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.json;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertyValue;
-
-import java.io.InputStream;
-import java.net.URL;
-import java.nio.charset.Charset;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.json.Json;
-import javax.json.JsonObject;
-import javax.json.JsonReaderFactory;
-import javax.json.JsonStructure;
-
-import static java.lang.String.format;
-
-/**
- * Property source based on a JSON file.
- */
-public class JSONPropertySource implements PropertySource {
- /** Constant for enabling comments in Johnzon. */
- public static final String JOHNZON_SUPPORTS_COMMENTS_PROP = "org.apache.johnzon.supports-comments";
-
- /** The underlying resource. */
- private final URL urlResource;
- /** The values read. */
- private final Map<String, String> values;
- /** The evaluated ordinal. */
- private int ordinal;
- /** The JSON reader factory used. */
- private JsonReaderFactory readerFactory = initReaderFactory();
-
- /** Initializes the factory to be used for creating readers. */
- private JsonReaderFactory initReaderFactory() {
- Map<String, Object> config = new HashMap<>();
- config.put(JOHNZON_SUPPORTS_COMMENTS_PROP, true);
- return Json.createReaderFactory(config);
- }
-
- /**
- * Constructor, hereby using 0 as the default ordinal.
- * @param resource the resource modelled as URL, not null.
- */
- public JSONPropertySource(URL resource) {
- this(resource, 0);
- }
-
- /**
- * Constructor.
- * @param resource the resource modelled as URL, not null.
- * @param defaultOrdinal the defaultOrdinal to be used.
- */
- public JSONPropertySource(URL resource, int defaultOrdinal) {
- urlResource = Objects.requireNonNull(resource);
- this.ordinal = defaultOrdinal; // may be overriden by read...
- this.values = readConfig(urlResource);
- if (this.values.containsKey(TAMAYA_ORDINAL)) {
- this.ordinal = Integer.parseInt(this.values.get(TAMAYA_ORDINAL));
- }
- Map<String, Object> config = new HashMap<>();
- config.put(JOHNZON_SUPPORTS_COMMENTS_PROP, true);
- this.readerFactory = Json.createReaderFactory(config);
- }
-
-
- @Override
- public int getOrdinal() {
- PropertyValue configuredOrdinal = get(TAMAYA_ORDINAL);
- if(configuredOrdinal!=null){
- try{
- return Integer.parseInt(configuredOrdinal.getValue());
- } catch(Exception e){
- Logger.getLogger(getClass().getName()).log(Level.WARNING,
- "Configured Ordinal is not an int number: " + configuredOrdinal, e);
- }
- }
- return ordinal;
- }
-
- @Override
- public String getName() {
- return urlResource.toExternalForm();
- }
-
- @Override
- public PropertyValue get(String key) {
- return PropertyValue.of(key, getProperties().get(key), getName());
- }
-
- @Override
- public Map<String, String> getProperties() {
- return Collections.unmodifiableMap(values);
- }
-
- /**
- * Reads the configuration.
- * @param urlResource soure of the configuration.
- * @return the configuration read from the given resource URL.
- * @throws ConfigException if resource URL cannot be read.
- */
- protected Map<String, String> readConfig(URL urlResource) {
- try (InputStream is = urlResource.openStream()) {
- JsonStructure root = this.readerFactory.createReader(is, Charset.forName("UTF-8")).read();
-
- // Test added. H. Saly, 15. Aug. 2015
- if (!(root instanceof JsonObject)) {
- throw new ConfigException("Currently only JSON objects are supported");
- }
-
- Map<String, String> values = new HashMap<>();
- JSONVisitor visitor = new JSONVisitor((JsonObject)root, values);
- visitor.run();
- return values;
- }
- catch (Throwable t) {
- throw new ConfigException(format("Failed to read properties from %s", urlResource.toExternalForm()), t);
- }
- }
-
- @Override
- public boolean isScannable() {
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/main/java/org/apache/tamaya/json/JSONVisitor.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/tamaya/json/JSONVisitor.java b/modules/json/src/main/java/org/apache/tamaya/json/JSONVisitor.java
deleted file mode 100644
index 2135ec5..0000000
--- a/modules/json/src/main/java/org/apache/tamaya/json/JSONVisitor.java
+++ /dev/null
@@ -1,119 +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.json;
-
-import org.apache.tamaya.ConfigException;
-
-import java.util.*;
-
-import javax.json.JsonArray;
-import javax.json.JsonObject;
-import javax.json.JsonString;
-import javax.json.JsonStructure;
-import javax.json.JsonValue;
-
-/**
- * Visitor implementation to read a JSON formatted input source.
- */
-class JSONVisitor {
- private final JsonObject rootNode;
- private final Map<String, String> targetStore;
-
- JSONVisitor(JsonObject startNode, Map<String, String> target) {
- rootNode = startNode;
- targetStore = target;
- }
-
- public void run() {
- Deque<VisitingContext> stack = new ArrayDeque<>();
-
- stack.add(new VisitingContext(rootNode));
- boolean goOn = stack.peek().hasNext();
-
- if (goOn) {
- do {
- Map.Entry<String, JsonValue> current = stack.peek().nextElement();
-
- if (!(current.getValue() instanceof JsonStructure)) {
- String key = stack.peek().getNSPrefix() + current.getKey();
- String value;
- JsonValue jsonValue = current.getValue();
- switch(jsonValue.getValueType()) {
- case NULL: value = null; break;
- case FALSE: value = Boolean.FALSE.toString(); break;
- case TRUE: value = Boolean.TRUE.toString(); break;
- case NUMBER: value = jsonValue.toString(); break;
- case STRING: value = ((JsonString) jsonValue).getString(); break;
- default:
- throw new ConfigException("Internal failure while processing JSON document.");
- }
-
- targetStore.put(key, value);
- } else if (current.getValue() instanceof JsonObject) {
- String key = stack.peek().getNSPrefix() + current.getKey();
- JsonObject node = (JsonObject) current.getValue();
- stack.push(new VisitingContext(node, key));
- } else if (current.getValue() instanceof JsonArray) {
- throw new ConfigException("Arrays are not supported at the moment.");
- } else {
- throw new ConfigException("Internal failure while processing JSON document.");
- }
-
- goOn = stack.peek().hasNext();
-
- while (!goOn && stack.size() > 0) {
- stack.remove();
- goOn = (stack.size() > 0) && stack.peek().hasNext();
- }
- } while (goOn);
- }
- }
-
- /**
- * Context for a sub context visited.
- */
- private static class VisitingContext {
- private final String namespace;
- private final JsonObject node;
- private final Iterator<Map.Entry<String, JsonValue>> elements;
-
- public VisitingContext(JsonObject node) {
- this(node, "");
- }
-
- public VisitingContext(JsonObject rootNode, String currentNamespace) {
- namespace = currentNamespace;
- node = rootNode;
- elements = node.entrySet().iterator();
- }
-
- public Map.Entry<String, JsonValue> nextElement() {
- return elements.next();
- }
-
-
- public boolean hasNext() {
- return elements.hasNext();
- }
-
- public String getNSPrefix() {
- return namespace.isEmpty() ? namespace : namespace + ".";
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
----------------------------------------------------------------------
diff --git a/modules/json/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat b/modules/json/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
deleted file mode 100644
index a843cbe..0000000
--- a/modules/json/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
+++ /dev/null
@@ -1,19 +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 current 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.
-#
-org.apache.tamaya.json.JSONFormat
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/java/org/apache/tamaya/json/CommonJSONTestCaseCollection.java
----------------------------------------------------------------------
diff --git a/modules/json/src/test/java/org/apache/tamaya/json/CommonJSONTestCaseCollection.java b/modules/json/src/test/java/org/apache/tamaya/json/CommonJSONTestCaseCollection.java
deleted file mode 100644
index 946878c..0000000
--- a/modules/json/src/test/java/org/apache/tamaya/json/CommonJSONTestCaseCollection.java
+++ /dev/null
@@ -1,190 +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.json;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertyValue;
-import org.hamcrest.CoreMatchers;
-import org.hamcrest.Matchers;
-import org.junit.Test;
-
-import java.net.URL;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.hasSize;
-
-/**
- * Class with a collection of common test cases each JSON processing
- * class must be able to pass.
- */
-public abstract class CommonJSONTestCaseCollection {
-
- abstract PropertySource getPropertiesFrom(URL source) throws Exception;
-
- @Test
- public void canReadNonLatinCharacters() throws Exception {
- URL configURL = JSONPropertySourceTest.class
- .getResource("/configs/valid/cyrillic.json");
-
- assertThat(configURL, Matchers.notNullValue());
-
- PropertySource propertySource = getPropertiesFrom(configURL);
-
- assertThat(propertySource.get("name"), Matchers.notNullValue());
- assertThat(propertySource.get("name").getValue(), equalTo("\u041e\u043b\u0438\u0432\u0435\u0440"));
- assertThat(propertySource.get("\u0444\u0430\u043c\u0438\u043b\u0438\u044f"), Matchers.notNullValue());
- assertThat(propertySource.get("\u0444\u0430\u043c\u0438\u043b\u0438\u044f").getValue(), Matchers.equalTo("Fischer"));
- }
-
- @Test
- public void canReadNestedStringOnlyJSONConfigFile() throws Exception {
- URL configURL = JSONPropertySourceTest.class
- .getResource("/configs/valid/simple-nested-string-only-config-1.json");
-
- assertThat(configURL, CoreMatchers.notNullValue());
-
- PropertySource properties = getPropertiesFrom(configURL);
-
- assertThat(properties.getProperties().keySet(), hasSize(5));
-
- PropertyValue keyB = properties.get("b");
- PropertyValue keyDO = properties.get("d.o");
- PropertyValue keyDP = properties.get("d.p");
-
- assertThat(keyB, notNullValue());
- assertThat(keyB.getValue(), equalTo("B"));
- assertThat(keyDO, notNullValue());
- assertThat(keyDO.getValue(), equalTo("O"));
- assertThat(keyDP, Matchers.notNullValue());
- assertThat(keyDP.getValue(), is("P"));
- }
-
- @Test
- public void canReadNestedStringOnlyJSONConfigFileWithObjectInTheMiddle()
- throws Exception {
- URL configURL = JSONPropertySourceTest.class
- .getResource("/configs/valid/simple-nested-string-only-config-2.json");
-
- assertThat(configURL, CoreMatchers.notNullValue());
-
- PropertySource properties = getPropertiesFrom(configURL);
-
- assertThat(properties.getProperties().keySet(), hasSize(4));
-
- PropertyValue keyA = properties.get("a");
- PropertyValue keyDO = properties.get("b.o");
- PropertyValue keyDP = properties.get("b.p");
- PropertyValue keyC = properties.get("c");
-
- assertThat(keyA, notNullValue());
- assertThat(keyA.getValue(), is("A"));
- assertThat(keyC, notNullValue());
- assertThat(keyC.getValue(), equalTo("C"));
- assertThat(keyDO, notNullValue());
- assertThat(keyDO.getValue(), equalTo("O"));
- assertThat(keyDP, notNullValue());
- assertThat(keyDP.getValue(), is("P"));
- }
-
- @Test(expected = ConfigException.class)
- public void canHandleIllegalJSONFileWhichContainsAnArray() throws Exception {
- URL configURL = JSONPropertySourceTest.class.getResource("/configs/invalid/with-array.json");
-
- assertThat(configURL, CoreMatchers.notNullValue());
-
- getPropertiesFrom(configURL).getProperties();
- }
-
- @Test(expected = ConfigException.class)
- public void canHandleIllegalJSONFileConsistingOfOneOpeningBracket() throws Exception {
- URL configURL = JSONPropertySourceTest.class.getResource("/configs/invalid/only-opening-bracket.json");
-
- assertThat(configURL, CoreMatchers.notNullValue());
-
- getPropertiesFrom(configURL).getProperties();
- }
-
- @Test(expected = ConfigException.class)
- public void canHandleIllegalJSONFileWhichIsEmpty() throws Exception {
- URL configURL = JSONPropertySourceTest.class.getResource("/configs/invalid/empty-file.json");
-
- assertThat(configURL, CoreMatchers.notNullValue());
-
- getPropertiesFrom(configURL).getProperties();
- }
-
- @Test
- public void priorityInConfigFileOverwriteExplicitlyGivenPriority() throws Exception {
- URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/with-explicit-priority.json");
-
- assertThat(configURL, CoreMatchers.notNullValue());
-
- PropertySource properties = getPropertiesFrom(configURL);
-
- assertThat(properties.getOrdinal(), is(16784));
- }
-
- @Test
- public void canReadFlatStringOnlyJSONConfigFile() throws Exception {
- URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/simple-flat-string-only-config.json");
-
- assertThat(configURL, CoreMatchers.notNullValue());
-
- PropertySource properties = getPropertiesFrom(configURL);
-
- assertThat(properties.getProperties().keySet(), hasSize(3));
-
- PropertyValue keyA = properties.get("a");
- PropertyValue keyB = properties.get("b");
- PropertyValue keyC = properties.get("c");
-
- assertThat(keyA, notNullValue());
- assertThat(keyA.getValue(), equalTo("A"));
- assertThat(keyB, notNullValue());
- assertThat(keyB.getValue(), is("B"));
- assertThat(keyC, notNullValue());
- assertThat(keyC.getValue(), is("C"));
- }
-
- @Test(expected = ConfigException.class)
- public void emptyJSONFileResultsInConfigException() throws Exception {
- URL configURL = JSONPropertySourceTest.class.getResource("/configs/invalid/empty-file.json");
-
- assertThat(configURL, CoreMatchers.notNullValue());
-
- PropertySource properties = getPropertiesFrom(configURL);
-
- properties.getProperties();
- }
-
- @Test
- public void canHandleEmptyJSONObject() throws Exception {
- URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/empty-object-config.json");
-
- assertThat(configURL, CoreMatchers.notNullValue());
-
- PropertySource properties = getPropertiesFrom(configURL);
-
- assertThat(properties.getProperties().keySet(), hasSize(0));
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/java/org/apache/tamaya/json/JSONFormatIT.java
----------------------------------------------------------------------
diff --git a/modules/json/src/test/java/org/apache/tamaya/json/JSONFormatIT.java b/modules/json/src/test/java/org/apache/tamaya/json/JSONFormatIT.java
deleted file mode 100644
index 851655e..0000000
--- a/modules/json/src/test/java/org/apache/tamaya/json/JSONFormatIT.java
+++ /dev/null
@@ -1,48 +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.json;
-
-import org.apache.tamaya.format.ConfigurationFormat;
-import org.apache.tamaya.spi.ServiceContextManager;
-import org.junit.Test;
-
-import java.util.List;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.notNullValue;
-
-/**
- * Integration tests for {@link JSONFormat}.
- */
-public class JSONFormatIT {
- @Test
- public void jsonFormatCanBeFoundViaServiceLoader() throws Exception {
- List<ConfigurationFormat> formats = ServiceContextManager.getServiceContext()
- .getServices(ConfigurationFormat.class);
-
- ConfigurationFormat format = null;
- for (ConfigurationFormat f : formats) {
- if (f instanceof JSONFormat) {
- format = f;
- break;
- }
- }
- assertThat(format, notNullValue());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/java/org/apache/tamaya/json/JSONFormatTest.java
----------------------------------------------------------------------
diff --git a/modules/json/src/test/java/org/apache/tamaya/json/JSONFormatTest.java b/modules/json/src/test/java/org/apache/tamaya/json/JSONFormatTest.java
deleted file mode 100644
index 9218046..0000000
--- a/modules/json/src/test/java/org/apache/tamaya/json/JSONFormatTest.java
+++ /dev/null
@@ -1,75 +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.json;
-
-
-import org.apache.tamaya.format.ConfigurationData;
-import org.apache.tamaya.format.FlattenedDefaultPropertySource;
-import org.apache.tamaya.spi.PropertySource;
-import org.junit.Test;
-
-import java.io.InputStream;
-import java.net.URL;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.Is.is;
-
-public class JSONFormatTest extends CommonJSONTestCaseCollection {
- private final JSONFormat format = new JSONFormat();
-
- @Test(expected = NullPointerException.class)
- public void acceptsNeedsNonNullParameter() throws Exception {
- format.accepts(null);
- }
-
- @Test
- public void aNonJSONFileBasedURLIsNotAccepted() throws Exception {
- URL url = new URL("file:///etc/service/conf.conf");
-
- assertThat(format.accepts(url), is(false));
- }
-
- @Test
- public void aJSONFileBasedURLIsAccepted() throws Exception {
- URL url = new URL("file:///etc/service/conf.json");
-
- assertThat(format.accepts(url), is(true));
- }
-
- @Test
- public void aHTTPBasedURLIsNotAccepted() throws Exception {
- URL url = new URL("http://nowhere.somewhere/conf.json");
- assertThat(format.accepts(url), is(true));
- }
-
- @Test
- public void aFTPBasedURLIsNotAccepted() throws Exception {
- URL url = new URL("ftp://nowhere.somewhere/a/b/c/d/conf.json");
-
- assertThat(format.accepts(url), is(true));
- }
-
- @Override
- PropertySource getPropertiesFrom(URL source) throws Exception {
- try (InputStream is = source.openStream()) {
- ConfigurationData data = format.readConfiguration(source.toString(), is);
- return new FlattenedDefaultPropertySource(data);
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/java/org/apache/tamaya/json/JSONPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/modules/json/src/test/java/org/apache/tamaya/json/JSONPropertySourceTest.java b/modules/json/src/test/java/org/apache/tamaya/json/JSONPropertySourceTest.java
deleted file mode 100644
index 9892446..0000000
--- a/modules/json/src/test/java/org/apache/tamaya/json/JSONPropertySourceTest.java
+++ /dev/null
@@ -1,56 +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.json;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.spi.PropertySource;
-import org.hamcrest.CoreMatchers;
-import org.junit.Test;
-
-import java.net.URL;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-
-public class JSONPropertySourceTest extends CommonJSONTestCaseCollection {
-
- @Test
- public void tamayaOrdinalKeywordIsNotPropagatedAsNormalProperty() throws Exception {
- URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/with-explicit-priority.json");
-
- assertThat(configURL, CoreMatchers.notNullValue());
-
- JSONPropertySource source = new JSONPropertySource(configURL, 4);
- assertEquals(source.get(PropertySource.TAMAYA_ORDINAL).getValue(), "16784");
- }
-
- @Test(expected=ConfigException.class)
- public void testDoNotAcceptJsonArrays() throws Exception {
- URL configURL = JSONPropertySourceTest.class.getResource("/configs/invalid/array.json");
-
- assertThat(configURL, CoreMatchers.notNullValue());
-
- new JSONPropertySource(configURL);
- }
-
- @Override
- PropertySource getPropertiesFrom(URL source) throws Exception {
- return new JSONPropertySource(source);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/resources/arquillian.xml
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/arquillian.xml b/modules/json/src/test/resources/arquillian.xml
deleted file mode 100644
index 1eeb58b..0000000
--- a/modules/json/src/test/resources/arquillian.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<arquillian xmlns="http://jboss.org/schema/arquillian"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
- <container qualifier="daemon" default="true">
- <configuration>
- <property name="host">localhost</property>
- <property name="port">12346</property>
- <property name="serverJarFile">target/arquillian-daemon-main.jar</property>
- </configuration>
- </container>
-</arquillian>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/resources/configs/invalid/array.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/invalid/array.json b/modules/json/src/test/resources/configs/invalid/array.json
deleted file mode 100644
index 0c2058a..0000000
--- a/modules/json/src/test/resources/configs/invalid/array.json
+++ /dev/null
@@ -1,21 +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.
-*/
-[
-
-]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/resources/configs/invalid/empty-file.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/invalid/empty-file.json b/modules/json/src/test/resources/configs/invalid/empty-file.json
deleted file mode 100644
index f396085..0000000
--- a/modules/json/src/test/resources/configs/invalid/empty-file.json
+++ /dev/null
@@ -1,18 +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.
-*/
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/resources/configs/invalid/only-opening-bracket.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/invalid/only-opening-bracket.json b/modules/json/src/test/resources/configs/invalid/only-opening-bracket.json
deleted file mode 100644
index b936f69..0000000
--- a/modules/json/src/test/resources/configs/invalid/only-opening-bracket.json
+++ /dev/null
@@ -1,19 +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.
-*/
-{
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/resources/configs/invalid/with-array.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/invalid/with-array.json b/modules/json/src/test/resources/configs/invalid/with-array.json
deleted file mode 100644
index e623e49..0000000
--- a/modules/json/src/test/resources/configs/invalid/with-array.json
+++ /dev/null
@@ -1,27 +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.
-*/
-{
- "a" : "A",
- "b" : {
- "c" : "C",
- "d" : [
- "1", "2"
- ]
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/resources/configs/valid/cyrillic.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/valid/cyrillic.json b/modules/json/src/test/resources/configs/valid/cyrillic.json
deleted file mode 100644
index b9f07b8..0000000
--- a/modules/json/src/test/resources/configs/valid/cyrillic.json
+++ /dev/null
@@ -1,22 +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.
-*/
-{
- "name" : "\u041e\u043b\u0438\u0432\u0435\u0440",
- "\u0444\u0430\u043c\u0438\u043b\u0438\u044f" : "Fischer"
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/resources/configs/valid/empty-object-config.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/valid/empty-object-config.json b/modules/json/src/test/resources/configs/valid/empty-object-config.json
deleted file mode 100644
index 103c28d..0000000
--- a/modules/json/src/test/resources/configs/valid/empty-object-config.json
+++ /dev/null
@@ -1,20 +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.
-*/
-{
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/resources/configs/valid/simple-flat-string-only-config.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/valid/simple-flat-string-only-config.json b/modules/json/src/test/resources/configs/valid/simple-flat-string-only-config.json
deleted file mode 100644
index 02e2cd8..0000000
--- a/modules/json/src/test/resources/configs/valid/simple-flat-string-only-config.json
+++ /dev/null
@@ -1,23 +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.
-*/
-{
- "a" : "A",
- "b" : "B",
- "c" : "C"
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json b/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json
deleted file mode 100644
index fb2c4fe..0000000
--- a/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json
+++ /dev/null
@@ -1,27 +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.
-*/
-{
- "a": "A",
- "b": "B",
- "c": "C",
- "d": {
- "o": "O",
- "p": "P"
- }
-}
[02/15] incubator-tamaya-extensions git commit: TAMAYA-189: Moved
format and injection modules into separate subtrees.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json b/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json
deleted file mode 100644
index b037174..0000000
--- a/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json
+++ /dev/null
@@ -1,26 +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.
-*/
-{
- "a" : "A",
- "b" : {
- "o" : "O",
- "p" : "P"
- },
- "c" : "C"
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/json/src/test/resources/configs/valid/with-explicit-priority.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/valid/with-explicit-priority.json b/modules/json/src/test/resources/configs/valid/with-explicit-priority.json
deleted file mode 100644
index ed7acc2..0000000
--- a/modules/json/src/test/resources/configs/valid/with-explicit-priority.json
+++ /dev/null
@@ -1,25 +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.
-*/
-{
- /*
- some useful comment here
- */
- "tamaya.ordinal" : 16784,
- "a" : "A" // another comment
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/pom.xml
----------------------------------------------------------------------
diff --git a/modules/pom.xml b/modules/pom.xml
index ffe708c..d243154 100644
--- a/modules/pom.xml
+++ b/modules/pom.xml
@@ -38,14 +38,12 @@ under the License.
<module>formats</module>
<module>functions</module>
<module>injection</module>
- <module>injection-api</module>
- <module>json</module>
+ <module>mutable-config</module>
<module>optional</module>
<module>resolver</module>
<module>resources</module>
<module>spi-support</module>
<module>spring</module>
- <module>yaml</module>
</modules>
<build>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/yaml/pom.xml
----------------------------------------------------------------------
diff --git a/modules/yaml/pom.xml b/modules/yaml/pom.xml
deleted file mode 100644
index 0a5a5d1..0000000
--- a/modules/yaml/pom.xml
+++ /dev/null
@@ -1,119 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.tamaya.ext</groupId>
- <artifactId>tamaya-extensions</artifactId>
- <version>0.3-incubating-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>tamaya-yaml</artifactId>
- <name>Apache Tamaya YAML Support</name>
- <packaging>bundle</packaging>
- <inceptionYear>2016</inceptionYear>
-
- <properties>
- <jdkVersion>1.7</jdkVersion>
- <snakeyaml.version>1.17</snakeyaml.version>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.tamaya</groupId>
- <artifactId>tamaya-api</artifactId>
- <version>${project.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.tamaya</groupId>
- <artifactId>tamaya-core</artifactId>
- <version>${project.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.tamaya.ext</groupId>
- <artifactId>tamaya-formats</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.yaml</groupId>
- <artifactId>snakeyaml</artifactId>
- <version>${snakeyaml.version}</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>java-hamcrest</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>copyMain</id>
- <phase>process-test-sources</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <outputDirectory>${project.build.directory}</outputDirectory>
- <overWriteReleases>false</overWriteReleases>
- <overWriteSnapshots>false</overWriteSnapshots>
- <overWriteIfNewer>true</overWriteIfNewer>
- <stripVersion>true</stripVersion>
- <artifactItems>
- <artifactItem>
- <groupId>org.jboss.arquillian.daemon</groupId>
- <artifactId>arquillian-daemon-main</artifactId>
- </artifactItem>
- </artifactItems>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>
- org.apache.tamaya.json
- </Export-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-
-</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLFormat.java
----------------------------------------------------------------------
diff --git a/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLFormat.java b/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLFormat.java
deleted file mode 100644
index 06e431e..0000000
--- a/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLFormat.java
+++ /dev/null
@@ -1,156 +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.json;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.format.ConfigurationData;
-import org.apache.tamaya.format.ConfigurationDataBuilder;
-import org.apache.tamaya.format.ConfigurationFormat;
-import org.yaml.snakeyaml.Yaml;
-
-import java.io.InputStream;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import static java.lang.String.format;
-
-
-/**
- * Implementation of the {@link org.apache.tamaya.format.ConfigurationFormat}
- * able to read configuration properties represented in JSON
- *
- * @see <a href="http://www.json.org">JSON format specification</a>
- */
-public class YAMLFormat implements ConfigurationFormat {
- /**
- * THe logger.
- */
- private static final Logger LOG = Logger.getLogger(YAMLFormat.class.getName());
-
- /**
- * Constructor, itniaitlizing zhe JSON reader factory.
- */
- public YAMLFormat(){
- }
-
- @Override
- public String getName() {
- return "yaml";
- }
-
- @Override
- public boolean accepts(URL url) {
- return Objects.requireNonNull(url).getPath().endsWith(".yaml");
- }
-
- @Override
- public ConfigurationData readConfiguration(String resource, InputStream inputStream) {
- try( InputStream in = inputStream;) {
- Map<String, String> values = readConfig(resource, inputStream);
- return ConfigurationDataBuilder.of(resource, this).addProperties(values)
- .build();
- } catch (Exception e) {
- throw new ConfigException("Failed to read data from " + resource, e);
- }
- }
-
- /**
- * Reads the configuration.
- * @param inputStream the input stream, not null.
- * @param resource resource URI, not null.
- * @return the configuration read from the given resource URI.
- * @throws ConfigException if resource URI cannot be read.
- */
- protected Map<String, String> readConfig(String resource, InputStream inputStream) {
- try{
- Yaml yaml = new Yaml();
- HashMap<String, String> values = new HashMap<>();
- Object config = yaml.load(inputStream);
- mapYamlIntoProperties(config, values);
- if(LOG.isLoggable(Level.FINEST)){
- LOG.finest("Read data from " + resource + " : " + values);
- }
- return values;
- }catch (Throwable t) {
- throw new ConfigException(format("Failed to read properties from %s", resource), t);
- }
- }
- /**
- * Reads the configuration.
- * @param urlResource soure of the configuration.
- * @return the configuration read from the given resource URL.
- * @throws ConfigException if resource URL cannot be read.
- */
- protected Map<String, String> readConfig(URL urlResource) {
- try (InputStream is = urlResource.openStream()) {
- return readConfig(urlResource.toExternalForm(), is);
- }
- catch (Throwable t) {
- throw new ConfigException(format("Failed to read properties from %s", urlResource.toExternalForm()), t);
- }
- }
-
- private void mapYamlIntoProperties(Object config, HashMap<String, String> values) {
- mapYamlIntoProperties("", config, values);
- }
-
- /**
- * Maps the given config item (could be a String, a collection type or something else returned by the yaml parser
- * to a key/value pair and adds it to {@code values} (hereby honoring the prefix as a key to be used.).
- * Collection types are recursively to remapped hereby extending the given prefix as needed and recursively
- * delegate mapping of values contained.
- * @param prefix the prefix or key evaluated so far, never null (but can be empty for root entries).
- * @param config the config value. Could be a single value or a collection type.
- * @param values the properties where items identified must be written into. These properties are going to be
- * returned as result of the format reading operation ans integrated into the overall configuration
- * map.
- */
- protected void mapYamlIntoProperties(String prefix, Object config, HashMap<String, String> values) {
- // add further data types supported by yaml, e.g. date, ...
- if(config instanceof List){
- StringBuilder b = new StringBuilder();
- for(Object val:((List<Object>)config)){
- b.append(mapValueToString(val));
- b.append(",");
- }
- if(b.length()>0){
- b.setLength(b.length()-1);
- }
- values.put(prefix, b.toString());
- values.put("_"+prefix+".collection-type", "List");
- } else if(config instanceof Map){
- for(Map.Entry<String,Object> en:((Map<String,Object>)config).entrySet()){
- String newPrefix = prefix.isEmpty()?en.getKey():prefix +"."+en.getKey();
- mapYamlIntoProperties(newPrefix, en.getValue(), values);
- }
- } else{
- values.put(prefix, mapValueToString(config));
- }
- }
-
- protected String mapValueToString(Object val) {
- return String.valueOf(val);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLPropertySource.java b/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLPropertySource.java
deleted file mode 100644
index e29d2e7..0000000
--- a/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLPropertySource.java
+++ /dev/null
@@ -1,100 +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.json;
-
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertyValue;
-
-import java.net.URL;
-import java.util.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-
-
-/**
- * Property source based on a JSON file.
- */
-public class YAMLPropertySource implements PropertySource {
- /** The underlying resource. */
- private final URL urlResource;
- /** The values read. */
- private final Map<String, String> values;
- /** The evaluated ordinal. */
- private int ordinal;
- /** The format implementation used for parsing. */
- private YAMLFormat format = new YAMLFormat();
-
- /**
- * Constructor, hereby using 0 as the default ordinal.
- * @param resource the resource modelled as URL, not null.
- */
- public YAMLPropertySource(URL resource) {
- this(resource, 0);
- }
-
- /**
- * Constructor.
- * @param resource the resource modelled as URL, not null.
- * @param defaultOrdinal the defaultOrdinal to be used.
- */
- public YAMLPropertySource(URL resource, int defaultOrdinal) {
- urlResource = Objects.requireNonNull(resource);
- this.ordinal = defaultOrdinal; // may be overriden by read...
- this.values = format.readConfig(urlResource);
- if (this.values.containsKey(TAMAYA_ORDINAL)) {
- this.ordinal = Integer.parseInt(this.values.get(TAMAYA_ORDINAL));
- }
- }
-
- @Override
- public int getOrdinal() {
- PropertyValue configuredOrdinal = get(TAMAYA_ORDINAL);
- if(configuredOrdinal!=null){
- try{
- return Integer.parseInt(configuredOrdinal.getValue());
- } catch(Exception e){
- Logger.getLogger(getClass().getName()).log(Level.WARNING,
- "Configured Ordinal is not an int number: " + configuredOrdinal, e);
- }
- }
- return ordinal;
- }
-
- @Override
- public String getName() {
- return urlResource.toExternalForm();
- }
-
- @Override
- public PropertyValue get(String key) {
- return PropertyValue.of(key, getProperties().get(key), getName());
- }
-
- @Override
- public Map<String, String> getProperties() {
- return Collections.unmodifiableMap(values);
- }
-
-
- @Override
- public boolean isScannable() {
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/yaml/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
----------------------------------------------------------------------
diff --git a/modules/yaml/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat b/modules/yaml/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
deleted file mode 100644
index 1b5d57d..0000000
--- a/modules/yaml/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
+++ /dev/null
@@ -1,19 +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 current 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.
-#
-org.apache.tamaya.json.YAMLFormat
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLFormatTest.java
----------------------------------------------------------------------
diff --git a/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLFormatTest.java b/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLFormatTest.java
deleted file mode 100644
index 0f0e589..0000000
--- a/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLFormatTest.java
+++ /dev/null
@@ -1,73 +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.json;
-
-
-import org.apache.tamaya.format.ConfigurationData;
-import org.apache.tamaya.format.FlattenedDefaultPropertySource;
-import org.apache.tamaya.spi.PropertySource;
-import org.junit.Test;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Map;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-public class YAMLFormatTest {
- private final YAMLFormat format = new YAMLFormat();
-
- @Test
- public void testAcceptURL() throws MalformedURLException {
- assertTrue(format.accepts(new URL("http://127.0.0.1/anyfile.yaml")));
- }
-
- @Test
- public void testAcceptURL_BC1() throws MalformedURLException {
- assertFalse(format.accepts(new URL("http://127.0.0.1/anyfile.YAML")));
- }
-
- @Test(expected = NullPointerException.class)
- public void testAcceptURL_BC2() throws MalformedURLException {
- assertFalse(format.accepts(null));
- }
-
- @Test
- public void testAcceptURL_BC3() throws MalformedURLException {
- assertFalse(format.accepts(new URL("http://127.0.0.1/anyfile.docx")));
- }
-
- @Test
- public void testRead() throws IOException {
- URL configURL = YAMLPropertySourceTest.class.getResource("/configs/valid/contact.yaml");
- assertTrue(format.accepts(configURL));
- ConfigurationData data = format.readConfiguration(configURL.toString(), configURL.openStream());
- assertNotNull(data);
- for(Map.Entry<String,String> en:data.getDefaultProperties().entrySet()) {
- System.out.println(en.getKey() + " -> " + en.getValue());
- }
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLPropertySourceTest.java b/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLPropertySourceTest.java
deleted file mode 100644
index 7f1c7a3..0000000
--- a/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLPropertySourceTest.java
+++ /dev/null
@@ -1,54 +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.json;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.spi.PropertySource;
-import org.hamcrest.CoreMatchers;
-import org.junit.Test;
-
-import java.net.URL;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-
-public class YAMLPropertySourceTest {
-
- @Test
- public void testYamlWithOrdinal() throws Exception {
- URL configURL = YAMLPropertySourceTest.class.getResource("/configs/valid/test-with-prio.yaml");
-
- assertThat(configURL, CoreMatchers.notNullValue());
-
- YAMLPropertySource source = new YAMLPropertySource(configURL, 4);
- assertEquals(source.getOrdinal(), 16784);
- }
-
- @Test
- public void testYamlDefaultOrdinal() throws Exception {
- URL configURL = YAMLPropertySourceTest.class.getResource("/configs/valid/test.yaml");
-
- assertThat(configURL, CoreMatchers.notNullValue());
-
- YAMLPropertySource source = new YAMLPropertySource(configURL, 4);
- assertEquals(source.getOrdinal(), 4);
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/yaml/src/test/resources/configs/valid/contact.yaml
----------------------------------------------------------------------
diff --git a/modules/yaml/src/test/resources/configs/valid/contact.yaml b/modules/yaml/src/test/resources/configs/valid/contact.yaml
deleted file mode 100644
index 95d5a03..0000000
--- a/modules/yaml/src/test/resources/configs/valid/contact.yaml
+++ /dev/null
@@ -1,46 +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 current 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.
-#
-invoice: 34843
-date : 2001-01-23
-bill-to: &id001
- given : Chris
- family : Dumars
- address:
- lines: |
- 458 Walkman Dr.
- Suite #292
- city : Royal Oak
- state : MI
- postal : 48046
-ship-to: *id001
-product:
- - sku : BL394D
- quantity : 4
- description : Basketball
- price : 450.00
- - sku : BL4438H
- quantity : 1
- description : Super Hoop
- price : 2392.00
-tax : 251.42
-total: 4443.52
-comments: >
- Late afternoon is best.
- Backup contact is Nancy
- Billsmer @ 338-4338.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/yaml/src/test/resources/configs/valid/test-with-prio.yaml
----------------------------------------------------------------------
diff --git a/modules/yaml/src/test/resources/configs/valid/test-with-prio.yaml b/modules/yaml/src/test/resources/configs/valid/test-with-prio.yaml
deleted file mode 100644
index 05b5dbf..0000000
--- a/modules/yaml/src/test/resources/configs/valid/test-with-prio.yaml
+++ /dev/null
@@ -1,39 +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 current 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.
-#
-version: 1.0
-released: 2012-11-30
-
-# tamaya specifics...
-tamaya:
- ordinal: 16784
-
-# Connection parameters
-connection:
- url: jdbc:mysql://localhost:3306/db
- poolSize: 5
-
-# Protocols
-protocols:
- - http
- - https
-
-# Users
-users:
- tom: passwd
- bob: passwd
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/yaml/src/test/resources/configs/valid/test.yaml
----------------------------------------------------------------------
diff --git a/modules/yaml/src/test/resources/configs/valid/test.yaml b/modules/yaml/src/test/resources/configs/valid/test.yaml
deleted file mode 100644
index 697e9f3..0000000
--- a/modules/yaml/src/test/resources/configs/valid/test.yaml
+++ /dev/null
@@ -1,35 +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 current 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.
-#
-version: 1.0
-released: 2012-11-30
-
-# Connection parameters
-connection:
- url: jdbc:mysql://localhost:3306/db
- poolSize: 5
-
-# Protocols
-protocols:
- - http
- - https
-
-# Users
-users:
- tom: passwd
- bob: passwd
\ No newline at end of file
[13/15] incubator-tamaya-extensions git commit: TAMAYA-182:
Streamlined/unified builder API and fixed some bugs popping up during
testing.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/BasePropertySourceTest.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/BasePropertySourceTest.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/BasePropertySourceTest.java
new file mode 100644
index 0000000..96f1c7f
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/BasePropertySourceTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.spisupport;
+
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spi.PropertyValueBuilder;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class BasePropertySourceTest {
+
+ @Test
+ public void testGetOrdinal() {
+
+ PropertySource defaultPropertySource = new BasePropertySource(56) {
+
+ @Override
+ public String getName() {
+ return "testWithDefault";
+ }
+
+ @Override
+ public PropertyValue get(String key) {
+ return null;
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return Collections.emptyMap();
+ }
+ };
+
+ Assert.assertEquals(56, defaultPropertySource.getOrdinal());
+ Assert.assertEquals(1000, new OverriddenOrdinalPropertySource().getOrdinal());
+
+ // propertySource with invalid ordinal
+ Assert.assertEquals(1, new OverriddenInvalidOrdinalPropertySource().getOrdinal());
+ }
+
+ @Test
+ public void testGet() {
+ Assert.assertEquals("1000", new OverriddenOrdinalPropertySource().get(PropertySource.TAMAYA_ORDINAL).get(PropertySource.TAMAYA_ORDINAL));
+ }
+
+ private static class OverriddenOrdinalPropertySource extends BasePropertySource {
+
+ private OverriddenOrdinalPropertySource() {
+ super(250);
+ }
+
+ @Override
+ public String getName() {
+ return "overriddenOrdinal";
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ Map<String, String> map = new HashMap<>(1);
+ map.put(PropertySource.TAMAYA_ORDINAL, "1000");
+ return map;
+ }
+ }
+
+ private static class OverriddenInvalidOrdinalPropertySource extends BasePropertySource {
+
+ private OverriddenInvalidOrdinalPropertySource() {
+ super(1);
+ }
+
+ @Override
+ public String getName() {
+ return "overriddenInvalidOrdinal";
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ Map<String, String> map = new HashMap<>(1);
+ map.put(PropertySource.TAMAYA_ORDINAL, "invalid");
+ return map;
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/C.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/C.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/C.java
new file mode 100644
index 0000000..da581e6
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/C.java
@@ -0,0 +1,56 @@
+/*
+ * 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.spisupport;
+
+import java.io.IOException;
+import java.nio.CharBuffer;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+public class C extends B implements Readable{
+
+ private final String inValue;
+
+ public C(String inValue){
+ this.inValue = inValue;
+ }
+
+ @Override
+ public int read(CharBuffer cb) throws IOException {
+ return 0;
+ }
+
+ /**
+ * Returns the input value, set on creation. Used for test assertion.
+ * @return the in value.
+ */
+ public String getInValue() {
+ return inValue;
+ }
+
+ @Override
+ public String toString() {
+ return "C{" +
+ "inValue='" + inValue + '\'' +
+ '}';
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/CLIPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/CLIPropertySourceTest.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/CLIPropertySourceTest.java
new file mode 100644
index 0000000..2c2baa4
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/CLIPropertySourceTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.core.propertysource.CLIPropertySource;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for PropertySource for reading main arguments as configuration.
+ */
+public class CLIPropertySourceTest {
+
+ @Test
+ public void setCLIProps() throws Exception {
+ System.clearProperty("main.args");
+ CLIPropertySource ps = new CLIPropertySource();
+ assertTrue(ps.getProperties().isEmpty());
+ CLIPropertySource.initMainArgs("-a", "b");
+ assertFalse(ps.getProperties().isEmpty());
+ assertEquals(ps.getProperties().get("a"), "b");
+ CLIPropertySource.initMainArgs("--c");
+ assertFalse(ps.getProperties().isEmpty());
+ assertEquals(ps.getProperties().get("c"), "c");
+ CLIPropertySource.initMainArgs("sss");
+ assertFalse(ps.getProperties().isEmpty());
+ assertEquals(ps.getProperties().get("sss"), "sss");
+ CLIPropertySource.initMainArgs("-a", "b", "--c", "sss", "--val=vvv");
+ assertFalse(ps.getProperties().isEmpty());
+ assertEquals(ps.getProperties().get("a"), "b");
+ assertEquals(ps.getProperties().get("c"), "c");
+ assertEquals(ps.getProperties().get("sss"), "sss");
+ // getProperties() throws Exception {
+ System.setProperty("main.args", "-a b\t--c sss ");
+ ps = new CLIPropertySource();
+ assertFalse(ps.getProperties().isEmpty());
+ System.clearProperty("main.args");
+ assertEquals(ps.getProperties().get("a"), "b");
+ assertEquals(ps.getProperties().get("c"), "c");
+ assertEquals(ps.getProperties().get("sss"), "sss");
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/CTestConverter.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/CTestConverter.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/CTestConverter.java
new file mode 100644
index 0000000..dce8121
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/CTestConverter.java
@@ -0,0 +1,32 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+
+/**
+ * Created by Anatole on 13.06.2015.
+ */
+public class CTestConverter implements PropertyConverter<C>{
+ @Override
+ public C convert(String value, ConversionContext context) {
+ return new C(value);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultConfigurationContextTest.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultConfigurationContextTest.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultConfigurationContextTest.java
new file mode 100644
index 0000000..0e08be4
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/DefaultConfigurationContextTest.java
@@ -0,0 +1,183 @@
+/*
+ * 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.spisupport;
+
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.FilterContext;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Simple tests for {@link DefaultConfigurationContext} by atsticks on 16.08.16.
+ */
+public class DefaultConfigurationContextTest {
+
+ @Test
+ public void addPropertySources() throws Exception {
+ ConfigurationContext ctx = new DefaultConfigurationContextBuilder().build();
+ PropertySource def = new TestPropertyDefaultSource();
+ assertFalse(ctx.getPropertySources().contains(def));
+ ctx.addPropertySources(def);
+ assertTrue(ctx.getPropertySources().contains(def));
+ }
+
+ @Test
+ public void testToString() throws Exception {
+ String toString = ConfigurationProvider.getConfiguration().getContext().toString();
+ System.out.println(toString);
+ }
+
+ @Test
+ public void getPropertySources() throws Exception {
+ ConfigurationContext ctx = new DefaultConfigurationContextBuilder().build();
+ assertNotNull(ctx.getPropertySources());
+ assertEquals(ctx.getPropertySources().size(), 0);
+ ctx = new DefaultConfigurationContextBuilder().loadDefaultPropertySources().build();
+ assertNotNull(ctx.getPropertySources());
+ assertEquals(3, ctx.getPropertySources().size());
+ }
+
+ @Test
+ public void getPropertySource() throws Exception {
+ PropertySource ps = new TestPropertyDefaultSource();
+ ConfigurationContext ctx = new DefaultConfigurationContextBuilder()
+ .addPropertySources(ps).build();
+ assertNotNull(ctx.getPropertySources());
+ assertEquals(ctx.getPropertySources().size(), 1);
+ assertNotNull(((DefaultConfigurationContext)ctx).getPropertySource(ps.getName()));
+ assertEquals(ps.getName(), ((DefaultConfigurationContext)ctx).getPropertySource(ps.getName()).getName());
+ assertNull(((DefaultConfigurationContext)ctx).getPropertySource("huhu"));
+
+ }
+
+ @Test
+ public void testHashCode() throws Exception {
+ PropertySource ps = new TestPropertyDefaultSource();
+ ConfigurationContext ctx1 = new DefaultConfigurationContextBuilder()
+ .addPropertySources(ps).build();
+ ConfigurationContext ctx2 = new DefaultConfigurationContextBuilder()
+ .addPropertySources(ps).build();
+ assertEquals(ctx1.hashCode(), ctx2.hashCode());
+ ctx2 = new DefaultConfigurationContextBuilder()
+ .build();
+ assertNotEquals(ctx1.hashCode(), ctx2.hashCode());
+
+ }
+
+ @Test
+ public void addPropertyConverter() throws Exception {
+ ConfigurationContext ctx = new DefaultConfigurationContextBuilder().build();
+ PropertyConverter testConverter = new PropertyConverter() {
+ @Override
+ public Object convert(String value, ConversionContext context) {
+ return "";
+ }
+ };
+ assertFalse(ctx.getPropertyConverters(TypeLiteral.of(String.class)).contains(testConverter));
+ ctx.addPropertyConverter(TypeLiteral.of(String.class), testConverter);
+ assertTrue(ctx.getPropertyConverters(TypeLiteral.of(String.class)).contains(testConverter));
+ }
+
+ @Test
+ public void getPropertyConverters() throws Exception {
+ ConfigurationContext ctx = new DefaultConfigurationContextBuilder().build();
+ PropertyConverter testConverter = new PropertyConverter() {
+ @Override
+ public Object convert(String value, ConversionContext context) {
+ return "";
+ }
+ };
+ ctx.addPropertyConverter(TypeLiteral.of(String.class), testConverter);
+ assertNotNull(ctx.getPropertyConverters());
+ assertTrue(ctx.getPropertyConverters().containsKey(TypeLiteral.of(String.class)));
+ assertTrue(ctx.getPropertyConverters().get(TypeLiteral.of(String.class)).contains(testConverter));
+ testConverter = new PropertyConverter() {
+ @Override
+ public Object convert(String value, ConversionContext context) {
+ return Integer.valueOf(5);
+ }
+ };
+ ctx.addPropertyConverter(TypeLiteral.of(Integer.class), testConverter);
+ assertTrue(ctx.getPropertyConverters().containsKey(TypeLiteral.of(Integer.class)));
+ assertTrue(ctx.getPropertyConverters().get(TypeLiteral.of(Integer.class)).contains(testConverter));
+ }
+
+ @Test
+ public void getPropertyConverters1() throws Exception {
+ ConfigurationContext ctx = new DefaultConfigurationContextBuilder().build();
+ PropertyConverter testConverter = new PropertyConverter() {
+ @Override
+ public Object convert(String value, ConversionContext context) {
+ return "";
+ }
+ };
+ assertNotNull(ctx.getPropertyConverters(TypeLiteral.of(String.class)));
+ assertEquals(ctx.getPropertyConverters(TypeLiteral.of(String.class)).size(),0);
+ ctx.addPropertyConverter(TypeLiteral.of(String.class), testConverter);
+ assertNotNull(ctx.getPropertyConverters(TypeLiteral.of(String.class)));
+ assertEquals(ctx.getPropertyConverters(TypeLiteral.of(String.class)).size(),1);
+ assertTrue(ctx.getPropertyConverters(TypeLiteral.of(String.class)).contains(testConverter));
+
+ }
+
+ @Test
+ public void getPropertyFilters() throws Exception {
+ ConfigurationContext ctx = new DefaultConfigurationContextBuilder().build();
+ PropertyFilter testFilter = new PropertyFilter() {
+
+ @Override
+ public String filterProperty(String value, FilterContext context) {
+ return value;
+ }
+ };
+ assertNotNull(ctx.getPropertyFilters());
+ assertFalse(ctx.getPropertyFilters().contains(testFilter));
+ ctx = ctx.toBuilder().addPropertyFilters(testFilter).build();
+ assertTrue(ctx.getPropertyFilters().contains(testFilter));
+ }
+
+ @Test
+ public void getPropertyValueCombinationPolicy() throws Exception {
+ ConfigurationContext ctx = new DefaultConfigurationContextBuilder().build();
+ assertNotNull(ctx.getPropertyValueCombinationPolicy());
+ assertEquals(ctx.getPropertyValueCombinationPolicy(),
+ PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR);
+ }
+
+ @Test
+ public void toBuilder() throws Exception {
+ assertNotNull(new DefaultConfigurationContextBuilder().build().toBuilder());
+ }
+
+ @Test
+ public void testRoundTrip() throws Exception {
+ ConfigurationContext ctx = new DefaultConfigurationContextBuilder().build();
+ assertEquals(ctx.toBuilder().build(), ctx);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/EnumConverterTest.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/EnumConverterTest.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/EnumConverterTest.java
new file mode 100644
index 0000000..c846e81
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/EnumConverterTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConversionContext;
+import org.junit.Test;
+
+import java.math.RoundingMode;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Test class testing the {@link EnumConverter} class.
+ */
+public class EnumConverterTest {
+
+ private final EnumConverter testConverter = new EnumConverter(RoundingMode.class);
+
+ private final ConversionContext DUMMY_CONTEXT = new ConversionContext.Builder("someKey", TypeLiteral.of(Enum.class)).build();
+
+ @Test
+ public void testConvert() {
+ assertEquals(testConverter.convert(RoundingMode.CEILING.toString(),
+ DUMMY_CONTEXT), RoundingMode.CEILING);
+ }
+
+ @Test
+ public void testConvert_LowerCase() {
+ assertEquals(testConverter.convert("ceiling", DUMMY_CONTEXT), RoundingMode.CEILING);
+ }
+
+ @Test
+ public void testConvert_MixedCase() {
+ assertEquals(testConverter.convert("CeiLinG", DUMMY_CONTEXT), RoundingMode.CEILING);
+ }
+
+ @Test
+ public void testConvert_OtherValue() {
+ assertNull(testConverter.convert("fooBars", DUMMY_CONTEXT));
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/EnvironmentPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/EnvironmentPropertySourceTest.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/EnvironmentPropertySourceTest.java
new file mode 100644
index 0000000..a7f0497
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/EnvironmentPropertySourceTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.core.propertysource.EnvironmentPropertySource;
+import org.junit.Test;
+
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for {@link EnvironmentPropertySource}.
+ */
+public class EnvironmentPropertySourceTest {
+
+ private final EnvironmentPropertySource envPropertySource = new EnvironmentPropertySource();
+
+ @Test
+ public void testGetOrdinal() throws Exception {
+ assertEquals(EnvironmentPropertySource.DEFAULT_ORDINAL, envPropertySource.getOrdinal());
+ }
+
+ @Test
+ public void testGetName() throws Exception {
+ assertEquals("environment-properties", envPropertySource.getName());
+ }
+
+ @Test
+ public void testGet() throws Exception {
+ for (Map.Entry<String, String> envEntry : System.getenv().entrySet()) {
+ assertEquals(envPropertySource.get(envEntry.getKey()).get(envEntry.getKey()), envEntry.getValue());
+ }
+ }
+
+ @Test
+ public void testGetProperties() throws Exception {
+ Map<String, String> props = envPropertySource.getProperties();
+ for(Map.Entry<String,String> en: props.entrySet()){
+ if(!en.getKey().startsWith("_")){
+ assertEquals(System.getenv(en.getKey()), en.getValue());
+ }
+ }
+ }
+
+ @Test
+ public void testIsScannable() throws Exception {
+ assertTrue(envPropertySource.isScannable());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/PriorityServiceComparatorTest.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/PriorityServiceComparatorTest.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/PriorityServiceComparatorTest.java
new file mode 100644
index 0000000..846e283
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/PriorityServiceComparatorTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.spisupport;
+
+import org.junit.Test;
+
+import javax.annotation.Priority;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by atsticks on 12.09.16.
+ */
+public class PriorityServiceComparatorTest {
+
+ private PriorityServiceComparator comp = new PriorityServiceComparator();
+
+ @Test
+ public void compare() throws Exception {
+ assertTrue(comp.compare("a", "b")==0);
+ assertTrue(comp.compare(getClass(), getClass())==0);
+ assertTrue(comp.compare(new A(), new SystemPropertySource())==-1);
+ assertTrue(comp.compare(new SystemPropertySource(), new A())==1);
+ }
+
+ @Priority(100)
+ private static final class A{}
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertiesFilePropertySourceTest.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertiesFilePropertySourceTest.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertiesFilePropertySourceTest.java
new file mode 100644
index 0000000..889e905
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertiesFilePropertySourceTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.core.propertysource.SimplePropertySource;
+import org.apache.tamaya.spi.PropertySource;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PropertiesFilePropertySourceTest {
+
+ private final SimplePropertySource testfilePropertySource = new SimplePropertySource(Thread.currentThread()
+ .getContextClassLoader().getResource("testfile.properties"));
+ private final SimplePropertySource overrideOrdinalPropertySource = new SimplePropertySource(
+ Thread.currentThread().getContextClassLoader().getResource("overrideOrdinal.properties"));
+
+
+ @Test
+ public void testGetOrdinal() {
+ Assert.assertEquals(0, testfilePropertySource.getOrdinal());
+ Assert.assertEquals(Integer.parseInt(overrideOrdinalPropertySource.get(PropertySource.TAMAYA_ORDINAL)
+ .get(PropertySource.TAMAYA_ORDINAL)),
+ overrideOrdinalPropertySource.getOrdinal());
+ }
+
+
+ @Test
+ public void testGet() {
+ Assert.assertEquals("val3", testfilePropertySource.get("key3").get("key3"));
+ Assert.assertEquals("myval5", overrideOrdinalPropertySource.get("mykey5").get("mykey5"));
+ Assert.assertNull(testfilePropertySource.get("nonpresentkey"));
+ }
+
+
+ @Test
+ public void testGetProperties() throws Exception {
+ Assert.assertEquals(5, testfilePropertySource.getProperties().size());
+ Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key1"));
+ Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key2"));
+ Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key3"));
+ Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key4"));
+ Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key5"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertyConverterManagerTest.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertyConverterManagerTest.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertyConverterManagerTest.java
new file mode 100644
index 0000000..45ecc9d
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/PropertyConverterManagerTest.java
@@ -0,0 +1,180 @@
+/*
+ * 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.spisupport;
+
+
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.TypeLiteral;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+
+public class PropertyConverterManagerTest {
+
+ private final ConversionContext DUMMY_CONTEXT = new ConversionContext.Builder(
+ "someKey", TypeLiteral.of(Object.class)).build();
+
+ @Test
+ public void customTypeWithFactoryMethodOfIsRecognizedAsSupported() {
+ PropertyConverterManager manager = new PropertyConverterManager();
+
+ assertThat(manager.isTargetTypeSupported(TypeLiteral.of(MyType.class)),
+ is(true));
+ }
+
+ @Test
+ public void factoryMethodOfIsUsedAsConverter() {
+ PropertyConverterManager manager = new PropertyConverterManager();
+
+ List<PropertyConverter<MyType>> converters = manager.getPropertyConverters(
+ (TypeLiteral)TypeLiteral.of(MyType.class));
+
+ assertThat(converters, hasSize(1));
+
+ PropertyConverter<MyType> converter = converters.get(0);
+
+ Object result = converter.convert("IN", DUMMY_CONTEXT);
+
+ assertThat(result, notNullValue());
+ assertThat(result, instanceOf(MyType.class));
+ assertThat(((MyType)result).getValue(), equalTo("IN"));
+ }
+
+ @Test
+ public void testDirectConverterMapping(){
+ PropertyConverterManager manager = new PropertyConverterManager();
+ List<PropertyConverter<C>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(C.class)));
+ assertThat(converters, hasSize(1));
+
+ PropertyConverter<C> converter = converters.get(0);
+ C result = converter.convert("testDirectConverterMapping", DUMMY_CONTEXT);
+
+ assertThat(result, notNullValue());
+ assertThat(result, instanceOf(C.class));
+ assertThat((result).getInValue(), equalTo("testDirectConverterMapping"));
+ }
+
+ @Test
+ public void testDirectSuperclassConverterMapping(){
+ PropertyConverterManager manager = new PropertyConverterManager();
+ List<PropertyConverter<B>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(B.class)));
+ assertThat(converters, hasSize(1));
+ converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(B.class)));
+ assertThat(converters, hasSize(1));
+
+ PropertyConverter<B> converter = converters.get(0);
+ B result = converter.convert("testDirectSuperclassConverterMapping", DUMMY_CONTEXT);
+
+ assertThat(result, notNullValue());
+ assertThat(result, instanceOf(C.class));
+ assertThat(((C)result).getInValue(), equalTo("testDirectSuperclassConverterMapping"));
+ }
+
+ @Test
+ public void testMultipleConverterLoad(){
+ PropertyConverterManager manager = new PropertyConverterManager();
+ List<PropertyConverter<B>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(B.class)));
+ assertThat(converters, hasSize(1));
+ manager = new PropertyConverterManager();
+ converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(B.class)));
+ assertThat(converters, hasSize(1));
+ }
+
+ @Test
+ public void testTransitiveSuperclassConverterMapping(){
+ PropertyConverterManager manager = new PropertyConverterManager();
+ List<PropertyConverter<A>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(A.class)));
+ assertThat(converters, hasSize(1));
+
+ PropertyConverter<A> converter = converters.get(0);
+ A result = converter.convert("testTransitiveSuperclassConverterMapping", DUMMY_CONTEXT);
+
+ assertThat(result, notNullValue());
+ assertThat(result, instanceOf(C.class));
+ assertThat(((C)result).getInValue(), equalTo("testTransitiveSuperclassConverterMapping"));
+ }
+
+ @Test
+ public void testDirectInterfaceMapping(){
+ PropertyConverterManager manager = new PropertyConverterManager();
+ List<PropertyConverter<Readable>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(Readable.class)));
+ assertThat(converters, hasSize(1));
+
+ PropertyConverter<Readable> converter = converters.get(0);
+ Readable result = converter.convert("testDirectInterfaceMapping", DUMMY_CONTEXT);
+
+ assertThat(result, notNullValue());
+ assertThat(result, instanceOf(C.class));
+ assertThat(((C)result).getInValue(), equalTo("testDirectInterfaceMapping"));
+ }
+
+ @Test
+ public void testTransitiveInterfaceMapping1(){
+ PropertyConverterManager manager = new PropertyConverterManager();
+ List<PropertyConverter<Runnable>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(Runnable.class)));
+ assertThat(converters, hasSize(1));
+
+ PropertyConverter<Runnable> converter = converters.get(0);
+ Runnable result = converter.convert("testTransitiveInterfaceMapping1", DUMMY_CONTEXT);
+
+ assertThat(result, notNullValue());
+ assertThat(result, instanceOf(C.class));
+ assertThat(((C)result).getInValue(), equalTo("testTransitiveInterfaceMapping1"));
+ }
+
+ @Test
+ public void testTransitiveInterfaceMapping2(){
+ PropertyConverterManager manager = new PropertyConverterManager();
+ List<PropertyConverter<AutoCloseable>> converters = List.class.cast(manager.getPropertyConverters(TypeLiteral.of(AutoCloseable.class)));
+ assertThat(converters, hasSize(1));
+
+ PropertyConverter<AutoCloseable> converter = converters.get(0);
+ AutoCloseable result = converter.convert("testTransitiveInterfaceMapping2", DUMMY_CONTEXT);
+
+ assertThat(result, notNullValue());
+ assertThat(result, instanceOf(C.class));
+ assertThat(((C)result).getInValue(), equalTo("testTransitiveInterfaceMapping2"));
+ }
+
+ public static class MyType {
+ private final String typeValue;
+
+ private MyType(String value) {
+ typeValue = value;
+ }
+
+ public static MyType of(String source) {
+ return new MyType(source);
+ }
+
+ public String getValue() {
+ return typeValue;
+ }
+
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/SimplePropertySourceTest.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/SimplePropertySourceTest.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/SimplePropertySourceTest.java
new file mode 100644
index 0000000..e199609
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/SimplePropertySourceTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.ConfigException;
+import org.junit.Test;
+
+import java.net.URL;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.aMapWithSize;
+import static org.hamcrest.Matchers.hasEntry;
+
+public class SimplePropertySourceTest {
+ @Test
+ public void successfulCreationWithPropertiesFromXMLPropertiesFile() {
+ URL resource = getClass().getResource("/valid-properties.xml");
+
+ SimplePropertySource source = new SimplePropertySource(resource);
+
+ assertThat(source, notNullValue());
+ assertThat(source.getProperties(), aMapWithSize(2));
+ assertThat(source.getProperties(), hasEntry("a", "b"));
+ assertThat(source.getProperties(), hasEntry("b", "1"));
+
+ }
+
+ @Test
+ public void failsToCreateFromNonXMLPropertiesXMLFile() {
+ URL resource = getClass().getResource("/non-xml-properties.xml");
+ ConfigException catchedException = null;
+
+ try {
+ new SimplePropertySource(resource);
+ } catch (ConfigException ce) {
+ catchedException = ce;
+ }
+
+ assertThat(catchedException.getMessage(), allOf(startsWith("Error loading properties from"),
+ endsWith("non-xml-properties.xml")));
+ }
+
+ @Test
+ public void failsToCreateFromInvalidPropertiesXMLFile() {
+ URL resource = getClass().getResource("/invalid-properties.xml");
+ ConfigException catchedException = null;
+
+ try {
+ new SimplePropertySource(resource);
+ } catch (ConfigException ce) {
+ catchedException = ce;
+ }
+
+ assertThat(catchedException.getMessage(), allOf(startsWith("Error loading properties from"),
+ endsWith("invalid-properties.xml")));
+ }
+
+
+ @Test
+ public void successfulCreationWithPropertiesFromSimplePropertiesFile() {
+ URL resource = getClass().getResource("/testfile.properties");
+
+ SimplePropertySource source = new SimplePropertySource(resource);
+
+ assertThat(source, notNullValue());
+ assertThat(source.getProperties(), aMapWithSize(5));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/SystemPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/SystemPropertySourceTest.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/SystemPropertySourceTest.java
new file mode 100644
index 0000000..54e970c
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/SystemPropertySourceTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.core.propertysource.SystemPropertySource;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Map;
+import java.util.Properties;
+
+public class SystemPropertySourceTest {
+
+ private final SystemPropertySource testPropertySource = new SystemPropertySource();
+
+
+ @Test
+ public void testGetOrdinal() throws Exception {
+
+ // test the default ordinal
+ Assert.assertEquals(SystemPropertySource.DEFAULT_ORDINAL, testPropertySource.getOrdinal());
+
+ // set the ordinal to 1000
+ System.setProperty(PropertySource.TAMAYA_ORDINAL, "1000");
+ Assert.assertEquals(1000, new SystemPropertySource().getOrdinal());
+ // currently its not possible to change ordinal at runtime
+
+ // reset it to not destroy other tests!!
+ System.clearProperty(PropertySource.TAMAYA_ORDINAL);
+ }
+
+ @Test
+ public void testGetName() throws Exception {
+ Assert.assertEquals("system-properties", testPropertySource.getName());
+ }
+
+ @Test
+ public void testGet() throws Exception {
+ String propertyKeyToCheck = System.getProperties().stringPropertyNames().iterator().next();
+
+ PropertyValue property = testPropertySource.get(propertyKeyToCheck);
+ Assert.assertNotNull("Property '" + propertyKeyToCheck + "' is not present in " +
+ SystemPropertySource.class.getSimpleName(), property);
+ Assert.assertEquals(System.getProperty(propertyKeyToCheck), property.getValue());
+ }
+
+ @Test
+ public void testGetProperties() throws Exception {
+ checkWithSystemProperties(testPropertySource.getProperties());
+
+ // modify system properties
+ System.setProperty("test", "myTestVal");
+
+ checkWithSystemProperties(testPropertySource.getProperties());
+
+ // cleanup
+ System.clearProperty("test");
+
+ // no modifaction
+ try {
+ testPropertySource.getProperties().put("add.new.keys", "must throw exception");
+ Assert.fail(UnsupportedOperationException.class.getName() + " expected");
+ }
+ catch (UnsupportedOperationException e) {
+ // expected -> all is fine
+ }
+ }
+
+ private void checkWithSystemProperties(Map<String, String> toCheck) {
+ Properties systemEntries = System.getProperties();
+
+ Assert.assertEquals("size of System.getProperties().entrySet() must be the same as SystemPropertySrouce.getProperties().entrySet()",
+ systemEntries.size(), toCheck.size()/2);
+
+ for (Map.Entry<String, String> propertySourceEntry : toCheck.entrySet()) {
+ if(propertySourceEntry.getKey().startsWith("_")){
+ continue; // meta entry
+ }
+ Assert.assertEquals("Entry values for key '" + propertySourceEntry.getKey() + "' do not match",
+ systemEntries.getProperty(propertySourceEntry.getKey()), propertySourceEntry.getValue());
+ }
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/TestPropertyDefaultSource.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/TestPropertyDefaultSource.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/TestPropertyDefaultSource.java
new file mode 100644
index 0000000..f55d8e4
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/TestPropertyDefaultSource.java
@@ -0,0 +1,56 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.core.propertysource.BasePropertySource;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Test provider reading properties from classpath:cfg/defaults/**.properties.
+ */
+public class TestPropertyDefaultSource extends BasePropertySource{
+
+ private Map<String,String> properties = new HashMap<>();
+
+ public TestPropertyDefaultSource() {
+ super(100);
+ properties.put("name","Anatole");
+ properties.put("name2","Sabine");
+ properties = Collections.unmodifiableMap(properties);
+ }
+
+ @Override
+ public String getName() {
+ return "default-testdata-properties";
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ @Override
+ public boolean isScannable() {
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter b/modules/spi-support/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
new file mode 100644
index 0000000..ff5d32c
--- /dev/null
+++ b/modules/spi-support/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyConverter
@@ -0,0 +1,38 @@
+#
+# 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.
+#
+
+#
+# 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 current 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.
+#
+org.apache.tamaya.spisupport.CTestConverter
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/resources/invalid-properties.xml
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/resources/invalid-properties.xml b/modules/spi-support/src/test/resources/invalid-properties.xml
new file mode 100644
index 0000000..d8b10b7
--- /dev/null
+++ b/modules/spi-support/src/test/resources/invalid-properties.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+ <entry key="a">
+ <entry key="b">1</entry>
+</properties>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/resources/non-xml-properties.xml
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/resources/non-xml-properties.xml b/modules/spi-support/src/test/resources/non-xml-properties.xml
new file mode 100644
index 0000000..8de819a
--- /dev/null
+++ b/modules/spi-support/src/test/resources/non-xml-properties.xml
@@ -0,0 +1,18 @@
+<!--
+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.
+-->
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/resources/overrideOrdinal.properties
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/resources/overrideOrdinal.properties b/modules/spi-support/src/test/resources/overrideOrdinal.properties
new file mode 100644
index 0000000..96935a8
--- /dev/null
+++ b/modules/spi-support/src/test/resources/overrideOrdinal.properties
@@ -0,0 +1,25 @@
+# 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.
+
+#override ordinal
+tamaya.ordinal=16784
+
+mykey1=myval1
+mykey2=myval2
+mykey3=myval3
+mykey4=myval4
+mykey5=myval5
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/resources/testfile.properties
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/resources/testfile.properties b/modules/spi-support/src/test/resources/testfile.properties
new file mode 100644
index 0000000..abd7ee8
--- /dev/null
+++ b/modules/spi-support/src/test/resources/testfile.properties
@@ -0,0 +1,22 @@
+# 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.
+
+key1=val1
+key2=val2
+key3=val3
+key4=val4
+key5=val5
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/resources/valid-properties.xml
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/resources/valid-properties.xml b/modules/spi-support/src/test/resources/valid-properties.xml
new file mode 100644
index 0000000..7eb51d9
--- /dev/null
+++ b/modules/spi-support/src/test/resources/valid-properties.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+ <entry key="a">b</entry>
+ <entry key="b">1</entry>
+</properties>
[06/15] incubator-tamaya-extensions git commit: TAMAYA-189: Moved
format and injection modules into separate subtrees.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/ConfiguredTest.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/ConfiguredTest.java b/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/ConfiguredTest.java
new file mode 100644
index 0000000..69e8ef9
--- /dev/null
+++ b/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/ConfiguredTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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 current 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.integration.cdi;
+
+import org.apache.deltaspike.testcontrol.api.TestControl;
+import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner;
+import org.hamcrest.MatcherAssert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.spi.CDI;
+import javax.inject.Singleton;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for CDI integration.
+ */
+@RunWith(CdiTestRunner.class)
+@TestControl(startScopes = {ApplicationScoped.class, Singleton.class})
+public class ConfiguredTest{
+
+ @Test
+ public void test_Configuration_is_injected_correctly(){
+ ConfiguredClass item = CDI.current().select(ConfiguredClass.class).get();
+ System.out.println("********************************************");
+ System.out.println(item);
+ System.out.println("********************************************");
+ double actual = 1234.5678;
+ MatcherAssert.assertThat(item.getDoubleValue(), is(actual));
+ }
+
+ @Test
+ public void test_Default_injections_are_accessible(){
+ InjectedClass injectedClass = CDI.current().select(InjectedClass.class).get();
+ System.out.println("********************************************");
+ System.out.println(injectedClass);
+ System.out.println("********************************************");
+ assertNotNull(injectedClass.builder1);
+ assertNotNull(injectedClass.builder2);
+ assertNotNull(injectedClass.config);
+ assertNotNull(injectedClass.configContext);
+ }
+
+ @Test
+ public void test_Injected_builders_are_notSame(){
+ InjectedClass injectedClass = CDI.current().select(InjectedClass.class).get();
+ assertTrue(injectedClass.builder1 != injectedClass.builder2);
+ }
+
+ @Test
+ public void test_Injected_configs_are_same(){
+ InjectedClass injectedClass = CDI.current().select(InjectedClass.class).get();
+ assertTrue(injectedClass.config == injectedClass.config2);
+ }
+
+ @Test
+ public void test_Injected_configContexts_are_same(){
+ InjectedClass injectedClass = CDI.current().select(InjectedClass.class).get();
+ assertTrue(injectedClass.configContext == injectedClass.configContext2);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/InjectedClass.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/InjectedClass.java b/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/InjectedClass.java
new file mode 100644
index 0000000..9b7bd23
--- /dev/null
+++ b/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/InjectedClass.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 current 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.integration.cdi;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Class loaded by CDI to test correct injection of Configuration API artifacts.
+ */
+@Singleton
+public class InjectedClass {
+
+ @Inject
+ Configuration config;
+
+ @Inject
+ Configuration config2;
+
+ @Inject
+ ConfigurationContext configContext;
+
+ @Inject
+ ConfigurationContext configContext2;
+
+ @Inject
+ ConfigurationContextBuilder builder1;
+
+ @Inject
+ ConfigurationContextBuilder builder2;
+
+ @Override
+ public String toString() {
+ return "InjectedClass{" +
+ "config=" + config +
+ ", configContext=" + configContext +
+ ", builder1=" + builder1 +
+ ", builder2=" + builder2 +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/cfg/ProvidedPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/cfg/ProvidedPropertySource.java b/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/cfg/ProvidedPropertySource.java
new file mode 100644
index 0000000..f7e3c6d
--- /dev/null
+++ b/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/cfg/ProvidedPropertySource.java
@@ -0,0 +1,67 @@
+/*
+ * 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 current 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.integration.cdi.cfg;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import javax.enterprise.inject.Vetoed;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by Anatole on 17.09.2015.
+ */
+@Vetoed
+class ProvidedPropertySource implements PropertySource{
+
+ final Map<String,String> config = new HashMap<>();
+
+ public ProvidedPropertySource(){
+ config.put("a.b.c.key3", "keys current a.b.c.key3");
+ config.put("a.b.c.key4", "keys current a.b.c.key4");
+ config.put("{meta}source.type:"+getClass().getName(), "PropertySourceProvider");
+ }
+
+ @Override
+ public int getOrdinal() {
+ return 10;
+ }
+
+ @Override
+ public String getName() {
+ return getClass().getName();
+ }
+
+ @Override
+ public PropertyValue get(String key) {
+ return PropertyValue.of(key, config.get(key), getName());
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return config;
+ }
+
+ @Override
+ public boolean isScannable() {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/cfg/TestConfigProvider.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/cfg/TestConfigProvider.java b/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/cfg/TestConfigProvider.java
new file mode 100644
index 0000000..7b89fba
--- /dev/null
+++ b/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/cfg/TestConfigProvider.java
@@ -0,0 +1,45 @@
+/*
+ * 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 current 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.integration.cdi.cfg;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertySourceProvider;
+
+import javax.enterprise.context.ApplicationScoped;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Created by Anatole on 29.09.2014.
+ */
+@ApplicationScoped
+public class TestConfigProvider implements PropertySourceProvider {
+
+ private List<PropertySource> configs = new ArrayList<>();
+
+ public TestConfigProvider(){
+ configs.add(new ProvidedPropertySource());
+ }
+
+ @Override
+ public Collection<PropertySource> getPropertySources() {
+ return configs;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/cfg/TestPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/cfg/TestPropertySource.java b/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/cfg/TestPropertySource.java
new file mode 100644
index 0000000..75c55ca
--- /dev/null
+++ b/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/cfg/TestPropertySource.java
@@ -0,0 +1,79 @@
+/*
+ * 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 current 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.integration.cdi.cfg;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import javax.inject.Singleton;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by Anatole on 17.09.2015.
+ */
+@Singleton
+public class TestPropertySource implements PropertySource{
+
+ final Map<String,String> config = new HashMap<>();
+
+ public TestPropertySource(){
+ config.put("a.b.c.key1", "keys current a.b.c.key1");
+ config.put("a.b.c.key2", "keys current a.b.c.key2");
+ config.put("a.b.key3", "keys current a.b.key3");
+ config.put("a.b.key4", "keys current a.b.key4");
+ config.put("a.key5", "keys current a.key5");
+ config.put("a.key6", "keys current a.key6");
+ config.put("int1", "123456");
+ config.put("int2", "111222");
+ config.put("testProperty", "testPropertyValue!");
+ config.put("booleanT", "true");
+ config.put("double1", "1234.5678");
+ config.put("BD", "123456789123456789123456789123456789.123456789123456789123456789123456789");
+ config.put("testProperty", "keys current testProperty");
+ config.put("runtimeVersion", "${java.version}");
+ config.put("{meta}source.type:"+getClass().getName(), "PropertySource");
+ }
+
+ @Override
+ public int getOrdinal() {
+ return 10;
+ }
+
+ @Override
+ public String getName() {
+ return getClass().getName();
+ }
+
+ @Override
+ public PropertyValue get(String key) {
+ return PropertyValue.of(key, config.get(key), getName());
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return config;
+ }
+
+ @Override
+ public boolean isScannable() {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/test/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/test/resources/META-INF/beans.xml b/modules/injection/cdi-se/src/test/resources/META-INF/beans.xml
new file mode 100644
index 0000000..adee378
--- /dev/null
+++ b/modules/injection/cdi-se/src/test/resources/META-INF/beans.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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 current 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.
+-->
+<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd">
+
+</beans>
+
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/test/resources/META-INF/javaconfiguration.properties
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/test/resources/META-INF/javaconfiguration.properties b/modules/injection/cdi-se/src/test/resources/META-INF/javaconfiguration.properties
new file mode 100644
index 0000000..362ce0b
--- /dev/null
+++ b/modules/injection/cdi-se/src/test/resources/META-INF/javaconfiguration.properties
@@ -0,0 +1,20 @@
+# 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.
+#
+double1=1234.5678
+int2=13
+booleanT=y
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/pom.xml
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/pom.xml b/modules/injection/injection-api/pom.xml
new file mode 100644
index 0000000..32e300d
--- /dev/null
+++ b/modules/injection/injection-api/pom.xml
@@ -0,0 +1,81 @@
+<!--
+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 current 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-injection-all</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>tamaya-injection-api</artifactId>
+ <name>Apache Tamaya Modules - Injection API</name>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <jdkVersion>1.7</jdkVersion>
+ <geronimo-atinject-1.0-spec.version>1.0</geronimo-atinject-1.0-spec.version>
+ <geronimo-jcdi-1.1-spec.version>1.0</geronimo-jcdi-1.1-spec.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-atinject_1.0_spec</artifactId>
+ <version>${geronimo-atinject-1.0-spec.version}</version>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jcdi_1.1_spec</artifactId>
+ <version>${geronimo-jcdi-1.1-spec.version}</version>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.tamaya.inject.api,
+ org.apache.tamaya.inject.spi
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/BaseDynamicValue.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/BaseDynamicValue.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/BaseDynamicValue.java
new file mode 100644
index 0000000..2f8c559
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/BaseDynamicValue.java
@@ -0,0 +1,125 @@
+/*
+ * 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.api;
+
+
+import java.io.Serializable;
+
+/**
+ * <p>A accessor for a single configured value. This can be used to support values that may change during runtime,
+ * reconfigured or final. Hereby external code (could be Tamaya configuration listners or client code), can set a
+ * new value. Depending on the {@link UpdatePolicy} the new value is immedeately active or it requires an active commit
+ * by client code. Similarly an instance also can ignore all later changes to the value.</p>
+ *
+ * <p>Types of this interface can be used as injection targets in injected beans or as template resiult on configuration
+ * templates.</p>
+ *
+ * <h3>Implementation Specification</h3>
+ * Implementation of this interface must be
+ * <ul>
+ * <li>Serializable, when also the item stored is serializable</li>
+ * <li>Thread safe</li>
+ * </ul>
+ *
+ * @param <T> The type of the value.
+ */
+public abstract class BaseDynamicValue<T> implements DynamicValue<T>, Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Performs a commit, if necessary, and returns the current value.
+ *
+ * @return the non-null value held by this {@code DynamicValue}
+ * @throws org.apache.tamaya.ConfigException if there is no value present
+ * @see DynamicValue#isPresent()
+ */
+ public T commitAndGet() {
+ commit();
+ return get();
+ }
+
+ /**
+ * Return {@code true} if there is a value present, otherwise {@code false}.
+ *
+ * @return {@code true} if there is a value present, otherwise {@code false}
+ */
+ public boolean isPresent() {
+ return get() != null;
+ }
+
+
+ /**
+ * Return the value if present, otherwise return {@code other}.
+ *
+ * @param other the value to be returned if there is no value present, may
+ * be null
+ * @return the value, if present, otherwise {@code other}
+ */
+ public T orElse(T other) {
+ T value = get();
+ if (value == null) {
+ return other;
+ }
+ return value;
+ }
+
+ /**
+ * Return the value if present, otherwise invoke {@code other} and return
+ * the result of that invocation.
+ *
+ * @param other a {@code ConfiguredItemSupplier} whose result is returned if no value
+ * is present
+ * @return the value if present otherwise the result of {@code other.get()}
+ * @throws NullPointerException if value is not present and {@code other} is
+ * null
+ */
+ public T orElseGet(ConfiguredItemSupplier<? extends T> other) {
+ T value = get();
+ if (value == null) {
+ return other.get();
+ }
+ return value;
+ }
+
+ /**
+ * Return the contained value, if present, otherwise throw an exception
+ * to be created by the provided supplier.
+ * <p>
+ * NOTE A method reference to the exception constructor with an empty
+ * argument list can be used as the supplier. For example,
+ * {@code IllegalStateException::new}
+ *
+ * @param <X> Type of the exception to be thrown
+ * @param exceptionSupplier The supplier which will return the exception to
+ * be thrown
+ * @return the present value
+ * @throws X if there is no value present
+ * @throws NullPointerException if no value is present and
+ * {@code exceptionSupplier} is null
+ */
+ public <X extends Throwable> T orElseThrow(ConfiguredItemSupplier<? extends X> exceptionSupplier) throws X {
+ T value = get();
+ if (value == null) {
+ throw exceptionSupplier.get();
+ }
+ return value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/Config.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/Config.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/Config.java
new file mode 100644
index 0000000..2484934
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/Config.java
@@ -0,0 +1,93 @@
+/*
+ * 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.api;
+
+
+import javax.enterprise.util.Nonbinding;
+import javax.inject.Qualifier;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** todo The author of this should fix this invalid Javadoc. Oliver B. Fischer, 2015-12-27 */
+///**
+// * Annotation to enable injection current a configured property or define the returned data for
+// * a configuration template method. Hereby this annotation can be used in multiple ways and combined
+// * with other annotations such as {@link ConfigDefault}, {@link WithConfigOperator}, {@link WithPropertyConverter}.
+// *
+// * Below the most simple variant current a configured class is given:
+// * {@code
+// * pubic class ConfiguredItem{
+// *
+// * @ConfiguredProperty
+// * private String aValue;
+// * }
+// * When this class is configured, e.g. by passing it to {@link org.apache.tamaya.Configuration#configure(Object)},
+// * the following is happening:
+// * <ul>
+// * <li>The current valid Configuration is evaluated by calling {@code Configuration cfg = ConfigurationProvider.getConfiguration();}</li>
+// * <li>The current possible property keys are evaluated by calling {@code cfg.get("aValue");}</li>
+// * <li>if not successful, and a @ConfigDefault annotation is present, the default value is used.
+// * <li>If no value could be evaluated a ({@link org.apache.tamaya.ConfigException} is thrown.</li>
+// * <li>On success, since no type conversion is involved, the value is injected.</li>
+// * </ul>
+// *
+// * In the next example we explicitly define the property keys:
+// * {@code
+// * @ConfigDefaultSections("section1")
+// * pubic class ConfiguredItem{
+// *
+// * @ConfiguredProperty({"b", "[a.b.deprecated.keys]", "a"})
+// * @ConfigDefault("myDefaultValue")
+// * private String aValue;
+// * }
+// *
+// * Within this example we evaluate multiple possible keys (section1.b, a.b.deprecated.keys, section1.a). Evaluation is
+// * aborted if a key could be successfully resolved. Hereby the ordering current the annotations define the ordering
+// * current resolution, so in the example above
+// * resolution equals to {@code "section1.b", "a.b.deprecated.keys", "section1.a"}. If no value has bee found,
+// * the configured default {@code myDefaultValue} is returned.
+// */
+@Qualifier
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
+public @interface Config {
+
+ /**
+ * Get the property names to be used. Hereby the first non null keys evaluated is injected as property keys.
+ *
+ * @return the property names, not null. If missing the field or method name being injected is used by default.
+ */
+ @Nonbinding
+ String[] value() default {};
+
+ /**
+ * The default value to be injected, if none of the configuration keys could be resolved. If no key has been
+ * resolved and no default value is defined, it is handled as a deployment error. Depending on the extension loaded
+ * default values can be fixed Strings or even themselves resolvable. For typed configuration of type T entries
+ * that are not Strings the default value must be a valid input to the corresponding
+ * {@link org.apache.tamaya.spi.PropertyConverter}.
+ *
+ * @return default value used in case resolution fails.
+ */
+ @Nonbinding
+ String defaultValue() default "";
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigAutoInject.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigAutoInject.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigAutoInject.java
new file mode 100644
index 0000000..1ed659e
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigAutoInject.java
@@ -0,0 +1,36 @@
+/*
+ * 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.api;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to control injection of a configured bean. The configuration keys
+ * to be resolved are basically determined by the {@link Config}
+ * annotation(s). When this annotation is added the injection systems tries to inject all
+ * fields found, also including fields not annotated with {@code @ConfigProperty}.
+ * Fields not to be injected ccan be annotated with {@code @NoConfig} to exclude them
+ * being eleceted for injection.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.TYPE })
+public @interface ConfigAutoInject {}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigDefaultSections.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigDefaultSections.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigDefaultSections.java
new file mode 100644
index 0000000..2037de6
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigDefaultSections.java
@@ -0,0 +1,44 @@
+/*
+ * 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.api;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** todo The author of this should fix this invalid Javadoc. Oliver B. Fischer, 2015-12-27 */
+///**
+// * Annotation to control injection and resolution current a configured bean. The configuration keys
+// * to be resolved are basically determined by the {@link org.apache.tamaya.inject.ConfigProperty}
+// * annotation(s). Nevertheless these annotations can also have relative key names. This annotation allows
+// * to define a configuration area that is prefixed to all relative configuration keys within the
+// * corresponding class/template interface.
+// */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.TYPE })
+public @interface ConfigDefaultSections {
+
+ /**
+ * Allows to declare an section names that are prepended to resolve relative configuration keys.
+ * @return the section names to used for key resolution.
+ */
+ String[] value() default {};
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfiguredItemSupplier.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfiguredItemSupplier.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfiguredItemSupplier.java
new file mode 100644
index 0000000..5e57121
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfiguredItemSupplier.java
@@ -0,0 +1,41 @@
+/*
+ * 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.api;
+
+/**
+ * Represents a supplier of results.
+ *
+ * There is no requirement that a new or distinct result be returned each
+ * time the supplier is invoked.
+ *
+ * This is a functional interface,
+ * whose functional method is {@link #get()}.
+ *
+ * @param <T> the type of results supplied by this supplier
+ */
+//@FunctionalInterface
+public interface ConfiguredItemSupplier<T> {
+
+ /**
+ * Gets a result.
+ *
+ * @return a result
+ */
+ T get();
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/DynamicValue.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/DynamicValue.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/DynamicValue.java
new file mode 100644
index 0000000..4cc29da
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/DynamicValue.java
@@ -0,0 +1,161 @@
+/*
+ * 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.api;
+
+import java.beans.PropertyChangeListener;
+
+
+/**
+ * <p>A accessor for a single configured value. This can be used to support values that may change during runtime,
+ * reconfigured or final. Hereby external code (could be Tamaya configuration listners or client code), can set a
+ * new value. Depending on the {@link UpdatePolicy} the new value is immedeately active or it requires an active commit
+ * by client code. Similarly an instance also can ignore all later changes to the value.</p>
+ *
+ * <p>Types of this interface can be used as injection targets in injected beans or as template resiult on configuration
+ * templates.</p>
+ *
+ * <h3>Implementation Specification</h3>
+ * Implementation of this interface must be
+ * <ul>
+ * <li>Serializable, when also the item stored is serializable</li>
+ * <li>Thread safe</li>
+ * </ul>
+ *
+ * @param <T> The type of the value.
+ */
+public interface DynamicValue<T> {
+
+ /**
+ * Performs a commit, if necessary, and returns the current value.
+ *
+ * @return the non-null value held by this {@code DynamicValue}
+ * @throws org.apache.tamaya.ConfigException if there is no value present
+ *
+ * @see DynamicValue#isPresent()
+ */
+ T commitAndGet();
+
+ /**
+ * Commits a new value that has not been committed yet, make it the new value of the instance. On change any
+ * registered listeners will be triggered.
+ */
+ void commit();
+
+ /**
+ * Access the {@link UpdatePolicy} used for updating this value.
+ * @return the update policy, never null.
+ */
+ UpdatePolicy getUpdatePolicy();
+
+ /**
+ * Add a listener to be called as weak reference, when this value has been changed.
+ * @param l the listener, not null
+ */
+ void addListener(PropertyChangeListener l);
+
+ /**
+ * Removes a listener to be called, when this value has been changed.
+ * @param l the listner to be removed, not null
+ */
+ void removeListener(PropertyChangeListener l);
+
+ /**
+ * If a value is present in this {@code DynamicValue}, returns the value,
+ * otherwise throws {@code ConfigException}.
+ *
+ * @return the non-null value held by this {@code Optional}
+ * @throws org.apache.tamaya.ConfigException if there is no value present
+ *
+ * @see DynamicValue#isPresent()
+ */
+ T get();
+
+ /**
+ * Method to check for and apply a new value. Depending on the {@link UpdatePolicy}
+ * the value is immediately or deferred visible (or it may even be ignored completely).
+ * @return true, if a new value has been detected. The value may not be visible depending on the current
+ * {@link UpdatePolicy} in place.
+ */
+ boolean updateValue();
+
+ /**
+ * Evaluates the current value dynamically from the underlying configuration.
+ * @return the current actual value, or null.
+ */
+ T evaluateValue();
+
+ /**
+ * Sets a new {@link UpdatePolicy}.
+ * @param updatePolicy the new policy, not null.
+ */
+ void setUpdatePolicy(UpdatePolicy updatePolicy);
+
+ /**
+ * Access a new value that has not yet been committed.
+ * @return the uncommitted new value, or null.
+ */
+ T getNewValue();
+
+ /**
+ * Return {@code true} if there is a value present, otherwise {@code false}.
+ *
+ * @return {@code true} if there is a value present, otherwise {@code false}
+ */
+ boolean isPresent();
+
+ /**
+ * Return the value if present, otherwise return {@code other}.
+ *
+ * @param other the value to be returned if there is no value present, may
+ * be null
+ * @return the value, if present, otherwise {@code other}
+ */
+ T orElse(T other);
+
+ /**
+ * Return the value if present, otherwise invoke {@code other} and return
+ * the result of that invocation.
+ *
+ * @param other a {@code ConfiguredItemSupplier} whose result is returned if no value
+ * is present
+ * @return the value if present otherwise the result of {@code other.get()}
+ * @throws NullPointerException if value is not present and {@code other} is
+ * null
+ */
+ T orElseGet(ConfiguredItemSupplier<? extends T> other);
+
+ /**
+ * Return the contained value, if present, otherwise throw an exception
+ * to be created by the provided supplier.
+ *
+ * NOTE A method reference to the exception constructor with an empty
+ * argument list can be used as the supplier. For example,
+ * {@code IllegalStateException::new}
+ *
+ * @param <X> Type of the exception to be thrown
+ * @param exceptionSupplier The supplier which will return the exception to
+ * be thrown
+ * @return the present value
+ * @throws X if there is no value present
+ * @throws NullPointerException if no value is present and
+ * {@code exceptionSupplier} is null
+ */
+ <X extends Throwable> T orElseThrow(ConfiguredItemSupplier<? extends X> exceptionSupplier) throws X;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/InjectionUtils.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/InjectionUtils.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/InjectionUtils.java
new file mode 100644
index 0000000..a010e96
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/InjectionUtils.java
@@ -0,0 +1,127 @@
+/*
+ * 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.api;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * Utility class with several commonly used functions.
+ */
+public final class InjectionUtils {
+
+ private InjectionUtils(){}
+
+
+ /**
+ * Collects all keys to be be accessed as defined by any annotations of type
+ * {@link ConfigDefaultSections}, {@link Config}.
+ * @param field the (optionally) annotated field instance
+ * @return the regarding key list to be accessed fomr the {@link org.apache.tamaya.Configuration}.
+ */
+ public static List<String> getKeys(Field field) {
+ ConfigDefaultSections areasAnnot = field.getDeclaringClass().getAnnotation(ConfigDefaultSections.class);
+ return InjectionUtils.evaluateKeys(field, areasAnnot, field.getAnnotation(Config.class));
+ }
+
+ /**
+ * Collects all keys to be be accessed as defined by any annotations of type
+ * {@link ConfigDefaultSections}, {@link Config}.
+ * @param method the (optionally) annotated method instance
+ * @return the regarding key list to be accessed fomr the {@link org.apache.tamaya.Configuration}.
+ */
+ public static List<String> getKeys(Method method) {
+ ConfigDefaultSections areasAnnot = method.getDeclaringClass().getAnnotation(ConfigDefaultSections.class);
+ return InjectionUtils.evaluateKeys(method, areasAnnot, method.getAnnotation(Config.class));
+ }
+
+ /**
+ * Evaluates all absolute configuration keys based on the member name found.
+ *
+ * @param member member to analyze.
+ * @param areasAnnot the (optional) annotation defining areas to be looked up.
+ * @return the list of current keys in order how they should be processed/looked up.
+ */
+ public static List<String> evaluateKeys(Member member, ConfigDefaultSections areasAnnot) {
+ List<String> keys = new ArrayList<>();
+ String name = member.getName();
+ String mainKey;
+ if (name.startsWith("get") || name.startsWith("set")) {
+ mainKey = Character.toLowerCase(name.charAt(3)) + name.substring(4);
+ } else {
+ mainKey = Character.toLowerCase(name.charAt(0)) + name.substring(1);
+ }
+ keys.add(mainKey);
+ if (areasAnnot != null) {
+ // Add prefixed entries, including absolute (root) entry for "" area keys.
+ for (String area : areasAnnot.value()) {
+ if (!area.isEmpty()) {
+ keys.add(area + '.' + mainKey);
+ }
+ }
+ } else { // add package name
+ keys.add(member.getDeclaringClass().getName() + '.' + mainKey);
+ keys.add(member.getDeclaringClass().getSimpleName() + '.' + mainKey);
+ }
+ return keys;
+ }
+
+ /**
+ * Evaluates all absolute configuration keys based on the annotations found in a class.
+ *
+ * @param member member to analyze.
+ * @param areasAnnot the (optional) annotation definining areas to be looked up.
+ * @param propertyAnnotation the annotation on field/method level that may defined one or
+ * several keys to be looked up (in absolute or relative form).
+ * @return the list current keys in order how they should be processed/looked up.
+ */
+ public static List<String> evaluateKeys(Member member, ConfigDefaultSections areasAnnot, Config propertyAnnotation) {
+ if(propertyAnnotation==null){
+ return evaluateKeys(member, areasAnnot);
+ }
+ List<String> keys = new ArrayList<>(Arrays.asList(propertyAnnotation.value()));
+ if (keys.isEmpty()) {
+ keys.add(member.getName());
+ }
+ ListIterator<String> iterator = keys.listIterator();
+ while (iterator.hasNext()) {
+ String next = iterator.next();
+ if (next.startsWith("[") && next.endsWith("]")) {
+ // absolute key, strip away brackets, take key as is
+ iterator.set(next.substring(1, next.length() - 1));
+ } else {
+ if (areasAnnot != null && areasAnnot.value().length>0) {
+ // Remove original entry, since it will be replaced with prefixed entries
+ iterator.remove();
+ // Add prefixed entries, including absolute (root) entry for "" area keys.
+ for (String area : areasAnnot.value()) {
+ iterator.add(area.isEmpty() ? next : area + '.' + next);
+ }
+ }
+ }
+ }
+ return keys;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/LoadPolicy.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/LoadPolicy.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/LoadPolicy.java
new file mode 100644
index 0000000..b9540fd
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/LoadPolicy.java
@@ -0,0 +1,42 @@
+/*
+ * 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.api;
+
+/**
+ * Available policies that describe how changes affecting configured values are published/reinjected
+ * for a {@link DynamicValue}.
+ * The policy also affects the cases were any configured listeners/listener methods are called for
+ * propagation current configuration changes.
+ */
+public enum LoadPolicy {
+ /**
+ * The configuration keys is evaluated once, when the owning component is loaded/configured, but never updated later.
+ */
+ INITIAL,
+ /**
+ * The configuration keys is evaluated exactly once on its first access/use lazily, but never updated later.
+ * @see DynamicValue#get()
+ * @see DynamicValue#commitAndGet()
+ */
+ LAZY,
+ /**
+ * The configuration value is evaluated evertime it is accessed.
+ */
+ ALWAYS
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/NoConfig.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/NoConfig.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/NoConfig.java
new file mode 100644
index 0000000..c5234d3
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/NoConfig.java
@@ -0,0 +1,36 @@
+/*
+ * 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.api;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This is a small marker annotations to inform Tamaya that the annotated element should never be injected with
+ * configured data. This is useful because by default Tamaya tries to lookup and inject configuration also by
+ * using property or method names without annotations. With that annotation none of these will be happen.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.FIELD, ElementType.METHOD })
+public @interface NoConfig {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/UpdatePolicy.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/UpdatePolicy.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/UpdatePolicy.java
new file mode 100644
index 0000000..231b9b9
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/UpdatePolicy.java
@@ -0,0 +1,40 @@
+/*
+ * 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.api;
+
+/**
+ * Policy to control how new values are applied to a {@link DynamicValue}.
+ */
+public enum UpdatePolicy {
+ /** New values are applied immedately and registered listeners are informed about the change. */
+ IMMEDEATE,
+ /** New values or not applied, but stored in the newValue property. Explcit call to DynamicValue#commit
+ of DynamicValue#commitAndGet are required to accept the change and inform the listeners about the change.
+ * Registered listeners will be informed, when the commit was performed explicitly.
+ */
+ EXPLCIT,
+ /**
+ * New values are always immedately discarded, listeners are not triggered.
+ */
+ NEVER,
+ /**
+ * All listeners are informed about the change encountered, but the value will not be applied.
+ */
+ LOG_ONLY
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/WithConfigOperator.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/WithConfigOperator.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/WithConfigOperator.java
new file mode 100644
index 0000000..6630e53
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/WithConfigOperator.java
@@ -0,0 +1,45 @@
+/*
+ * 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.api;
+
+import org.apache.tamaya.ConfigOperator;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to define an configuration operator to be used before accessing a configured key.
+ * This allows filtering the current configuration, e.g. to realize views or ensure security
+ * constraints.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = {ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
+public @interface WithConfigOperator {
+
+ /**
+ * Define a custom adapter that should be used to adapt the configuration entry injected. This overrides any
+ * general org.apache.tamaya.core.internal registered. If no adapter is defined (default) and no corresponding adapter is
+ * registered, it is handled as a deployment error.
+ * @return adapter used to transform the configuration entry.
+ */
+ Class<? extends ConfigOperator> value();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/WithPropertyConverter.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/WithPropertyConverter.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/WithPropertyConverter.java
new file mode 100644
index 0000000..499360c
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/WithPropertyConverter.java
@@ -0,0 +1,46 @@
+/*
+ * 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.api;
+
+
+import org.apache.tamaya.spi.PropertyConverter;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to define a type adapter to be used before injecting a configured key, or for applying changes.
+ * This will override any other adapter for performing the type conversion before
+ * injecting the field keys.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = {ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
+public @interface WithPropertyConverter {
+
+ /**
+ * Define a custom adapter or codec that should be used to adapt the configuration entry injected. This overrides any
+ * general org.apache.tamaya.core.internal registered. If no adapter is defined (default) and no corresponding adapter is
+ * registered, it is handled as a deployment error.
+ * @return adapter used to change the configuration entry.
+ */
+ Class<? extends PropertyConverter<?>> value();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/package-info.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/package-info.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/package-info.java
new file mode 100644
index 0000000..b5d8bc3
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/api/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+/**
+ * Common njection API.
+ */
+package org.apache.tamaya.inject.api;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredField.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredField.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredField.java
new file mode 100644
index 0000000..94c0091
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredField.java
@@ -0,0 +1,68 @@
+/*
+ * 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.Configuration;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+
+/**
+ * Abstract model of an field used to inject configuration.
+ */
+public interface ConfiguredField {
+
+ /**
+ * Get the field's type.
+ * @return the field type, never null.
+ */
+ Class<?> getType();
+
+ /**
+ * Get a list of all target keys for the given field. The first resolvable key normally determines the
+ * configuration value injected.
+ * @return a list of evaluated keys.
+ */
+ Collection<String> getConfiguredKeys();
+
+ /**
+ * Get the field's name.
+ * @return the name, not null.
+ */
+ String getName();
+
+ /**
+ * Get the field's full signature.
+ * @return the signature, not null.
+ */
+ String getSignature();
+
+ /**
+ * Get the annotated field.
+ * @return the field, not null.
+ */
+ Field getAnnotatedField();
+
+ /**
+ * Actually calls the annotated method on the instance, hereby passing the configuration values evaluated.
+ * @param instance the instance, not null.
+ * @param config the configuration, not null.
+ */
+ void configure(Object instance, Configuration config);
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredMethod.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredMethod.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredMethod.java
new file mode 100644
index 0000000..128946e
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredMethod.java
@@ -0,0 +1,70 @@
+/*
+ * 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.Configuration;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+
+/**
+ * Abstract model of an method used to inject configuration.
+ */
+public interface ConfiguredMethod {
+
+ /**
+ * Get the key required to be evaluated.
+ * @return the configured keys.
+ */
+ Collection<String> getConfiguredKeys();
+
+ /**
+ * Get the methods input parameter types.
+ * @return the method param types, not null.
+ */
+ Class<?>[] getParameterTypes();
+
+ /**
+ * Get the underlying method reflection type.
+ * @return the method element.
+ */
+ Method getAnnotatedMethod();
+
+ /**
+ * Get the method's name, e.g. {@code setName}.
+ * @return the name, never null.
+ */
+ String getName();
+
+ /**
+ * Get the methods signature, e.g. {@code void setName(String)}.
+ * @return he signature, never null.
+ */
+ String getSignature();
+
+ /**
+ * This method actually configures the given method on a instance of its parent type.
+ * This evaluates the initial key closure and applies changes on the field.
+ *
+ * @param instance the target instance, not null.
+ * @param config the configuration, not null.
+ * @throws org.apache.tamaya.ConfigException if evaluation or conversion failed.
+ */
+ void configure(Object instance, Configuration config);
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredType.java
----------------------------------------------------------------------
diff --git a/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredType.java b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredType.java
new file mode 100644
index 0000000..0f81dc7
--- /dev/null
+++ b/modules/injection/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredType.java
@@ -0,0 +1,63 @@
+/*
+ * 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.Configuration;
+
+import java.util.Collection;
+
+/**
+ * Abstract model of an type used to inject configuration. This also includes instances passed programmatically.
+ */
+public interface ConfiguredType{
+
+ /**
+ * Get the type's class.
+ * @return the base type.
+ */
+ Class getType();
+
+ /**
+ * Get the type's name.
+ * @return the type's name.
+ */
+ String getName();
+
+ /**
+ * Get the registered configured fields.
+ * @return the registered configured fields, never null.
+ */
+ Collection<ConfiguredField> getConfiguredFields();
+
+ /**
+ * Get the registered configured methods.
+ * @return the registered configured methods, never null.
+ */
+ Collection<ConfiguredMethod> getConfiguredMethods();
+
+ /**
+ * This method actually configures an instance using the given configuration data.
+ *
+ * @param instance The instance to be configured, not null.
+ * @param config the target config, not null.
+ */
+ void configure(Object instance, Configuration config);
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/pom.xml
----------------------------------------------------------------------
diff --git a/modules/injection/pom.xml b/modules/injection/pom.xml
index 16809b7..88b8f4b 100644
--- a/modules/injection/pom.xml
+++ b/modules/injection/pom.xml
@@ -1,24 +1,22 @@
-<!--
-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 current 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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<!--
+ ~ 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
@@ -27,78 +25,15 @@ under the License.
<version>0.3-incubating-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
- <artifactId>tamaya-injection</artifactId>
- <name>Apache Tamaya Injection Support</name>
- <packaging>bundle</packaging>
-
- <properties>
- <jdkVersion>1.7</jdkVersion>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.tamaya</groupId>
- <artifactId>tamaya-api</artifactId>
- <version>${project.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.tamaya.ext</groupId>
- <artifactId>tamaya-injection-api</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.tamaya</groupId>
- <artifactId>tamaya-core</artifactId>
- <version>${project.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.tamaya.ext</groupId>
- <artifactId>tamaya-resolver</artifactId>
- <version>${project.version}</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.apache.tamaya.ext</groupId>
- <artifactId>tamaya-builder</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.tamaya.ext</groupId>
- <artifactId>tamaya-events</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>java-hamcrest</artifactId>
- </dependency>
-
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>
- org.apache.tamaya.inject
- </Export-Package>
- <Private-Package>
- org.apache.tamaya.inject.internal
- </Private-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
+ <artifactId>tamaya-injection-all</artifactId>
+ <name>Apache Tamaya Modules - Injection Parent</name>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>injection-api</module>
+ <module>standalone</module>
+ <module>cdi-se</module>
+ <module>cdi-ee</module>
+ </modules>
</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/main/java/org/apache/tamaya/inject/ConfigurationInjection.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/ConfigurationInjection.java b/modules/injection/src/main/java/org/apache/tamaya/inject/ConfigurationInjection.java
deleted file mode 100644
index 79d6218..0000000
--- a/modules/injection/src/main/java/org/apache/tamaya/inject/ConfigurationInjection.java
+++ /dev/null
@@ -1,42 +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.inject;
-
-import org.apache.tamaya.spi.ServiceContextManager;
-
-/**
- * Singleton accessor class for accessing {@link ConfigurationInjector} instances.
- */
-public final class ConfigurationInjection {
-
- /**
- * Singleton constructor.
- */
- private ConfigurationInjection() {
- }
-
- /**
- * Get the current injector instance.
- *
- * @return the current injector, not null.
- */
- public static ConfigurationInjector getConfigurationInjector() {
- return ServiceContextManager.getServiceContext().getService(ConfigurationInjector.class);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/main/java/org/apache/tamaya/inject/ConfigurationInjector.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/ConfigurationInjector.java b/modules/injection/src/main/java/org/apache/tamaya/inject/ConfigurationInjector.java
deleted file mode 100644
index 563ae47..0000000
--- a/modules/injection/src/main/java/org/apache/tamaya/inject/ConfigurationInjector.java
+++ /dev/null
@@ -1,94 +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.inject;
-
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.inject.api.ConfiguredItemSupplier;
-
-/**
- * Accessor interface for injection of configuration and configuration templates.
- */
-public interface ConfigurationInjector {
-
- /**
- * Configures the current instance and registers necessary listener to forward config change events as
- * defined by the current annotations in place.
- *
- * Unannotated types are ignored.
- *
- * @param <T> the type of the instance.
- * @param instance the instance to be configured
- * @return the configured instance (allows chaining of operations).
- */
- <T> T configure(T instance);
-
- /**
- * Configures the current instance and registers necessary listener to forward config change events as
- * defined by the current annotations in place.
- *
- * Unannotated types are ignored.
- *
- * @param <T> the type of the instance.
- * @param instance the instance to be configured
- * @param config the configuration to be used for injection.
- * @return the configured instance (allows chaining of operations).
- */
- <T> T configure(T instance, Configuration config);
-
- /**
- * Creates a template implementing the annotated methods based on current configuration data.
- *
- * @param <T> the type of the template.
- * @param templateType the type of the template to be created.
- * @return the configured template.
- */
- <T> T createTemplate(Class<T> templateType);
-
- /**
- * Creates a template implementting the annotated methods based on current configuration data.
- *
- * @param <T> the type of the template.
- * @param config the configuration to be used for backing the template.
- * @param templateType the type of the template to be created.
- * @return the configured template.
- */
- <T> T createTemplate(Class<T> templateType, Configuration config);
-
-
- /**
- * Creates a supplier for configured instances of the given type {@code T}.
- *
- * @param supplier the supplier to create new instances.
- * @param <T> the target type.
- * @return a supplier creating configured instances of {@code T}.
- */
- <T> ConfiguredItemSupplier<T> getConfiguredSupplier(ConfiguredItemSupplier<T> supplier);
-
- /**
- * Creates a supplier for configured instances of the given type {@code T}.
- *
- * @param supplier the supplier to create new instances.
- * @param config the configuration to be used for backing the supplier.
- * @param <T> the target type.
- * @return a supplier creating configured instances of {@code T}.
- */
- <T> ConfiguredItemSupplier<T> getConfiguredSupplier(ConfiguredItemSupplier<T> supplier, Configuration config);
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigTemplateInvocationHandler.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigTemplateInvocationHandler.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigTemplateInvocationHandler.java
deleted file mode 100644
index 5d634e1..0000000
--- a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigTemplateInvocationHandler.java
+++ /dev/null
@@ -1,73 +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.inject.internal;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.ConfigurationProvider;
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.inject.api.DynamicValue;
-import org.apache.tamaya.inject.spi.ConfiguredType;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.util.Objects;
-
-/**
- * Invocation handler that handles request against a configuration template.
- */
-public final class ConfigTemplateInvocationHandler implements InvocationHandler {
-
- /**
- * The configured type.
- */
- private final ConfiguredType type;
-
- /**
- * Creates a new handler instance.
- *
- * @param type the target type, not null.
- */
- public ConfigTemplateInvocationHandler(Class<?> type) {
- this.type = new ConfiguredTypeImpl(Objects.requireNonNull(type));
- if (!type.isInterface()) {
- throw new IllegalArgumentException("Can only proxy interfaces as configuration templates.");
- }
- InjectionHelper.sendConfigurationEvent(this.type);
- }
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- Configuration config = ConfigurationProvider.getConfiguration();
- if ("toString".equals(method.getName())) {
- return "Configured Proxy -> " + this.type.getType().getName();
- } else if ("hashCode".equals(method.getName())) {
- return Objects.hashCode(proxy);
- } else if ("equals".equals(method.getName())) {
- return Objects.equals(proxy, args[0]);
- } else if ("get".equals(method.getName())) {
- return config;
- }
- if (method.getReturnType() == DynamicValue.class) {
- return DefaultDynamicValue.of(method, config);
- }
- String[] retKey = new String[1];
- String configValue = InjectionHelper.getConfigValue(method, retKey, config);
- return InjectionHelper.adaptValue(method, TypeLiteral.of(method.getReturnType()), retKey[0], configValue);
- }
-}
[15/15] incubator-tamaya-extensions git commit: TAMAYA-182:
Streamlined/unified builder API and fixed some bugs popping up during
testing.
Posted by an...@apache.org.
TAMAYA-182: Streamlined/unified builder API and fixed some bugs popping up during testing.
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/3aca9112
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/tree/3aca9112
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/diff/3aca9112
Branch: refs/heads/master
Commit: 3aca9112035e8b1ed70ecd739b03de15c32a3617
Parents: fe7cd8f
Author: anatole <an...@apache.org>
Authored: Sun Oct 30 22:59:21 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Sun Oct 30 22:59:21 2016 +0100
----------------------------------------------------------------------
...faultConfigurationContextChangeListener.java | 5 +-
.../functions/ConfigurationFunctions.java | 5 +
.../tamaya/functions/SimplePropertySource.java | 89 ++++
modules/mutable-config/pom.xml | 82 ++++
.../mutableconfig/ChangePropagationPolicy.java | 53 +++
.../mutableconfig/MutableConfiguration.java | 126 ++++++
.../MutableConfigurationProvider.java | 239 +++++++++++
.../internal/DefaultMutableConfiguration.java | 170 ++++++++
.../DefaultMutableConfigurationSpi.java | 38 ++
.../MutablePropertiesPropertySource.java | 196 +++++++++
.../MutableXmlPropertiesPropertySource.java | 198 +++++++++
.../mutableconfig/spi/ConfigChangeRequest.java | 176 ++++++++
.../spi/MutableConfigurationProviderSpi.java | 42 ++
.../spi/MutablePropertySource.java | 47 +++
...leconfig.spi.MutableConfigurationProviderSpi | 19 +
.../MutableConfigurationProviderTest.java | 84 ++++
.../mutableconfig/MutableConfigurationTest.java | 187 +++++++++
.../PropertiesFileConfigBackendTest.java | 29 ++
.../internal/WritablePropertiesSource.java | 49 +++
.../internal/WritableXmlPropertiesSource.java | 49 +++
.../org.apache.tamaya.spi.PropertySource | 20 +
modules/spi-support/pom.xml | 6 +-
.../tamaya/spisupport/CLIPropertySource.java | 101 +++++
.../tamaya/spisupport/DefaultConfiguration.java | 4 +-
.../spisupport/DefaultConfigurationContext.java | 253 ++++++------
.../DefaultConfigurationContextBuilder.java | 410 +++++++++++++++++++
.../spisupport/EnvironmentPropertySource.java | 102 +++++
.../spisupport/PropertyConverterManager.java | 248 ++++++-----
.../spisupport/PropertyFilterComparator.java | 60 +++
.../spisupport/PropertyFilterManager.java | 131 ++++++
.../tamaya/spisupport/SimplePropertySource.java | 151 +++++++
.../tamaya/spisupport/SystemPropertySource.java | 125 ++++++
.../java/org/apache/tamaya/spisupport/A.java | 29 ++
.../java/org/apache/tamaya/spisupport/B.java | 29 ++
.../spisupport/BasePropertySourceTest.java | 106 +++++
.../java/org/apache/tamaya/spisupport/C.java | 56 +++
.../spisupport/CLIPropertySourceTest.java | 59 +++
.../tamaya/spisupport/CTestConverter.java | 32 ++
.../DefaultConfigurationContextTest.java | 183 +++++++++
.../tamaya/spisupport/EnumConverterTest.java | 60 +++
.../EnvironmentPropertySourceTest.java | 67 +++
.../PriorityServiceComparatorTest.java | 45 ++
.../PropertiesFilePropertySourceTest.java | 60 +++
.../PropertyConverterManagerTest.java | 180 ++++++++
.../spisupport/SimplePropertySourceTest.java | 85 ++++
.../spisupport/SystemPropertySourceTest.java | 102 +++++
.../spisupport/TestPropertyDefaultSource.java | 56 +++
.../org.apache.tamaya.spi.PropertyConverter | 38 ++
.../src/test/resources/invalid-properties.xml | 25 ++
.../src/test/resources/non-xml-properties.xml | 18 +
.../test/resources/overrideOrdinal.properties | 25 ++
.../src/test/resources/testfile.properties | 22 +
.../src/test/resources/valid-properties.xml | 25 ++
53 files changed, 4565 insertions(+), 231 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/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 e49856d..8a9ff64 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
@@ -56,10 +56,7 @@ public class DefaultConfigurationContextChangeListener implements ConfigEventLis
.setContext(context);
if (!affectedPropertySources.isEmpty()) {
Set<String> propertySourceNames = new HashSet<>();
- for (PropertySource removed : contextChange.getRemovedPropertySources()) {
- propertySourceNames.add(removed.getName());
- }
- newContextBuilder.removePropertySources(propertySourceNames);
+ newContextBuilder.removePropertySources(contextChange.getRemovedPropertySources());
}
newContextBuilder.addPropertySources(contextChange.getAddedPropertySources());
newContextBuilder.addPropertySources(contextChange.getUpdatedPropertySources());
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/functions/src/main/java/org/apache/tamaya/functions/ConfigurationFunctions.java
----------------------------------------------------------------------
diff --git a/modules/functions/src/main/java/org/apache/tamaya/functions/ConfigurationFunctions.java b/modules/functions/src/main/java/org/apache/tamaya/functions/ConfigurationFunctions.java
index 6dd0427..97934f6 100644
--- a/modules/functions/src/main/java/org/apache/tamaya/functions/ConfigurationFunctions.java
+++ b/modules/functions/src/main/java/org/apache/tamaya/functions/ConfigurationFunctions.java
@@ -124,6 +124,11 @@ public final class ConfigurationFunctions {
}
@Override
+ public PropertySource getPropertySource(String name) {
+ return null;
+ }
+
+ @Override
public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
// ignore
}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/functions/src/main/java/org/apache/tamaya/functions/SimplePropertySource.java
----------------------------------------------------------------------
diff --git a/modules/functions/src/main/java/org/apache/tamaya/functions/SimplePropertySource.java b/modules/functions/src/main/java/org/apache/tamaya/functions/SimplePropertySource.java
new file mode 100644
index 0000000..5dad7bb
--- /dev/null
+++ b/modules/functions/src/main/java/org/apache/tamaya/functions/SimplePropertySource.java
@@ -0,0 +1,89 @@
+/*
+ * 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.functions;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+* Simple property source implementation using a map.
+*/
+public class SimplePropertySource implements PropertySource {
+ /** The properties. */
+ private final Map<String, String> properties;
+ /** The source's name. */
+ private final String name;
+ /** The default ordinal. */
+ private int defaultOrdinal;
+
+ public SimplePropertySource(String name, Map<String, String> properties){
+ this.properties = new HashMap<>(properties);
+ this.name = Objects.requireNonNull(name);
+ }
+
+ @Override
+ public int getOrdinal(){
+ PropertyValue configuredOrdinal = get(TAMAYA_ORDINAL);
+ if(configuredOrdinal!=null){
+ try{
+ return Integer.parseInt(configuredOrdinal.getValue());
+ } catch(Exception e){
+ Logger.getLogger(getClass().getName()).log(Level.WARNING,
+ "Configured Ordinal is not an int number: " + configuredOrdinal, e);
+ }
+ }
+ return getDefaultOrdinal();
+ }
+
+ public int getDefaultOrdinal(){
+ return defaultOrdinal;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public PropertyValue get(String key) {
+ return PropertyValue.of(key, this.properties.get(key),
+ getName());
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return this.properties;
+ }
+
+ @Override
+ public boolean isScannable() {
+ return false;
+ }
+
+ @Override
+ public String toString(){
+ return "SimplePropertySource(name="+name+", numProps="+properties.size()+")";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/pom.xml
----------------------------------------------------------------------
diff --git a/modules/mutable-config/pom.xml b/modules/mutable-config/pom.xml
new file mode 100644
index 0000000..e9be993
--- /dev/null
+++ b/modules/mutable-config/pom.xml
@@ -0,0 +1,82 @@
+<!--
+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 current 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-extensions</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>tamaya-mutable-config</artifactId>
+ <name>Apache Tamaya Modules - Mutable Configuration</name>
+ <description>This module provides abstraction, if your scenario needs to actively change configuration entries
+ and write changes back to some property sources, files etc.</description>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <jdkVersion>1.7</jdkVersion>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-spisupport</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-core</artifactId>
+ <version>${project.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>java-hamcrest</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.tamaya.mutableconfig
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ChangePropagationPolicy.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ChangePropagationPolicy.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ChangePropagationPolicy.java
new file mode 100644
index 0000000..5378166
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ChangePropagationPolicy.java
@@ -0,0 +1,53 @@
+/*
+ * 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.mutableconfig;
+
+import org.apache.tamaya.mutableconfig.spi.ConfigChangeRequest;
+import org.apache.tamaya.spi.PropertySource;
+
+import java.util.Collection;
+
+/**
+ * Policy that defines how changes are applied to the available
+ * {@link org.apache.tamaya.mutableconfig.spi.MutablePropertySource} instances, e.g.
+ * <ul>
+ * <li><b>ALL: </b>Changes are propagated to all {@link org.apache.tamaya.mutableconfig.spi.MutablePropertySource}
+ * instances in order of significance. This means that a key added, updated or removed in each instance, if the key
+ * is writable/removable.</li>
+ * <li><b>SIGNIFICANT_ONLY: </b>A change (creation, update) is only applied, if
+ * <ol>
+ * <li>the value is not provided by a more significant read-only property source.</li>
+ * <li>there is no more significant writable property source, which supports writing a g iven key.</li>
+ * </ol>
+ * In other words a added or updated value is written exactly once to the most significant
+ * writable property source, which accepts a given key. Otherwise the change is discarded.</li>
+ * <li><b>NONE: </b>Do not apply any changes.</li>
+ * </ul>
+ */
+public interface ChangePropagationPolicy {
+
+ /**
+ * Method being called when a multiple key/value pairs are added or updated.
+ * @param propertySources the property sources, including readable property sources of the current configuration,
+ * never null.
+ * @param configChange the configuration change, not null.
+ */
+ void applyChange(ConfigChangeRequest configChange, Collection<PropertySource> propertySources);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
new file mode 100644
index 0000000..451769e
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
@@ -0,0 +1,126 @@
+/*
+ * 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.mutableconfig;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.mutableconfig.spi.ConfigChangeRequest;
+
+import java.util.Collection;
+import java.util.Map;
+
+
+/**
+ * This interface extends the Configuration interface hereby adding methods to change configuration entries.
+ * Hereby not all configuration entries are necessarily mutable, since some entries may be read from non
+ * mutable areas of configuration. Of course, it is always possible to add a mutable shadow layer on top of all
+ * property sources to persist/control any changes applied. The exact management and storage persistence algorithm
+ * should be transparent.
+ *
+ * As a consequence clients should first check, using the corresponding methods, if entries can be added/updated or
+ * removed.
+ *
+ * This class should only used in a single threaded context, though all methods inherited from {@link Configuration}
+ * must be thread-safe. Methods handling configuration changes are expected to be used in a single threaded environment
+ * only. For multi-threaded us create a new instance of {@link MutableConfiguration} for each thread.
+ */
+public interface MutableConfiguration extends Configuration {
+
+ /**
+ * Storesd the changes. After a commit the change is not editable anymore. All changes applied will be written to
+ * the corresponding configuration backend.
+ *
+ * NOTE that changes applied must not necessarily be visible in the current {@link Configuration} instance,
+ * since visibility of changes also depends on the ordinals set on the {@link org.apache.tamaya.spi.PropertySource}s
+ * configured.
+ * @throws org.apache.tamaya.ConfigException if the request already has been committed or cancelled, or the commit fails.
+ */
+ void store();
+
+ /**
+ * Access the current configuration change context, built up on all the change context of the participating
+ * {@link org.apache.tamaya.mutableconfig.spi.MutablePropertySource} instances.
+ * @return the colleted changes as one single config change for the current transaction, or null, if no transaction
+ * is active.
+ */
+ ConfigChangeRequest getConfigChangeRequest();
+
+ /**
+ * Access the active {@link ChangePropagationPolicy}.This policy controls how configuration changes are written/published
+ * to the known {@link org.apache.tamaya.mutableconfig.spi.MutablePropertySource} instances of a {@link Configuration}.
+ * @return he active {@link ChangePropagationPolicy}, never null.
+ */
+ ChangePropagationPolicy getChangePropagationPolicy();
+
+ /**
+ * Sets a property.
+ *
+ * @param key the property's key, not null.
+ * @param value the property's value, not null.
+ * @return the former property value, or null.
+ * @throws org.apache.tamaya.ConfigException if the key/value cannot be added, or the request is read-only.
+ */
+ MutableConfiguration put(String key, String value);
+
+ /**
+ * Puts all given configuration entries. This method should check that all given properties are
+ * basically removable, as defined by #isWritable. If any of the passed keys is not writable during this initial
+ * check, the operation should not perform any configuration changes and throw a
+ * {@link org.apache.tamaya.ConfigException}. If errors occur afterwards, when the properties are effectively
+ * written back to the backends, the errors should be collected and returned as part of the ConfigException
+ * payload. Nevertheless the operation should in that case remove all entries as far as possible and abort the
+ * writing operation.
+ *
+ * @param properties the properties tobe written, not null.
+ * @return the config change request
+ * @throws org.apache.tamaya.ConfigException if any of the given properties could not be written, or the request
+ * is read-only.
+ */
+ MutableConfiguration putAll(Map<String, String> properties);
+
+ /**
+ * Removes all given configuration entries. This method should check that all given properties are
+ * basically removable, as defined by #isRemovable. If any of the passed keys is not removable during this initial
+ * check, the operation should not perform any configuration changes and throw a
+ * {@link org.apache.tamaya.ConfigException}. If errors
+ * occur afterwards, when the properties are effectively written back to the backends, the errors should be
+ * collected and returned as part of the ConfigException payload. Nevertheless the operation should in that case
+ * remove all entries as far as possible and abort the writing operation.
+ *
+ * @param keys the property's keys to be removedProperties, not null.
+ * @return the config change request
+ * @throws org.apache.tamaya.ConfigException if any of the given keys could not be removedProperties, or the
+ * request is read-only.
+ */
+ MutableConfiguration remove(Collection<String> keys);
+
+ /**
+ * Removes all given configuration entries. This method should check that all given properties are
+ * basically removable, as defined by #isRemovable. If any of the passed keys is not removable during this initial
+ * check, the operation should not perform any configuration changes and throw a {@link org.apache.tamaya.ConfigException}. If errors
+ * occur afterwards, when the properties are effectively written back to the backends, the errors should be
+ * collected and returned as part of the ConfigException payload. Nevertheless the operation should in that case
+ * remove all entries as far as possible and abort the writing operation.
+ *
+ * @param keys the property's keys to be removedProperties, not null.
+ * @return the config change request
+ * @throws org.apache.tamaya.ConfigException if any of the given keys could not be removedProperties, or the request is read-only.
+ */
+ MutableConfiguration remove(String... keys);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationProvider.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationProvider.java
new file mode 100644
index 0000000..c2cd20e
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationProvider.java
@@ -0,0 +1,239 @@
+/*
+ * 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.mutableconfig;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.mutableconfig.spi.ConfigChangeRequest;
+import org.apache.tamaya.mutableconfig.spi.MutableConfigurationProviderSpi;
+import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Logger;
+
+
+/**
+ * Accessor for creating {@link MutableConfiguration} instances to change configuration and commit changes.
+ */
+public final class MutableConfigurationProvider {
+
+ private static final Logger LOG = Logger.getLogger(MutableConfigurationProvider.class.getName());
+ /**
+ * URIs used by this query instance to identify the backends to use for write operations.
+ */
+ private static MutableConfigurationProviderSpi mutableConfigurationProviderSpi = loadSpi();
+
+ /**
+ * SPI loader method.
+ * @throws ConfigException if loading fails.
+ * @return the SPI, never null.
+ */
+ private static MutableConfigurationProviderSpi loadSpi() {
+ try{
+ return ServiceContextManager.getServiceContext().getService(
+ MutableConfigurationProviderSpi.class) ;
+ } catch(Exception e){
+ throw new ConfigException("Failed to initialize MutableConfigurationProviderSpi - " +
+ "mutable configuration support.");
+ }
+ }
+
+
+ /** Singleton constructor. */
+ private MutableConfigurationProvider(){}
+
+ /**
+ * Creates a new {@link MutableConfiguration} for the given default configuration, using all
+ * {@link MutablePropertySource} instances found in its context and {@code autoCommit = false}.
+ *
+ * @return a new MutableConfiguration instance
+ */
+ public static MutableConfiguration createMutableConfiguration(){
+ return mutableConfigurationProviderSpi.createMutableConfiguration(
+ ConfigurationProvider.getConfiguration(), getApplyMostSignificantOnlyChangePolicy());
+ }
+
+ /**
+ * Creates a new {@link MutableConfiguration} for the given default configuration, using all
+ * {@link MutablePropertySource} instances found in its context and {@code autoCommit = false}.
+ * @param changePropgationPolicy policy that defines how a change is written back and which property
+ * sources are finally eligible for a write operation.
+ * @return a new MutableConfiguration instance, with the given change policy active.
+ */
+ public static MutableConfiguration createMutableConfiguration(ChangePropagationPolicy changePropgationPolicy){
+ return mutableConfigurationProviderSpi.createMutableConfiguration(
+ ConfigurationProvider.getConfiguration(), changePropgationPolicy);
+ }
+
+
+ /**
+ * Creates a new {@link MutableConfiguration} for the given configuration, using all
+ * {@link MutablePropertySource} instances found in its context and {@code MOST_SIGNIFICANT_ONLY_POLICY}
+ * configuration writing policy.
+ *
+ * @param configuration the configuration to use to write the changes/config.
+ * @return a new MutableConfiguration instance
+ */
+ public static MutableConfiguration createMutableConfiguration(Configuration configuration){
+ return createMutableConfiguration(configuration, MOST_SIGNIFICANT_ONLY_POLICY);
+ }
+
+ /**
+ * Creates a new {@link MutableConfiguration} for the given configuration, using all
+ * {@link MutablePropertySource} instances found in its context and {@code ALL_POLICY}
+ * configuration writing policy.
+ *
+ * @param configuration the configuration to use to write the changes/config.
+ * @param changePropagationPolicy the configuration writing policy.
+ * @return a new MutableConfiguration instance
+ */
+ public static MutableConfiguration createMutableConfiguration(Configuration configuration, ChangePropagationPolicy changePropagationPolicy){
+ return mutableConfigurationProviderSpi.createMutableConfiguration(configuration, changePropagationPolicy);
+ }
+
+ /**
+ * This propagation policy writes through all changes to all mutable property sources, where applicable.
+ * This is also the default policy.
+ * @return default all policy.
+ */
+ public static ChangePropagationPolicy getApplyAllChangePolicy(){
+ return ALL_POLICY;
+ }
+
+ /**
+ * This propagation policy writes changes only once to the most significant property source, where a change is
+ * applicable.
+ * @return a corresponding {@link ChangePropagationPolicy} implementation, never null.
+ */
+ public static ChangePropagationPolicy getApplyMostSignificantOnlyChangePolicy(){
+ return MOST_SIGNIFICANT_ONLY_POLICY;
+ }
+
+ /**
+ * This propagation policy writes changes only once to the most significant property source, where a change is
+ * applicable.
+ * @param propertySourceNames the names of the mutable property sources to be considered for writing any changes to.
+ * @return a corresponding {@link ChangePropagationPolicy} implementation, never null.
+ */
+ public static ChangePropagationPolicy getApplySelectiveChangePolicy(String... propertySourceNames){
+ return new SelectiveChangeApplyPolicy(propertySourceNames);
+ }
+
+ /**
+ * This propagation policy writes changes only once to the most significant property source, where a change is
+ * applicable.
+ * @return a corresponding {@link ChangePropagationPolicy} implementation, never null.
+ */
+ public static ChangePropagationPolicy getApplyNonePolicy(){
+ return NONE_POLICY;
+ }
+
+ /**
+ * This propagation policy writes through all changes to all mutable property sources, where applicable.
+ */
+ private static final ChangePropagationPolicy ALL_POLICY = new ChangePropagationPolicy() {
+ @Override
+ public void applyChange(ConfigChangeRequest change, Collection<PropertySource> propertySources) {
+ for(PropertySource propertySource: propertySources){
+ if(propertySource instanceof MutablePropertySource){
+ MutablePropertySource target = (MutablePropertySource)propertySource;
+ try{
+ target.applyChange(change);
+ }catch(ConfigException e){
+ LOG.warning("Failed to store changes '"+change+"' not applicable to "+target.getName()
+ +"("+target.getClass().getName()+").");
+ }
+ }
+ }
+ }
+
+ };
+
+ /**
+ * This propagation policy writes changes only once to the most significant property source, where a change is
+ * applicable.
+ */
+ private static final ChangePropagationPolicy MOST_SIGNIFICANT_ONLY_POLICY = new ChangePropagationPolicy() {
+ @Override
+ public void applyChange(ConfigChangeRequest change, Collection<PropertySource> propertySources) {
+ for(PropertySource propertySource: propertySources){
+ if(propertySource instanceof MutablePropertySource){
+ MutablePropertySource target = (MutablePropertySource)propertySource;
+ try{
+ target.applyChange(change);
+ }catch(ConfigException e){
+ LOG.warning("Failed to store changes '"+change+"' not applicable to "+target.getName()
+ +"("+target.getClass().getName()+").");
+ }
+ break;
+ }
+ }
+ }
+
+ };
+
+ /**
+ * This propagation policy writes changes only once to the most significant property source, where a change is
+ * applicable.
+ */
+ private static final ChangePropagationPolicy NONE_POLICY = new ChangePropagationPolicy() {
+ @Override
+ public void applyChange(ConfigChangeRequest change, Collection<PropertySource> propertySources) {
+ LOG.warning("Cannot store changes '"+change+"': prohibited by change policy (read-only).");
+ }
+ };
+
+ /**
+ * This propagation policy writes through all changes to all mutable property sources, where applicable.
+ */
+ private static final class SelectiveChangeApplyPolicy implements ChangePropagationPolicy {
+
+ private Set<String> propertySourceNames = new HashSet<>();
+
+ SelectiveChangeApplyPolicy(String... propertySourceNames){
+ this.propertySourceNames.addAll(Arrays.asList(propertySourceNames));
+ }
+
+ @Override
+ public void applyChange(ConfigChangeRequest change, Collection<PropertySource> propertySources) {
+ for(PropertySource propertySource: propertySources){
+ if(propertySource instanceof MutablePropertySource){
+ if(this.propertySourceNames.contains(propertySource.getName())) {
+ MutablePropertySource target = (MutablePropertySource) propertySource;
+ try{
+ target.applyChange(change);
+ }catch(ConfigException e){
+ LOG.warning("Failed to store changes '"+change+"' not applicable to "+target.getName()
+ +"("+target.getClass().getName()+").");
+ }
+ break;
+ }
+ }
+ }
+ }
+ };
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfiguration.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfiguration.java
new file mode 100644
index 0000000..ad272ef
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfiguration.java
@@ -0,0 +1,170 @@
+/*
+ * 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.mutableconfig.internal;
+
+import org.apache.tamaya.ConfigOperator;
+import org.apache.tamaya.ConfigQuery;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.mutableconfig.ChangePropagationPolicy;
+import org.apache.tamaya.mutableconfig.MutableConfiguration;
+import org.apache.tamaya.mutableconfig.spi.ConfigChangeRequest;
+import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.PropertySource;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.logging.Logger;
+
+
+/**
+ * Default implementation of a {@link MutableConfiguration}.
+ */
+public class DefaultMutableConfiguration implements MutableConfiguration {
+ private static final Logger LOG = Logger.getLogger(DefaultMutableConfiguration.class.getName());
+ private ConfigChangeRequest changeRequest = new ConfigChangeRequest(UUID.randomUUID().toString());
+ private final Configuration config;
+ private ChangePropagationPolicy changePropagationPolicy;
+
+ public DefaultMutableConfiguration(Configuration config, ChangePropagationPolicy changePropagationPolicy){
+ this.config = Objects.requireNonNull(config);
+ this.changePropagationPolicy = Objects.requireNonNull(changePropagationPolicy);
+ }
+
+ @Override
+ public ChangePropagationPolicy getChangePropagationPolicy(){
+ return changePropagationPolicy;
+ }
+
+ @Override
+ public ConfigChangeRequest getConfigChangeRequest(){
+ return changeRequest;
+ }
+
+ protected List<MutablePropertySource> getMutablePropertySources() {
+ List<MutablePropertySource> result = new ArrayList<>();
+ for(PropertySource propertySource:this.config.getContext().getPropertySources()) {
+ if(propertySource instanceof MutablePropertySource){
+ result.add((MutablePropertySource)propertySource);
+ }
+ }
+ return result;
+ }
+
+
+ @Override
+ public MutableConfiguration put(String key, String value) {
+ changeRequest.put(key, value);
+ return this;
+ }
+
+ @Override
+ public MutableConfiguration putAll(Map<String, String> properties) {
+ changeRequest.putAll(properties);
+ return this;
+ }
+
+ @Override
+ public MutableConfiguration remove(String... keys) {
+ changeRequest.removeAll(Arrays.asList(keys));
+ return this;
+ }
+
+
+ @Override
+ public void store() {
+ this.changePropagationPolicy.applyChange(changeRequest, config.getContext().getPropertySources());
+ }
+
+ @Override
+ public MutableConfiguration remove(Collection<String> keys) {
+ for(MutablePropertySource target:getMutablePropertySources()) {
+ changeRequest.removeAll(keys);
+ }
+ return this;
+ }
+
+ @Override
+ public String get(String key) {
+ return this.config.get(key);
+ }
+
+ @Override
+ public String getOrDefault(String key, String defaultValue) {
+ return this.config.getOrDefault(key, defaultValue);
+ }
+
+ @Override
+ public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
+ return this.config.getOrDefault(key, type, defaultValue);
+ }
+
+ @Override
+ public <T> T get(String key, Class<T> type) {
+ return this.config.get(key, type);
+ }
+
+ @Override
+ public <T> T get(String key, TypeLiteral<T> type) {
+ return this.config.get(key, type);
+ }
+
+ @Override
+ public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) {
+ return this.config.getOrDefault(key, type, defaultValue);
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return this.config.getProperties();
+ }
+
+ @Override
+ public Configuration with(ConfigOperator operator) {
+ return operator.operate(this);
+ }
+
+ @Override
+ public <T> T query(ConfigQuery<T> query) {
+ return query.query(this);
+ }
+
+ @Override
+ public ConfigurationContext getContext() {
+ return config.getContext();
+ }
+
+ private Collection<PropertySource> getPropertySources() {
+ return this.config.getContext().getPropertySources();
+ }
+
+ @Override
+ public String toString() {
+ return "DefaultMutableConfiguration{" +
+ "config=" + config +
+ '}';
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfigurationSpi.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfigurationSpi.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfigurationSpi.java
new file mode 100644
index 0000000..a47cd0e
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfigurationSpi.java
@@ -0,0 +1,38 @@
+/*
+ * 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.mutableconfig.internal;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.mutableconfig.ChangePropagationPolicy;
+import org.apache.tamaya.mutableconfig.MutableConfiguration;
+import org.apache.tamaya.mutableconfig.spi.MutableConfigurationProviderSpi;
+
+
+/**
+ * SPI implementation that creates instances of {@link DefaultMutableConfiguration}, hereby for
+ * each instance of {@link Configuration} a new instance has to be returned.
+ */
+public class DefaultMutableConfigurationSpi implements MutableConfigurationProviderSpi {
+
+ @Override
+ public MutableConfiguration createMutableConfiguration(Configuration configuration,
+ ChangePropagationPolicy propagationPolicy){
+ return new DefaultMutableConfiguration(configuration, propagationPolicy);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutablePropertiesPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutablePropertiesPropertySource.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutablePropertiesPropertySource.java
new file mode 100644
index 0000000..af9bed4
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutablePropertiesPropertySource.java
@@ -0,0 +1,196 @@
+/*
+ * 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.mutableconfig.propertysources;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.mutableconfig.spi.ConfigChangeRequest;
+import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spi.PropertyValueBuilder;
+import org.apache.tamaya.spisupport.BasePropertySource;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Simple implementation of a mutable {@link org.apache.tamaya.spi.PropertySource} for .properties files.
+ */
+public class MutablePropertiesPropertySource extends BasePropertySource
+implements MutablePropertySource{
+
+ /**
+ * The logger.
+ */
+ private static final Logger LOG = Logger.getLogger(MutablePropertiesPropertySource.class.getName());
+
+ /**
+ * Default update interval is 1 minute.
+ */
+ private static final long DEFAULT_UPDATE_INTERVAL = 60000L;
+
+ /**
+ * The property source name.
+ */
+ private String name;
+
+ /**
+ * The configuration resource's URL.
+ */
+ private File file;
+
+ /**
+ * Timestamp of last read.
+ */
+ private long lastRead;
+
+ /**
+ * Interval, when the resource should try to update its contents.
+ */
+ private long updateInterval = DEFAULT_UPDATE_INTERVAL;
+ /**
+ * The current properties.
+ */
+ private Map<String, String> properties = new HashMap<>();
+
+ /**
+ * Creates a new Properties based PropertySource based on the given URL.
+ *
+ * @param propertiesLocation the URL encoded location, not null.
+ * @param defaultOrdinal the default ordinal to be used, when no ordinal is provided with the property
+ * source's properties.
+ */
+ public MutablePropertiesPropertySource(File propertiesLocation, int defaultOrdinal) {
+ super(defaultOrdinal);
+ this.name = propertiesLocation.toString();
+ try {
+ this.file = propertiesLocation;
+ load();
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE, "Cannot convert file to URL: " + propertiesLocation, e);
+ }
+ }
+
+ @Override
+ public PropertyValue get(String key) {
+ Map<String,String> properties = getProperties();
+ String val = properties.get(key);
+ if(val==null){
+ return null;
+ }
+ PropertyValueBuilder b = new PropertyValueBuilder(key, val, getName());
+ String metaKeyStart = "_" + key + ".";
+ for(Map.Entry<String,String> en:properties.entrySet()) {
+ if(en.getKey().startsWith(metaKeyStart)){
+ b.addContextData(en.getKey().substring(metaKeyStart.length()), en.getValue());
+ }
+ }
+ return b.build();
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ checkLoad();
+ return Collections.unmodifiableMap(this.properties);
+ }
+
+
+ private void checkLoad() {
+ if(file!=null && (lastRead+updateInterval)<System.currentTimeMillis()){
+ load();
+ }
+ }
+
+ /**
+ * loads the Properties from the given URL
+ *
+ * @throws IllegalStateException in case of an error while reading properties-file
+ */
+ private void load() {
+ try (InputStream stream = new FileInputStream(file)) {
+ Map<String, String> properties = new HashMap<>();
+ Properties props = new Properties();
+ props.load(stream);
+ for (String key : props.stringPropertyNames()) {
+ properties.put(key, props.getProperty(key));
+ }
+ this.lastRead = System.currentTimeMillis();
+ LOG.log(Level.FINEST, "Loaded properties from " + file);
+ this.properties = properties;
+ } catch (IOException e) {
+ LOG.log(Level.FINEST, "Cannot load properties from " + file, e);
+ }
+ }
+
+ @Override
+ public void applyChange(ConfigChangeRequest change) {
+ if(change.isEmpty()){
+ LOG.info("Nothing to commit for transaction: " + change.getTransactionID());
+ return;
+ }
+ if(!file.exists()){
+ try {
+ if(!file.createNewFile()){
+ throw new ConfigException("Failed to create config file " + file);
+ }
+ } catch (IOException e) {
+ throw new ConfigException("Failed to create config file " + file, e);
+ }
+ }
+ for(Map.Entry<String,String> en:change.getAddedProperties().entrySet()){
+ int index = en.getKey().indexOf('?');
+ if(index>0){
+ this.properties.put(en.getKey().substring(0, index), en.getValue());
+ }else{
+ this.properties.put(en.getKey(), en.getValue());
+ }
+ }
+ for(String rmKey:change.getRemovedProperties()){
+ this.properties.remove(rmKey);
+ }
+ try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))){
+ Properties props = new Properties();
+ for (Map.Entry<String,String> en : this.properties.entrySet()) {
+ props.setProperty(en.getKey(), en.getValue());
+ }
+ props.store(bos, "Properties written from Tamaya on " + new Date());
+ bos.flush();
+ }
+ catch(Exception e){
+ throw new ConfigException("Failed to write config to " + file, e);
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutableXmlPropertiesPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutableXmlPropertiesPropertySource.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutableXmlPropertiesPropertySource.java
new file mode 100644
index 0000000..514ed1d
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutableXmlPropertiesPropertySource.java
@@ -0,0 +1,198 @@
+/*
+ * 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.mutableconfig.propertysources;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.mutableconfig.spi.ConfigChangeRequest;
+import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spi.PropertyValueBuilder;
+import org.apache.tamaya.spisupport.BasePropertySource;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Simple implementation of a mutable {@link org.apache.tamaya.spi.PropertySource} for .xml properties files.
+ */
+public class MutableXmlPropertiesPropertySource extends BasePropertySource
+implements MutablePropertySource{
+
+ /**
+ * The logger.
+ */
+ private static final Logger LOG = Logger.getLogger(MutableXmlPropertiesPropertySource.class.getName());
+ /**
+ * Default update interval is 1 minute.
+ */
+ private static final long DEFAULT_UPDATE_INTERVAL = 60000L;
+
+ /**
+ * The property source name.
+ */
+ private String name;
+
+ /**
+ * The configuration resource's URL.
+ */
+ private File file;
+
+ /**
+ * Timestamp of last read.
+ */
+ private long lastRead;
+
+ /**
+ * Interval, when the resource should try to update its contents.
+ */
+ private long updateInterval = DEFAULT_UPDATE_INTERVAL;
+ /**
+ * The current properties.
+ */
+ private Map<String, String> properties = new HashMap<>();
+
+ /**
+ * Creates a new Properties based PropertySource based on the given URL.
+ *
+ * @param propertiesLocation the URL encoded location, not null.
+ * @param defaultOrdinal the default ordinal to be used, when no ordinal is provided with the property
+ * source's properties.
+ */
+ public MutableXmlPropertiesPropertySource(File propertiesLocation, int defaultOrdinal) {
+ super(defaultOrdinal);
+ this.name = propertiesLocation.toString();
+ try {
+ this.file = propertiesLocation;
+ load();
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE, "Cannot convert file to URL: " + propertiesLocation, e);
+ }
+ }
+
+
+
+ @Override
+ public PropertyValue get(String key) {
+ Map<String,String> properties = getProperties();
+ String val = properties.get(key);
+ if(val==null){
+ return null;
+ }
+ PropertyValueBuilder b = new PropertyValueBuilder(key, val, getName());
+ String metaKeyStart = "_" + key + ".";
+ for(Map.Entry<String,String> en:properties.entrySet()) {
+ if(en.getKey().startsWith(metaKeyStart)){
+ b.addContextData(en.getKey().substring(metaKeyStart.length()), en.getValue());
+ }
+ }
+ return b.build();
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ checkLoad();
+ return Collections.unmodifiableMap(this.properties);
+ }
+
+
+ private void checkLoad() {
+ if(file!=null && (lastRead+updateInterval)<System.currentTimeMillis()){
+ load();
+ }
+ }
+
+ /**
+ * loads the Properties from the given URL
+ *
+ * @throws IllegalStateException in case of an error while reading properties-file
+ */
+ private void load() {
+ try (InputStream stream = new FileInputStream(file)) {
+ Map<String, String> properties = new HashMap<>();
+ Properties props = new Properties();
+ props.loadFromXML(stream);
+ for (String key : props.stringPropertyNames()) {
+ properties.put(key, props.getProperty(key));
+ }
+ this.lastRead = System.currentTimeMillis();
+ this.properties = properties;
+ LOG.log(Level.FINEST, "Loaded properties from " + file);
+ this.properties = properties;
+ } catch (IOException e) {
+ LOG.log(Level.FINEST, "Cannot load properties from " + file, e);
+ }
+ }
+
+ @Override
+ public void applyChange(ConfigChangeRequest configChange) {
+ if(configChange.isEmpty()){
+ LOG.info("Nothing to commit for transaction: " + configChange.getTransactionID());
+ return;
+ }
+ if(!file.exists()){
+ try {
+ if(!file.createNewFile()){
+ throw new ConfigException("Failed to create config file " + file);
+ }
+ } catch (IOException e) {
+ throw new ConfigException("Failed to create config file " + file, e);
+ }
+ }
+ for(Map.Entry<String,String> en:configChange.getAddedProperties().entrySet()){
+ int index = en.getKey().indexOf('?');
+ if(index>0){
+ this.properties.put(en.getKey().substring(0, index), en.getValue());
+ }else{
+ this.properties.put(en.getKey(), en.getValue());
+ }
+ }
+ for(String rmKey:configChange.getRemovedProperties()){
+ this.properties.remove(rmKey);
+ }
+ try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))){
+ Properties props = new Properties();
+ for (Map.Entry<String,String> en : this.properties.entrySet()) {
+ props.setProperty(en.getKey(), en.getValue());
+ }
+ props.storeToXML(bos, "Properties written from Tamaya on " + new Date());
+ bos.flush();
+ }
+ catch(Exception e){
+ throw new ConfigException("Failed to write config to " + file, e);
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/ConfigChangeRequest.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/ConfigChangeRequest.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/ConfigChangeRequest.java
new file mode 100644
index 0000000..2349ad1
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/ConfigChangeRequest.java
@@ -0,0 +1,176 @@
+/*
+ * 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.mutableconfig.spi;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Change context used for managing configuration changes within an
+ * {@link org.apache.tamaya.mutableconfig.spi.MutablePropertySource}.
+ */
+public final class ConfigChangeRequest {
+ /**
+ * The transaction id.
+ */
+ private String transactionId;
+ /**
+ * The starting point.
+ */
+ private long startedAt = System.currentTimeMillis();
+ /**
+ * The Properties.
+ */
+ private final Map<String,String> addedProperties = new HashMap<>();
+ /**
+ * The Removed.
+ */
+ private final Set<String> removedProperties = new HashSet<>();
+
+ /**
+ * Creates a new instance bound to the given transaction.
+ * @param transactionID the transaction ID, not null.
+ */
+ public ConfigChangeRequest(String transactionID){
+ this.transactionId = Objects.requireNonNull(transactionID);
+ }
+
+ /**
+ * Sets the started at value. By default {@link #startedAt} is already set on instance creation to
+ * {@code System.currentTimeMillis()}.
+ * @param startedAt the new UTC POSIX timestamp in millis.
+ */
+ public void setStartedAt(long startedAt) {
+ this.startedAt = startedAt;
+ }
+
+ /**
+ * Get the corresppnding transaction ID of this instance.
+ * @return the transaction ID, never null.
+ */
+ public String getTransactionID(){
+ return transactionId;
+ }
+
+ /**
+ * Timestamp in UTC millis, when this transaction (context) was created.
+ * @return the timestamp in millis.
+ */
+ public long getStartedAt(){
+ return startedAt;
+ }
+
+ /**
+ * Get an unmodifiable key/value map of properties added or updated.
+ * @return an unmodifiable key/value map of properties added or updated, never null.
+ */
+ public Map<String,String> getAddedProperties(){
+ return Collections.unmodifiableMap(addedProperties);
+ }
+
+ /**
+ * Get an unmodifiable key set of properties removed.
+ * @return an unmodifiable key set of properties removed, never null.
+ */
+ public Set<String> getRemovedProperties(){
+ return Collections.unmodifiableSet(removedProperties);
+ }
+
+ /**
+ * Adds/updates a new key/value pair.
+ * @param key the key, not null.
+ * @param value the value, not null.
+ */
+ public void put(String key, String value) {
+ this.addedProperties.put(key, value);
+ this.removedProperties.remove(key);
+ }
+
+ /**
+ * Add/updated multiple key/values.
+ * @param properties the keys and values to be added/updated, not null.
+ */
+ public void putAll(Map<String, String> properties) {
+ this.addedProperties.putAll(properties);
+ this.removedProperties.removeAll(properties.keySet());
+ }
+
+ /**
+ * Remove all the given keys, ir present.
+ * @param key the key to be removed, not null.
+ */
+ public void remove(String key) {
+ this.removedProperties.add(key);
+ this.addedProperties.remove(key);
+ }
+
+ /**
+ * Remove all the given keys, ir present.
+ * @param keys the keys to be removed, not null.
+ */
+ public void removeAll(Collection<String> keys) {
+ this.removedProperties.addAll(keys);
+ for(String k:keys) {
+ this.addedProperties.remove(k);
+ }
+ }
+
+ /**
+ * Allows easily to check if no additions/changes an no removals are present in the current transaction.
+ * @return true, if not actions have to be committed.
+ */
+ public boolean isEmpty() {
+ return this.addedProperties.isEmpty() && this.removedProperties.isEmpty();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof ConfigChangeRequest)) {
+ return false;
+ }
+ ConfigChangeRequest that = (ConfigChangeRequest) o;
+ return transactionId.equals(that.transactionId);
+
+ }
+
+ @Override
+ public int hashCode() {
+ return transactionId.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "ConfigChangeRequest{" +
+ "transactionId=" + transactionId +
+ ", startedAt=" + startedAt +
+ ", addedProperties=" + addedProperties +
+ ", removedProperties=" + removedProperties +
+ '}';
+ }
+
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationProviderSpi.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationProviderSpi.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationProviderSpi.java
new file mode 100644
index 0000000..4412085
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationProviderSpi.java
@@ -0,0 +1,42 @@
+/*
+ * 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.mutableconfig.spi;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.mutableconfig.ChangePropagationPolicy;
+import org.apache.tamaya.mutableconfig.MutableConfiguration;
+
+
+/**
+ * Provider SPI used by {@link org.apache.tamaya.mutableconfig.MutableConfigurationProvider}. Providers may override
+ * other providers registering with a higher {@link javax.annotation.Priority} value annotated.
+ */
+public interface MutableConfigurationProviderSpi {
+
+ /**
+ * Creates a new {@link MutableConfiguration} with {@code autoCommit = false} as default.
+ *
+ * @param configuration the configuration, not null.
+ * @param propagationPolicy policy that defines how changes are published to the property
+ * sources.
+ * @return a new mutable configuration instance.
+ */
+ MutableConfiguration createMutableConfiguration(Configuration configuration,
+ ChangePropagationPolicy propagationPolicy);
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutablePropertySource.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutablePropertySource.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutablePropertySource.java
new file mode 100644
index 0000000..b648341
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutablePropertySource.java
@@ -0,0 +1,47 @@
+/*
+ * 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.mutableconfig.spi;
+
+import org.apache.tamaya.spi.PropertySource;
+
+
+/**
+ * This interface models a writable backend for configuration data.
+ *
+ * As a consequence clients should first check, using the corresponding methods, if entries are to edited or removedProperties
+ * actually are eligible for change/creation or removal.
+ */
+public interface MutablePropertySource extends PropertySource {
+
+ /**
+ * Puts all given configuration entries. This method should check that all given properties are
+ * basically removable, as defined by #isWritable. If any of the passed keys is not writable during this initial
+ * check, the operation should not perform any configuration changes and throw a {@link org.apache.tamaya.ConfigException}. If errors
+ * occur afterwards, when the properties are effectively written back to the backends, the errors should be
+ * collected and returned as part of the ConfigException payload. Nevertheless the operation should in that case
+ * remove all entries as far as possible and abort the writing operation.
+ *
+ * @param configChange the {@link ConfigChangeRequest}, containing the transactionId used to isolate
+ * the change, the properties to be added/overridden and the property keys
+ * being removed.
+ * @throws org.apache.tamaya.ConfigException if any of the given properties could not be written, or the request is read-only.
+ */
+ void applyChange(ConfigChangeRequest configChange);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/main/resources/META-INF/services/org.apache.tamaya.mutableconfig.spi.MutableConfigurationProviderSpi
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/resources/META-INF/services/org.apache.tamaya.mutableconfig.spi.MutableConfigurationProviderSpi b/modules/mutable-config/src/main/resources/META-INF/services/org.apache.tamaya.mutableconfig.spi.MutableConfigurationProviderSpi
new file mode 100644
index 0000000..eb366fc
--- /dev/null
+++ b/modules/mutable-config/src/main/resources/META-INF/services/org.apache.tamaya.mutableconfig.spi.MutableConfigurationProviderSpi
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.mutableconfig.internal.DefaultMutableConfigurationSpi
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationProviderTest.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationProviderTest.java b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationProviderTest.java
new file mode 100644
index 0000000..b316b7d
--- /dev/null
+++ b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationProviderTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.mutableconfig;
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by atsticks on 26.08.16.
+ */
+public class MutableConfigurationProviderTest {
+ @Test
+ public void createMutableConfiguration() throws Exception {
+ assertNotNull(MutableConfigurationProvider.createMutableConfiguration());
+ }
+
+ @Test
+ public void createMutableConfiguration1() throws Exception {
+ MutableConfiguration cfg = MutableConfigurationProvider
+ .createMutableConfiguration(ConfigurationProvider.getConfiguration());
+ assertNotNull(cfg);
+ assertEquals(cfg.getChangePropagationPolicy(),
+ MutableConfigurationProvider.getApplyMostSignificantOnlyChangePolicy());
+ }
+
+ @Test
+ public void createMutableConfiguration2() throws Exception {
+ ChangePropagationPolicy policy = MutableConfigurationProvider.getApplySelectiveChangePolicy("blabla");
+ MutableConfiguration cfg = MutableConfigurationProvider
+ .createMutableConfiguration(ConfigurationProvider.getConfiguration(),
+ policy);
+ assertNotNull(cfg);
+ assertEquals(cfg.getChangePropagationPolicy(), policy);
+ }
+
+ @Test
+ public void createMutableConfiguration3() throws Exception {
+ ChangePropagationPolicy policy = MutableConfigurationProvider.getApplySelectiveChangePolicy("gugus");
+ MutableConfiguration cfg = MutableConfigurationProvider
+ .createMutableConfiguration(policy);
+ assertNotNull(cfg);
+ assertEquals(cfg.getChangePropagationPolicy(), policy);
+ }
+
+ @Test
+ public void getApplyAllChangePolicy() throws Exception {
+ assertNotNull(MutableConfigurationProvider.getApplyAllChangePolicy());
+ }
+
+ @Test
+ public void getApplyMostSignificantOnlyChangePolicy() throws Exception {
+ assertNotNull(MutableConfigurationProvider.getApplyMostSignificantOnlyChangePolicy());
+ }
+
+ @Test
+ public void getApplySelectiveChangePolicy() throws Exception {
+ assertNotNull(MutableConfigurationProvider.getApplySelectiveChangePolicy());
+ }
+
+ @Test
+ public void getApplyNonePolicy() throws Exception {
+ assertNotNull(MutableConfigurationProvider.getApplyNonePolicy());
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationTest.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationTest.java b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationTest.java
new file mode 100644
index 0000000..814f3ce
--- /dev/null
+++ b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationTest.java
@@ -0,0 +1,187 @@
+/*
+ * 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.mutableconfig;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.mutableconfig.internal.WritablePropertiesSource;
+import org.apache.tamaya.mutableconfig.internal.WritableXmlPropertiesSource;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for {@link MutableConfiguration}.
+ */
+public class MutableConfigurationTest {
+
+ /**
+ * Test create change request.
+ *
+ * @throws Exception the exception
+ */
+ @Test
+ public void testCreateMutableConfiguration() throws Exception {
+ File f = File.createTempFile("ConfigChangeRequest",".properties");
+ MutableConfiguration cfg1 = MutableConfigurationProvider.createMutableConfiguration(
+ ConfigurationProvider.getConfiguration(),
+ MutableConfigurationProvider.getApplyAllChangePolicy());
+ assertNotNull(cfg1);
+ assertNotNull(cfg1.getConfigChangeRequest());
+ MutableConfiguration cfg2 = MutableConfigurationProvider.createMutableConfiguration(
+ ConfigurationProvider.getConfiguration());
+ assertNotNull(cfg2);
+ assertNotNull(cfg2.getConfigChangeRequest());
+ assertTrue(cfg1!=cfg2);
+ assertTrue(cfg1.getConfigChangeRequest()!=cfg2.getConfigChangeRequest());
+ }
+
+ /**
+ * Test null create change request.
+ *
+ * @throws Exception the exception
+ */
+ @Test(expected=NullPointerException.class)
+ public void testNullCreateMutableConfiguration1() throws Exception {
+ MutableConfigurationProvider.createMutableConfiguration(
+ (Configuration) null);
+ }
+
+ /**
+ * Test null create change request.
+ *
+ * @throws Exception the exception
+ */
+ @Test(expected=NullPointerException.class)
+ public void testNullCreateMutableConfiguration2() throws Exception {
+ MutableConfigurationProvider.createMutableConfiguration(
+ (ChangePropagationPolicy) null);
+ }
+
+ /**
+ * Test read write properties with rollback.
+ *
+ * @throws IOException the io exception
+ */
+ @Test
+ public void testReadWriteProperties_WithCancel() throws IOException {
+ WritablePropertiesSource.target.delete();
+ MutableConfiguration mutConfig = MutableConfigurationProvider.createMutableConfiguration(
+ ConfigurationProvider.getConfiguration()
+ );
+ mutConfig.put("key1", "value1");
+ Map<String,String> cm = new HashMap<>();
+ cm.put("key2", "value2");
+ cm.put("key3", "value3");
+ }
+
+ /**
+ * Test read write properties with commit.
+ *
+ * @throws IOException the io exception
+ */
+ @Test
+ public void testReadWriteProperties_WithCommit() throws IOException {
+ WritablePropertiesSource.target.delete();
+ MutableConfiguration mutConfig = MutableConfigurationProvider.createMutableConfiguration(
+ ConfigurationProvider.getConfiguration()
+ );
+ mutConfig.put("key1", "value1");
+ Map<String,String> cm = new HashMap<>();
+ cm.put("key2", "value2");
+ cm.put("key3", "value3");
+ mutConfig.putAll(cm);
+ mutConfig.store();
+ assertTrue(WritablePropertiesSource.target.exists());
+ MutableConfiguration mmutConfig2 = MutableConfigurationProvider.createMutableConfiguration(
+ ConfigurationProvider.getConfiguration()
+ );
+ mmutConfig2.remove("foo");
+ mmutConfig2.remove("key3");
+ mmutConfig2.put("key1", "value1.2");
+ mmutConfig2.put("key4", "value4");
+ mmutConfig2.store();
+ Properties props = new Properties();
+ props.load(WritablePropertiesSource.target.toURL().openStream());
+ assertEquals(3, props.size());
+ assertEquals("value1.2", props.getProperty("key1"));
+ assertEquals("value2", props.getProperty("key2"));
+ assertEquals("value4", props.getProperty("key4"));
+ }
+
+ /**
+ * Test read write xml properties with commit.
+ *
+ * @throws IOException the io exception
+ */
+ @Test
+ public void testReadWriteXmlProperties_WithCommit() throws IOException {
+ WritableXmlPropertiesSource.target.delete();
+ MutableConfiguration cfg = MutableConfigurationProvider.createMutableConfiguration(
+ ConfigurationProvider.getConfiguration(), MutableConfigurationProvider.getApplyAllChangePolicy());
+ cfg.put("key1", "value1");
+ Map<String,String> cm = new HashMap<>();
+ cm.put("key2", "value2");
+ cm.put("key3", "value3");
+ cfg.putAll(cm);
+ cfg.store();
+ assertTrue(WritableXmlPropertiesSource.target.exists());
+ MutableConfiguration cfg2 = MutableConfigurationProvider.createMutableConfiguration(
+ ConfigurationProvider.getConfiguration());
+ assertTrue(cfg != cfg2);
+ cfg2.remove("foo");
+ cfg2.remove("key3");
+ cfg2.put("key1", "value1.2");
+ cfg2.put("key4", "value4");
+ cfg2.store();
+ Properties props = new Properties();
+ props.loadFromXML( WritableXmlPropertiesSource.target.toURL().openStream());
+ assertEquals(3, props.size());
+ assertEquals("value1", props.getProperty("key1"));
+ assertEquals("value2", props.getProperty("key2"));
+ }
+
+ /**
+ * Test read write xml properties with commit.
+ *
+ * @throws IOException the io exception
+ */
+ @Test
+ public void testWriteWithNoChangePolicy() throws IOException {
+ WritableXmlPropertiesSource.target.delete();
+ MutableConfiguration cfg = MutableConfigurationProvider.createMutableConfiguration(
+ ConfigurationProvider.getConfiguration(),
+ MutableConfigurationProvider.getApplyNonePolicy());
+ cfg.put("key1", "value1");
+ Map<String,String> cm = new HashMap<>();
+ cm.put("key2", "value2");
+ cm.put("key3", "value3");
+ cfg.putAll(cm);
+ cfg.store();
+ assertFalse(WritableXmlPropertiesSource.target.exists());
+ }
+
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendTest.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendTest.java b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendTest.java
new file mode 100644
index 0000000..e6c79f5
--- /dev/null
+++ b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/PropertiesFileConfigBackendTest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.mutableconfig.internal;
+
+import org.apache.tamaya.mutableconfig.propertysources.MutablePropertiesPropertySource;
+
+
+/**
+ * Tests for {@link MutablePropertiesPropertySource}.
+ */
+public class PropertiesFileConfigBackendTest {
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/WritablePropertiesSource.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/WritablePropertiesSource.java b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/WritablePropertiesSource.java
new file mode 100644
index 0000000..5257c8b
--- /dev/null
+++ b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/WritablePropertiesSource.java
@@ -0,0 +1,49 @@
+/*
+ * 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.mutableconfig.internal;
+
+import org.apache.tamaya.mutableconfig.propertysources.MutablePropertiesPropertySource;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Writable test property source based on the {@link MutablePropertiesPropertySource}.
+ */
+public class WritablePropertiesSource extends MutablePropertiesPropertySource {
+
+ public static File target = createFile();
+
+ private static File createFile() {
+ try {
+ return File.createTempFile("writableProps",".properties");
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new IllegalStateException("Cannot init test.", e);
+ }
+ }
+
+ /**
+ * Creates a new Properties based PropertySource based on the given URL.
+ */
+ public WritablePropertiesSource() throws IOException {
+ super(target, 100);
+ }
+
+}
[05/15] incubator-tamaya-extensions git commit: TAMAYA-189: Moved
format and injection modules into separate subtrees.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredFieldImpl.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredFieldImpl.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredFieldImpl.java
deleted file mode 100644
index 64b0c95..0000000
--- a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredFieldImpl.java
+++ /dev/null
@@ -1,170 +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.inject.internal;
-
-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.DynamicValue;
-import org.apache.tamaya.inject.api.InjectionUtils;
-import org.apache.tamaya.inject.spi.ConfiguredField;
-
-import java.lang.reflect.Field;
-import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
-import java.util.Collection;
-import java.util.Objects;
-
-/**
- * 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, converting any applying the
- * final keys by reflection.
- */
-public class ConfiguredFieldImpl implements ConfiguredField{
- /**
- * The configured field instance.
- */
- protected final Field annotatedField;
-
- /**
- * Models a configured field and provides mechanisms for injection.
- *
- * @param field the field instance.
- */
- public ConfiguredFieldImpl(Field field) {
- Objects.requireNonNull(field);
- this.annotatedField = field;
- }
-
-
- /**
- * Evaluate the initial keys fromMap the configuration and applyChanges it to the field.
- *
- * @param target the target instance.
- * @throws ConfigException if evaluation or conversion failed.
- */
- public void configure(Object target, Configuration config) throws ConfigException {
- if (this.annotatedField.getType() == DynamicValue.class) {
- applyDynamicValue(target);
- } else {
- applyValue(target, config, false);
- }
- }
-
-
- /**
- * This method instantiates and assigns a dynamic value.
- *
- * @param target the target instance, not null.
- * @throws ConfigException if the configuration required could not be resolved or converted.
- */
- private void applyDynamicValue(Object target) throws ConfigException {
- Objects.requireNonNull(target);
- try {
- AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
- @Override
- public Object run() throws Exception {
- annotatedField.setAccessible(true);
- return annotatedField;
- }
- });
- annotatedField.set(target,
- DefaultDynamicValue.of(annotatedField, ConfigurationProvider.getConfiguration()));
- } catch (Exception e) {
- throw new ConfigException("Failed to annotation configured field: " + this.annotatedField.getDeclaringClass()
- .getName() + '.' + annotatedField.getName(), e);
- }
- }
-
- /**
- * This method applies a configuration to the field.
- *
- * @param target the target instance, not null.
- * @param config The configuration to be used.
- * @param resolve set to true, if expression resolution should be applied on the keys passed.
- * @throws ConfigException if the configuration required could not be resolved or converted.
- */
- private void applyValue(Object target, Configuration config, boolean resolve) throws ConfigException {
- Objects.requireNonNull(target);
- try {
- String[] retKey = new String[1];
- String configValue = InjectionHelper.getConfigValue(this.annotatedField, retKey, config);
- // Next step perform expression resolution, if any
- String evaluatedValue = resolve && configValue != null
- ? InjectionHelper.evaluateValue(configValue)
- : configValue;
-
- // Check for adapter/filter
- Object value = InjectionHelper.adaptValue(this.annotatedField,
- TypeLiteral.of(this.annotatedField.getType()), retKey[0], evaluatedValue);
- AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
- @Override
- public Object run() throws Exception {
- annotatedField.setAccessible(true);
- return annotatedField;
- }
- });
- if(value!=null) {
- annotatedField.set(target, value);
- }
- } catch (Exception e) {
- throw new ConfigException("Failed to evaluate annotated field: " + this.annotatedField.getDeclaringClass()
- .getName() + '.' + annotatedField.getName(), e);
- }
- }
-
- /**
- * Get the field's type.
- * @return the field's type, not null.
- */
- @Override
- public Class<?> getType(){
- return this.annotatedField.getType();
- }
-
- /**
- * Access the applyable configuration keys for this field.
- * @return the configuration keys, never null.
- */
- @Override
- public Collection<String> getConfiguredKeys(){
- return InjectionUtils.getKeys(this.annotatedField);
- }
-
- @Override
- public String toString() {
- return "ConfiguredField[" + getSignature() + ']';
- }
-
- @Override
- public String getName() {
- return annotatedField.getName();
- }
-
- @Override
- public String getSignature() {
- return getName()+':'+getType().getName();
- }
-
- @Override
- public Field getAnnotatedField() {
- return annotatedField;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredSetterMethod.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredSetterMethod.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredSetterMethod.java
deleted file mode 100644
index b69df20..0000000
--- a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredSetterMethod.java
+++ /dev/null
@@ -1,139 +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.inject.internal;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.inject.api.InjectionUtils;
-import org.apache.tamaya.inject.spi.ConfiguredMethod;
-
-import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
-import java.util.Collection;
-import java.util.Objects;
-
-/**
- * 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.
- */
-public class ConfiguredSetterMethod implements ConfiguredMethod {
-
- /**
- * The configured field instance.
- */
- private Method setterMethod;
- private Collection<String> configuredKeys;
-
- /**
- * Models a configured field and provides mechanisms for injection.
- *
- * @param method the method instance.
- */
- public ConfiguredSetterMethod(Method method) {
- if (void.class.equals(method.getReturnType()) &&
- method.getParameterTypes().length == 1) {
- this.setterMethod = method;
- }
- }
-
- @Override
- public void configure(Object target, Configuration config) throws ConfigException {
- String[] retKey = new String[1];
- String configValue = InjectionHelper.getConfigValue(this.setterMethod, retKey, config);
- Objects.requireNonNull(target);
- try {
- String evaluatedString = configValue != null
- ? InjectionHelper.evaluateValue(configValue)
- : configValue;
-
- // Check for adapter/filter
- Object value = InjectionHelper.adaptValue(
- this.setterMethod, TypeLiteral.of(this.setterMethod.getParameterTypes()[0]),
- retKey[0], evaluatedString);
-
- AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
- @Override
- public Object run() throws Exception {
- setterMethod.setAccessible(true);
- return setterMethod;
- }
- });
-
- setterMethod.invoke(target, value);
- } catch (Exception e) {
- throw new ConfigException("Failed to annotation configured method: " + this.setterMethod.getDeclaringClass()
- .getName() + '.' + setterMethod.getName(), e);
- }
- }
-
-
- /**
- * Access the applyable configuration keys for this field.
- *
- * @return the configuration keys, never null.
- */
- @Override
- public Collection<String> getConfiguredKeys() {
- return InjectionUtils.getKeys(this.setterMethod);
- }
-
- /**
- * Get the type to be set on the setter method.
- * @return the setter type.
- */
- @Override
- public Class<?>[] getParameterTypes() {
- return this.setterMethod.getParameterTypes();
- }
-
- /**
- * Access the annotated method.
- * @return the annotated method, not null.
- */
- @Override
- public Method getAnnotatedMethod() {
- return this.setterMethod;
- }
-
- @Override
- public String getName() {
- return this.setterMethod.getName();
- }
-
- @Override
- public String getSignature() {
- return "void " + this.setterMethod.getName()+'('+ printTypes(getParameterTypes())+')';
- }
-
- private String printTypes(Class<?>[] parameterTypes) {
- StringBuilder b = new StringBuilder();
- for(Class cl:parameterTypes){
- b.append(cl.getName());
- b.append(',');
- }
- if(b.length()>0){
- b.setLength(b.length()-1);
- }
- return b.toString();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredTypeImpl.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredTypeImpl.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredTypeImpl.java
deleted file mode 100644
index b40f6c9..0000000
--- a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredTypeImpl.java
+++ /dev/null
@@ -1,237 +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.inject.internal;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.*;
-import java.util.logging.Logger;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.ConfigurationProvider;
-import org.apache.tamaya.inject.api.ConfigAutoInject;
-import org.apache.tamaya.inject.api.NoConfig;
-import org.apache.tamaya.inject.api.Config;
-import org.apache.tamaya.inject.api.ConfigDefaultSections;
-import org.apache.tamaya.inject.spi.ConfiguredField;
-import org.apache.tamaya.inject.spi.ConfiguredMethod;
-import org.apache.tamaya.inject.spi.ConfiguredType;
-
-/**
- * Structure that contains and manages configuration related things for a configured type registered.
- * Created by Anatole on 03.10.2014.
- */
-@SuppressWarnings({"rawtypes", "unchecked"})
-public class ConfiguredTypeImpl implements ConfiguredType{
- /** The log used. */
- private static final Logger LOG = Logger.getLogger(ConfiguredTypeImpl.class.getName());
- /**
- * A list with all annotated instance variables.
- */
- private final List<ConfiguredField> configuredFields = new ArrayList<>();
- /**
- * A list with all annotated methods (templates).
- */
- private final List<ConfiguredMethod> configuredSetterMethods = new ArrayList<>();
- /**
- * The basic type.
- */
- private final Class type;
-
- /**
- * Creates an instance of this class hereby evaluating the config annotations given for later effective
- * injection (configuration) of instances.
- *
- * @param type the instance type.
- */
- public ConfiguredTypeImpl(Class type) {
- this.type = Objects.requireNonNull(type);
- if(!isConfigured(type)){
- LOG.info("Auto-Configuring type: " + type.getName());
- initFields(type, true);
- initMethods(type, true);
- }else {
- ConfigAutoInject autoInject = (ConfigAutoInject) type.getAnnotation(ConfigAutoInject.class);
- if (autoInject != null) {
- initFields(type, autoInject != null);
- initMethods(type, autoInject != null);
- } else {
- initFields(type, false);
- initMethods(type, false);
- }
- }
- }
-
- private void initFields(Class type, boolean autoConfigure) {
- for (Field f : type.getDeclaredFields()) {
- if (f.isAnnotationPresent(NoConfig.class)) {
- LOG.finest("Ignored @NoConfig annotated field " + f.getClass().getName() + "#" +
- f.toGenericString());
- continue;
- }
- if (Modifier.isFinal(f.getModifiers())) {
- LOG.finest("Ignored final field " + f.getClass().getName() + "#" +
- f.toGenericString());
- continue;
- }
- if (f.isSynthetic()) {
- LOG.finest("Ignored synthetic field " + f.getClass().getName() + "#" +
- f.toGenericString());
- continue;
- }
- try {
- if(isConfiguredField(f) || autoConfigure) {
- ConfiguredField configuredField = new ConfiguredFieldImpl(f);
- configuredFields.add(configuredField);
- LOG.finer("Registered field " + f.getClass().getName() + "#" +
- f.toGenericString());
- }
- } catch (Exception e) {
- throw new ConfigException("Failed to initialized configured field: " +
- f.getDeclaringClass().getName() + '.' + f.getName(), e);
- }
- }
- }
-
- private void initMethods(Class type, boolean autoConfigure) {
- // TODO revisit this logic here...
- for (Method m : type.getDeclaredMethods()) {
- if (m.isAnnotationPresent(NoConfig.class)) {
- LOG.finest("Ignored @NoConfig annotated method " + m.getClass().getName() + "#" +
- m.toGenericString());
- continue;
- }
- if (m.isSynthetic()) {
- LOG.finest("Ignored synthetic method " + m.getClass().getName() + "#" +
- m.toGenericString());
- continue;
- }
- if(isConfiguredMethod(m) || autoConfigure) {
- Config propAnnot = m.getAnnotation(Config.class);
- if (addPropertySetter(m, propAnnot)) {
- LOG.finer("Added configured setter: " + m.getClass().getName() + "#" +
- m.toGenericString());
- }
- }
- }
- }
-
- private boolean addPropertySetter(Method m, Config prop) {
- if (prop!=null) {
- if (m.getParameterTypes().length == 1) {
- // getter method
- Class<?> returnType = m.getReturnType();
- if (void.class.equals(returnType)) {
- try {
- configuredSetterMethods.add(new ConfiguredSetterMethod(m));
- return true;
- } catch (Exception e) {
- throw new ConfigException("Failed to initialized configured setter method: " +
- m.getDeclaringClass().getName() + '.' + m.getName(), e);
- }
- }
- }
- }
- return false;
- }
-
-
- /**
- * Method called to configure an instance.
- *
- * @param instance The instance to be configured.
- */
- public void configure(Object instance) {
- configure(instance, ConfigurationProvider.getConfiguration());
- }
-
- @Override
- public void configure(Object instance, Configuration config) {
- for (ConfiguredField field : configuredFields) {
- field.configure(instance, config);
- }
- for (ConfiguredMethod method : configuredSetterMethods) {
- method.configure(instance, config);
-// // TODO, if method should be recalled on changes, corresponding callbacks could be registered here
- }
- }
-
-
- public static boolean isConfigured(Class type) {
- if (type.getAnnotation(ConfigDefaultSections.class) != null) {
- return true;
- }
- // if no class level annotation is there we might have field level annotations only
- for (Field field : type.getDeclaredFields()) {
- if (isConfiguredField(field)) {
- return true;
- }
- }
- // if no class level annotation is there we might have method level annotations only
- for (Method method : type.getDeclaredMethods()) {
- if(isConfiguredMethod(method)) {
- return true;
- }
- }
- return false;
- }
-
- public static boolean isConfiguredField(Field field) {
- return field.isAnnotationPresent(Config.class);
- }
-
- public static boolean isConfiguredMethod(Method method) {
- return method.isAnnotationPresent(Config.class);
- }
-
- @Override
- public Class getType() {
- return this.type;
- }
-
- @Override
- public String getName() {
- return this.type.getName();
- }
-
- /**
- * Get the registered configured fields.
- * @return the registered configured fields, never null.
- */
- @Override
- public Collection<ConfiguredField> getConfiguredFields(){
- return configuredFields;
- }
-
- /**
- * Get the registered annotated setter methods.
- * @return the registered annotated setter methods, never null.
- */
- @Override
- public Collection<ConfiguredMethod> getConfiguredMethods(){
- return configuredSetterMethods;
- }
-
- @Override
- public String toString() {
- return "ConfigDefaultSections{"+ this.getType().getName() + '}';
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/main/java/org/apache/tamaya/inject/internal/DefaultConfigurationInjector.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/DefaultConfigurationInjector.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/DefaultConfigurationInjector.java
deleted file mode 100644
index a3a7015..0000000
--- a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/DefaultConfigurationInjector.java
+++ /dev/null
@@ -1,179 +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.inject.internal;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.ConfigurationProvider;
-import org.apache.tamaya.inject.ConfigurationInjector;
-
-import javax.annotation.Priority;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Logger;
-
-import org.apache.tamaya.inject.api.ConfiguredItemSupplier;
-import org.apache.tamaya.inject.api.NoConfig;
-import org.apache.tamaya.inject.api.Config;
-import org.apache.tamaya.inject.api.ConfigDefaultSections;
-import org.apache.tamaya.inject.spi.ConfiguredType;
-
-/**
- * Simple injector singleton that also registers instances configured using weak references.
- */
-@Priority(0)
-public final class DefaultConfigurationInjector implements ConfigurationInjector {
-
- private final Map<Class<?>, ConfiguredType> configuredTypes = new ConcurrentHashMap<>();
-
- private static final Logger LOG = Logger.getLogger(DefaultConfigurationInjector.class.getName());
-
- private boolean autoConfigureEnabled = true;
-
- /**
- * Extract the configuration annotation config and registers it per class, for later reuse.
- *
- * @param type the type to be configured.
- * @return the configured type registered.
- */
- public ConfiguredType registerType(Class<?> type) {
- ConfiguredType confType = configuredTypes.get(type);
- if (confType == null) {
- if(!isConfigAnnotated(type) && !autoConfigureEnabled){
- return null;
- }
- confType = new ConfiguredTypeImpl(type);
- configuredTypes.put(type, confType);
- InjectionHelper.sendConfigurationEvent(confType);
- }
- return confType;
- }
-
- /**
- * If set also non annotated instances can be configured or created as templates.
- * @return true, if autoConfigureEnabled.
- */
- public boolean isAutoConfigureEnabled(){
- return autoConfigureEnabled;
- }
-
- /**
- * Setting to true enables also configuration/templating of non annotated classes or
- * interfaces.
- * @param enabled true enables also configuration/templating of
- */
- public void setAutoConfigureEnabled(boolean enabled){
- this.autoConfigureEnabled = enabled;
- }
-
- /**
- * CHecks if type is eligible for configuration injection.
- * @param type the target type, not null.
- * @return true, if the type, a method or field has Tamaya config annotation on it.
- */
- private boolean isConfigAnnotated(Class<?> type) {
- if(type.getClass().isAnnotationPresent(ConfigDefaultSections.class)){
- return true;
- }
- for (Field f : type.getDeclaredFields()) {
- if (f.isAnnotationPresent(NoConfig.class) || f.isAnnotationPresent(Config.class)) {
- return true;
- }
- }
- for (Method m : type.getDeclaredMethods()) {
- if (m.isAnnotationPresent(NoConfig.class) || m.isAnnotationPresent(Config.class)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Configured the current instance and reigsterd necessary listener to forward config change events as
- * defined by the current annotations in place.
- *
- * @param instance the instance to be configured
- */
- @Override
- public <T> T configure(T instance) {
- return configure(instance, ConfigurationProvider.getConfiguration());
- }
-
- /**
- * Configured the current instance and reigsterd necessary listener to forward config change events as
- * defined by the current annotations in place.
- *
- * @param instance the instance to be configured
- * @param config the target configuration, not null.
- */
- @Override
- public <T> T configure(T instance, Configuration config) {
- Class<?> type = Objects.requireNonNull(instance).getClass();
- ConfiguredType configuredType = registerType(type);
- if(configuredType!=null){
- configuredType.configure(instance, config);
- }else{
- LOG.info("Instance passed is not configurable: " + instance);
- }
- return instance;
- }
-
- /**
- * Create a template implementting the annotated methods based on current configuration data.
- *
- * @param templateType the type of the template to be created.
- */
- @Override
- public <T> T createTemplate(Class<T> templateType) {
- return createTemplate(templateType, ConfigurationProvider.getConfiguration());
- }
-
- /**
- * Create a template implementting the annotated methods based on current configuration data.
- *
- * @param templateType the type of the template to be created.
- * @param config the target configuration, not null.
- */
- @Override
- public <T> T createTemplate(Class<T> templateType, Configuration config) {
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- if(cl==null){
- cl = this.getClass().getClassLoader();
- }
- return templateType.cast(Proxy.newProxyInstance(cl, new Class[]{ConfiguredItemSupplier.class, Objects.requireNonNull(templateType)},
- new ConfigTemplateInvocationHandler(templateType)));
- }
-
- @Override
- public <T> ConfiguredItemSupplier<T> getConfiguredSupplier(final ConfiguredItemSupplier<T> supplier) {
- return getConfiguredSupplier(supplier, ConfigurationProvider.getConfiguration());
- }
-
- @Override
- public <T> ConfiguredItemSupplier<T> getConfiguredSupplier(final ConfiguredItemSupplier<T> supplier, final Configuration config) {
- return new ConfiguredItemSupplier<T>() {
- public T get() {
- return configure(supplier.get(), config);
- }
- };
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/main/java/org/apache/tamaya/inject/internal/DefaultDynamicValue.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/DefaultDynamicValue.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/DefaultDynamicValue.java
deleted file mode 100644
index 2f051b3..0000000
--- a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/DefaultDynamicValue.java
+++ /dev/null
@@ -1,498 +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.inject.internal;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.inject.api.BaseDynamicValue;
-import org.apache.tamaya.inject.api.DynamicValue;
-import org.apache.tamaya.inject.api.InjectionUtils;
-import org.apache.tamaya.inject.api.LoadPolicy;
-import org.apache.tamaya.inject.api.UpdatePolicy;
-import org.apache.tamaya.inject.api.WithPropertyConverter;
-import org.apache.tamaya.spi.ConversionContext;
-import org.apache.tamaya.spi.PropertyConverter;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-import java.util.logging.Logger;
-
-/**
- * A accessor for a single configured value. This can be used to support values that may change during runtime,
- * reconfigured or final. Hereby external code (could be Tamaya configuration listners or client code), can set a
- * new value. Depending on the {@link UpdatePolicy} the new value is immedeately active or it requires an active commit
- * by client code. Similarly an instance also can ignore all later changes to the value.
- * <h3>Implementation Details</h3>
- * This class is
- * <ul>
- * <li>Serializable, when also the item stored is serializable</li>
- * <li>Thread safe</li>
- * </ul>
- *
- * @param <T> The type of the value.
- */
-final class DefaultDynamicValue<T> extends BaseDynamicValue<T> {
-
- private static final long serialVersionUID = -2071172847144537443L;
-
- /**
- * The property name of the entry.
- */
- private final String propertyName;
- /**
- * The keys to be resolved.
- */
- private final String[] keys;
- /**
- * Back reference to the base configuration instance. This reference is used reevalaute the given property and
- * compare the result with the previous value after a configuration change was triggered.
- */
- private final Configuration configuration;
- /**
- * The target type of the property used to lookup a matching {@link PropertyConverter}.
- * If null, {@code propertyConverter} is set and used instead.
- */
- private final TypeLiteral<T> targetType;
- /**
- * The property converter to be applied, may be null. In the ladder case targetType is not null.
- */
- private final PropertyConverter<T> propertyConverter;
- /**
- * Policy that defines how new values are applied, be default it is applied initially once, but never updated
- * anymore.
- */
- private UpdatePolicy updatePolicy;
- /**
- * Load policy.
- */
- private final LoadPolicy loadPolicy;
-
- /**
- * The current value, never null.
- */
- private transient T value;
- /**
- * The new value, or null.
- */
- private transient Object[] newValue;
- /**
- * List of listeners that listen for changes.
- */
- private transient WeakList<PropertyChangeListener> listeners;
-
- /**
- * Constructor.
- *
- * @param propertyName the name of the fields' property/method.
- * @param keys the keys of the property, not null.
- * @param configuration the configuration, not null.
- * @param targetType the target type, not null.
- * @param propertyConverter the optional converter to be used.
- */
- private DefaultDynamicValue(String propertyName, Configuration configuration, TypeLiteral<T> targetType,
- PropertyConverter<T> propertyConverter, List<String> keys, LoadPolicy loadPolicy,
- UpdatePolicy updatePolicy) {
- this.propertyName = Objects.requireNonNull(propertyName);
- this.keys = keys.toArray(new String[keys.size()]);
- this.configuration = Objects.requireNonNull(configuration);
- this.propertyConverter = propertyConverter;
- this.targetType = targetType;
- this.loadPolicy = Objects.requireNonNull(loadPolicy);
- this.updatePolicy = Objects.requireNonNull(updatePolicy);
- if(loadPolicy == LoadPolicy.INITIAL){
- this.value = evaluateValue();
- }
- }
-
- public static DynamicValue of(Field annotatedField, Configuration configuration) {
- return of(annotatedField, configuration, LoadPolicy.ALWAYS, UpdatePolicy.IMMEDEATE);
- }
-
- public static DynamicValue of(Field annotatedField, Configuration configuration, LoadPolicy loadPolicy) {
- return of(annotatedField, configuration, loadPolicy, UpdatePolicy.IMMEDEATE);
- }
-
- public static DynamicValue of(Field annotatedField, Configuration configuration, UpdatePolicy updatePolicy) {
- return of(annotatedField, configuration, LoadPolicy.ALWAYS, updatePolicy);
- }
-
- public static DynamicValue of(Field annotatedField, Configuration configuration, LoadPolicy loadPolicy, UpdatePolicy updatePolicy) {
- // Check for adapter/filter
- Type targetType = annotatedField.getGenericType();
- if (targetType == null) {
- throw new ConfigException("Failed to evaluate target type for " + annotatedField.getDeclaringClass().getName()
- + '.' + annotatedField.getName());
- }
- if (targetType instanceof ParameterizedType) {
- ParameterizedType pt = (ParameterizedType) targetType;
- Type[] types = pt.getActualTypeArguments();
- if (types.length != 1) {
- throw new ConfigException("Failed to evaluate target type for " + annotatedField.getDeclaringClass().getName()
- + '.' + annotatedField.getName());
- }
- targetType = types[0];
- }
- PropertyConverter<?> propertyConverter = null;
- WithPropertyConverter annot = annotatedField.getAnnotation(WithPropertyConverter.class);
- if (annot != null) {
- try {
- propertyConverter = annot.value().newInstance();
- } catch (Exception e) {
- throw new ConfigException("Failed to instantiate annotated PropertyConverter on " +
- annotatedField.getDeclaringClass().getName()
- + '.' + annotatedField.getName(), e);
- }
- }
- List<String> keys = InjectionUtils.getKeys(annotatedField);
- return new DefaultDynamicValue(annotatedField.getName(), configuration,
- TypeLiteral.of(targetType), propertyConverter, keys, loadPolicy, updatePolicy);
- }
-
- public static DynamicValue of(Method method, Configuration configuration) {
- return of(method, configuration, LoadPolicy.ALWAYS, UpdatePolicy.IMMEDEATE);
- }
-
- public static DynamicValue of(Method method, Configuration configuration, UpdatePolicy updatePolicy) {
- return of(method, configuration, LoadPolicy.ALWAYS, updatePolicy);
- }
-
- public static DynamicValue of(Method method, Configuration configuration, LoadPolicy loadPolicy) {
- return of(method, configuration, loadPolicy, UpdatePolicy.IMMEDEATE);
- }
-
- public static DynamicValue of(Method method, Configuration configuration, LoadPolicy loadPolicy, UpdatePolicy updatePolicy) {
- // Check for adapter/filter
- Type targetType = method.getGenericReturnType();
- if (targetType == null) {
- throw new ConfigException("Failed to evaluate target type for " + method.getDeclaringClass()
- .getName() + '.' + method.getName());
- }
- if (targetType instanceof ParameterizedType) {
- ParameterizedType pt = (ParameterizedType) targetType;
- Type[] types = pt.getActualTypeArguments();
- if (types.length != 1) {
- throw new ConfigException("Failed to evaluate target type for " + method.getDeclaringClass()
- .getName() + '.' + method.getName());
- }
- targetType = types[0];
- }
- PropertyConverter<Object> propertyConverter = null;
- WithPropertyConverter annot = method.getAnnotation(WithPropertyConverter.class);
- if (annot != null) {
- try {
- propertyConverter = (PropertyConverter<Object>) annot.value().newInstance();
- } catch (Exception e) {
- throw new ConfigException("Failed to instantiate annotated PropertyConverter on " +
- method.getDeclaringClass().getName()
- + '.' + method.getName(), e);
- }
- }
- return new DefaultDynamicValue<>(method.getName(),
- configuration, TypeLiteral.of(targetType), propertyConverter, InjectionUtils.getKeys(method),
- loadPolicy, updatePolicy);
- }
-
-
- /**
- * Commits a new value that has not been committed yet, make it the new value of the instance. On change any
- * registered listeners will be triggered.
- */
- public void commit() {
- T oldValue = value;
- value = newValue==null?null:(T)newValue[0];
- newValue = null;
- informListeners(oldValue, value);
- }
-
- private void informListeners(T value, T newValue) {
- synchronized (this) {
- PropertyChangeEvent evt = new PropertyChangeEvent(this, propertyName, value,
- newValue);
- if (listeners != null) {
- for (PropertyChangeListener consumer : listeners.get()) {
- consumer.propertyChange(evt);
- }
- }
- }
- }
-
- /**
- * Discards a new value that was published. No listeners will be informed.
- */
- public void discard() {
- newValue = null;
- }
-
-
- /**
- * Access the {@link UpdatePolicy} used for updating this value.
- *
- * @return the update policy, never null.
- */
- public UpdatePolicy getUpdatePolicy() {
- return updatePolicy;
- }
-
- /**
- * Sets a new {@link UpdatePolicy}.
- *
- * @param updatePolicy the new policy, not null.
- */
- public void setUpdatePolicy(UpdatePolicy updatePolicy) {
- this.updatePolicy = Objects.requireNonNull(updatePolicy);
- }
-
- /**
- * Add a listener to be called as weak reference, when this value has been changed.
- *
- * @param l the listener, not null
- */
- public void addListener(PropertyChangeListener l) {
- if (listeners == null) {
- listeners = new WeakList<>();
- }
- listeners.add(l);
- }
-
- /**
- * Removes a listener to be called, when this value has been changed.
- *
- * @param l the listner to be removed, not null
- */
- public void removeListener(PropertyChangeListener l) {
- if (listeners != null) {
- listeners.remove(l);
- }
- }
-
- /**
- * If a value is present in this {@code DynamicValue}, returns the value,
- * otherwise throws {@code ConfigException}.
- *
- * @return the non-null value held by this {@code Optional}
- * @throws ConfigException if there is no value present
- * @see DefaultDynamicValue#isPresent()
- */
- public T get() {
- T newLocalValue;
- if(loadPolicy!=LoadPolicy.INITIAL) {
- newLocalValue = evaluateValue();
- if (this.value == null) {
- this.value = newLocalValue;
- }
- if(!Objects.equals(this.value, newLocalValue)){
- switch (updatePolicy){
- case IMMEDEATE:
- commit();
- break;
- case EXPLCIT:
- this.newValue = new Object[]{newLocalValue};
- break;
- case LOG_ONLY:
- informListeners(this.value, newLocalValue);
- this.newValue = null;
- break;
- case NEVER:
- this.newValue = null;
- break;
- default:
- this.newValue = null;
- break;
- }
- }
- }
- return value;
- }
-
- /**
- * Method to check for and apply a new value. Depending on the {@link UpdatePolicy}
- * the value is immediately or deferred visible (or it may even be ignored completely).
- *
- * @return true, if a new value has been detected. The value may not be visible depending on the current
- * {@link UpdatePolicy} in place.
- */
- public boolean updateValue() {
- if(this.value==null && this.newValue==null){
- this.value = evaluateValue();
- return false;
- }
- T newValue = evaluateValue();
- if (Objects.equals(newValue, this.value)) {
- return false;
- }
- switch (this.updatePolicy) {
- case LOG_ONLY:
- Logger.getLogger(getClass().getName()).info("Discard change on " + this + ", newValue=" + newValue);
- informListeners(value, newValue);
- this.newValue = null;
- break;
- case NEVER:
- this.newValue = null;
- break;
- case EXPLCIT:
- case IMMEDEATE:
- default:
- this.newValue = new Object[]{newValue};
- commit();
- break;
- }
- return true;
- }
-
- /**
- * Evaluates the current value dynamically from the underlying configuration.
- *
- * @return the current actual value, or null.
- */
- public T evaluateValue() {
- T value = null;
-
- for (String key : keys) {
- ConversionContext ctx = new ConversionContext.Builder(key, targetType).build();
- if (propertyConverter == null) {
- value = configuration.get(key, targetType);
- } else {
- String source = configuration.get(key);
- value = propertyConverter.convert(source, ctx);
- }
-
- if (value != null) {
- break;
- }
- }
-
- return value;
- }
-
- /**
- * Access a new value that has not yet been committed.
- *
- * @return the uncommitted new value, or null.
- */
- public T getNewValue() {
- T nv = newValue==null?null:(T)newValue[0];
- if (nv != null) {
- return nv;
- }
- return null;
- }
-
-
- /**
- * Serialization implementation that strips away the non serializable Optional part.
- *
- * @param oos the output stream
- * @throws IOException if serialization fails.
- */
- private void writeObject(ObjectOutputStream oos) throws IOException {
- oos.writeObject(getUpdatePolicy());
- oos.writeObject(get());
- }
-
- /**
- * Reads an instance from the input stream.
- *
- * @param ois the object input stream
- * @throws IOException if deserialization fails.
- * @throws ClassNotFoundException
- */
- private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
- this.updatePolicy = (UpdatePolicy) ois.readObject();
- if (isPresent()) {
- this.value = (T) ois.readObject();
- }
- newValue = null;
- }
-
-
- /**
- * Simple helper that allows keeping the listeners registered as weak references, hereby avoiding any
- * memory leaks.
- *
- * @param <I> the type
- */
- private class WeakList<I> {
- final List<WeakReference<I>> refs = new LinkedList<>();
-
- /**
- * Adds a new instance.
- *
- * @param t the new instance, not null.
- */
- void add(I t) {
- refs.add(new WeakReference<>(t));
- }
-
- /**
- * Removes a instance.
- *
- * @param t the instance to be removed.
- */
- void remove(I t) {
- synchronized (refs) {
- for (Iterator<WeakReference<I>> iterator = refs.iterator(); iterator.hasNext(); ) {
- WeakReference<I> ref = iterator.next();
- I instance = ref.get();
- if (instance == null || instance == t) {
- iterator.remove();
- break;
- }
- }
- }
- }
-
-
- /**
- * Access a list (copy) of the current instances that were not discarded by the GC.
- *
- * @return the list of accessible items.
- */
- public List<I> get() {
- synchronized (refs) {
- List<I> res = new ArrayList<>();
- for (Iterator<WeakReference<I>> iterator = refs.iterator(); iterator.hasNext(); ) {
- WeakReference<I> ref = iterator.next();
- I instance = ref.get();
- if (instance == null) {
- iterator.remove();
- } else {
- res.add(instance);
- }
- }
- return res;
- }
- }
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/main/java/org/apache/tamaya/inject/internal/InjectionHelper.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/InjectionHelper.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/InjectionHelper.java
deleted file mode 100644
index 305a660..0000000
--- a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/InjectionHelper.java
+++ /dev/null
@@ -1,244 +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.inject.internal;
-
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.ConfigurationProvider;
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.events.ConfigEventManager;
-import org.apache.tamaya.events.spi.BaseConfigEvent;
-import org.apache.tamaya.inject.api.Config;
-import org.apache.tamaya.inject.api.ConfigDefaultSections;
-import org.apache.tamaya.inject.api.InjectionUtils;
-import org.apache.tamaya.inject.api.WithPropertyConverter;
-import org.apache.tamaya.inject.spi.ConfiguredType;
-import org.apache.tamaya.resolver.spi.ExpressionEvaluator;
-import org.apache.tamaya.spi.ConfigurationContext;
-import org.apache.tamaya.spi.ConversionContext;
-import org.apache.tamaya.spi.PropertyConverter;
-import org.apache.tamaya.spi.ServiceContextManager;
-
-
-/**
- * Utility class containing several aspects used in this module.
- */
-@SuppressWarnings("unchecked")
-final class InjectionHelper {
-
- private static final Logger LOG = Logger.getLogger(InjectionHelper.class.getName());
-
- private static final boolean RESOLUTION_MODULE_LOADED = checkResolutionModuleLoaded();
-
- private static final boolean EVENTS_AVAILABLE = checkForEvents();
-
- private static boolean checkForEvents() {
- try{
- Class.forName("org.apache.tamaya.events.FrozenConfiguration");
- LOG.info("Detected tamaya-events is loaded, will trigger ConfigEvents...");
- return true;
- } catch(Exception e){
- LOG.info("Detected tamaya-events not found, will not trigger any ConfigEvents...");
- return false;
- }
- }
-
- private static boolean checkResolutionModuleLoaded() {
- try {
- Class.forName("org.apache.tamaya.resolver.internal.DefaultExpressionEvaluator");
- return true;
- } catch (ClassNotFoundException e) {
- return false;
- }
- }
-
- private InjectionHelper() {
- }
-
- /**
- * Internally evaluated the current valid configuration keys based on the given annotations present.
- * @param method the method
- * @return the keys to be returned, or null.
- */
- public static String getConfigValue(Method method, Configuration config) {
- return getConfigValue(method, null, config);
- }
-
- /**
- * Internally evaluated the current valid configuration keys based on the given annotations present.
- * @param method the method
- * @param retKey the array to return the key found, or null.
- * @return the keys to be returned, or null.
- */
- public static String getConfigValue(Method method, String[] retKey, Configuration config) {
- ConfigDefaultSections areasAnnot = method.getDeclaringClass().getAnnotation(ConfigDefaultSections.class);
- return getConfigValueInternal(method, areasAnnot, retKey, config);
- }
-
- /**
- * Internally evaluated the current valid configuration keys based on the given annotations present.
- * @param field the field
- * @return the keys to be returned, or null.
- */
- public static String getConfigValue(Field field, Configuration config) {
- return getConfigValue(field, null, config);
- }
-
- /**
- * Internally evaluated the current valid configuration keys based on the given annotations present.
- * @param field the field
- * @param retKey the array to return the key found, or null.
- * @return the keys to be returned, or null.
- */
- public static String getConfigValue(Field field, String[] retKey, Configuration config) {
- ConfigDefaultSections areasAnnot = field.getDeclaringClass().getAnnotation(ConfigDefaultSections.class);
- return getConfigValueInternal(field, areasAnnot, retKey, config);
- }
-
- /**
- * Internally evaluated the current valid configuration keys based on the given annotations present.
- *
- * @return the keys to be returned, or null.
- */
- private static String getConfigValueInternal(AnnotatedElement element, ConfigDefaultSections areasAnnot, String[] retKey, Configuration config) {
- Config prop = element.getAnnotation(Config.class);
- List<String> keys;
- if (prop == null) {
- keys = InjectionUtils.evaluateKeys((Member) element, areasAnnot);
- } else {
- keys = InjectionUtils.evaluateKeys((Member) element, areasAnnot, prop);
- }
- String configValue = evaluteConfigValue(keys, retKey, config);
- if (configValue == null) {
- if(prop==null || prop.defaultValue().isEmpty()){
- return null;
- }
- return prop.defaultValue();
- }
- return configValue;
- }
-
-
- private static String evaluteConfigValue(List<String> keys, String[] retKey, Configuration config) {
- String configValue = null;
- for (String key : keys) {
- configValue = config.get(key);
- if (configValue != null) {
- if(retKey!=null && retKey.length>0){
- retKey[0] = key;
- }
- break;
- }
- }
- return configValue;
- }
-
-
- @SuppressWarnings("rawtypes")
- public static <T> T adaptValue(AnnotatedElement element, TypeLiteral<T> targetType, String key, String configValue) {
- // Check for adapter/filter
- T adaptedValue = null;
- WithPropertyConverter converterAnnot = element.getAnnotation(WithPropertyConverter.class);
- Class<? extends PropertyConverter<T>> converterType;
- if (converterAnnot != null) {
- converterType = (Class<? extends PropertyConverter<T>>) converterAnnot.value();
- if (!converterType.getName().equals(WithPropertyConverter.class.getName())) {
- try {
- // TODO cache here...
- ConversionContext ctx = new ConversionContext.Builder(key,targetType)
- .setAnnotatedElement(element).build();
-
- PropertyConverter<T> converter = PropertyConverter.class.cast(converterType.newInstance());
- adaptedValue = converter.convert(configValue, ctx);
- } catch (Exception e) {
- LOG.log(Level.SEVERE, "Failed to convert using explicit PropertyConverter on " + element +
- ", trying default conversion.", e);
- }
- }
- }
- if (adaptedValue != null) {
- return adaptedValue;
- }
- if (String.class == targetType.getType()) {
- return (T) configValue;
- } else{
- if(configValue==null) {
- return null;
- }
- ConfigurationContext configContext = ConfigurationProvider.getConfiguration().getContext();
- List<PropertyConverter<T>> converters = configContext
- .getPropertyConverters(targetType);
- ConversionContext ctx = new ConversionContext.Builder(ConfigurationProvider.getConfiguration(),
- configContext, key, targetType).setAnnotatedElement(element).build();
- for (PropertyConverter<T> converter : converters) {
- adaptedValue = converter.convert(configValue, ctx);
- if (adaptedValue != null) {
- return adaptedValue;
- }
- }
- }
- throw new ConfigException("Non convertible property type: " + element);
- }
-
- /**
- * Method that allows to statically check, if the resolver module is loaded. If the module is loaded
- * value expressions are automatically forwarded to the resolver module for resolution.
- *
- * @return true, if the resolver module is on the classpath.
- */
- public static boolean isResolutionModuleLoaded() {
- return RESOLUTION_MODULE_LOADED;
- }
-
- /**
- * Evaluates the given expression.
- *
- * @param expression the expression, not null.
- * @return the evaluated expression.
- */
- public static String evaluateValue(String expression) {
- if (!RESOLUTION_MODULE_LOADED) {
- return expression;
- }
- ExpressionEvaluator evaluator = ServiceContextManager.getServiceContext().getService(ExpressionEvaluator.class);
- if (evaluator != null) {
- return evaluator.evaluateExpression("<injection>", expression, true);
- }
- return expression;
- }
-
- /**
- * This method distributes the configuration event, if the Tamaya event module is accessible.
- * When Tamaya events are not available, the call simply returns.
- * @param event the event to be distributed, not null.
- */
- static void sendConfigurationEvent(ConfiguredType event) {
- if(EVENTS_AVAILABLE){
- ConfigEventManager.fireEvent(new BaseConfigEvent<ConfiguredType>(event, ConfiguredType.class) {});
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/main/java/org/apache/tamaya/inject/internal/Utils.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/Utils.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/Utils.java
deleted file mode 100644
index 2c08467..0000000
--- a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/Utils.java
+++ /dev/null
@@ -1,128 +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.inject.internal;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Utility class simplifying some implementation aspects.
- * Created by Anatole on 11.11.2014.
- */
-@SuppressWarnings("unchecked")
-public final class Utils {
-
- private static final Logger LOG = Logger.getLogger(Utils.class.getName());
-
- private Utils() {
- }
-
- /**
- * Utility method to read out repeatable annotations.
- *
- * @param annotated the annotated instance.
- * @param repeatableAnnotation the repeatable annotation type
- * @param annotationContainer the container annotation type
- * @param <T> the repeatable annotation type
- * @param <R> the repeatable container annotation type
- * @return a list with the annotations found (could be empty, but never null).
- */
- public static <T extends Annotation, R extends Annotation> Collection<T>
- getAnnotations(AnnotatedElement annotated,
- Class<T> repeatableAnnotation,
- Class<R> annotationContainer) {
- List<T> result = new ArrayList<>();
- R containerAnnot = annotated.getAnnotation(annotationContainer);
- if (containerAnnot != null) {
- Method valueMethod;
- try {
- valueMethod = annotationContainer.getMethod("keys");
- result.addAll(Arrays.asList((T[]) valueMethod.invoke(containerAnnot)));
- } catch (Exception e) {
- LOG.log(Level.SEVERE, "Failed to evaluate repeatable annotation.", e);
- }
- } else {
- T annot = annotated.getAnnotation(repeatableAnnotation);
- if (annot != null) {
- result.add(annot);
- }
- }
- return result;
- }
-
- /**
- * Utility method to read out repeatable annotations.
- *
- * @param annotated the annotated instance.
- * @param repeatableAnnotation the repeatable annotation type
- * @param annotationContainer the container annotation type
- * @param <T> the repeatable annotation type
- * @param <R> the repeatable container annotation type
- * @return a list with the annotations found (could be empty, but never null).
- */
- public static <T extends Annotation, R extends Annotation> Collection<T>
- getAnnotations(AccessibleObject annotated,
- Class<T> repeatableAnnotation,
- Class<R> annotationContainer) {
- List<T> result = new ArrayList<>();
- R containerAnnot = annotated.getAnnotation(annotationContainer);
- if (containerAnnot != null) {
- Method valueMethod;
- try {
- valueMethod = annotationContainer.getMethod("keys");
- result.addAll(Arrays.asList((T[]) valueMethod.invoke(containerAnnot)));
- } catch (Exception e) {
- LOG.log(Level.SEVERE, "Failed to evaluate repeatable annotation.", e);
- }
- } else {
- T annot = annotated.getAnnotation(repeatableAnnotation);
- if (annot != null) {
- result.add(annot);
- }
- }
- return result;
- }
-
- /**
- * Utility method to read out repeatable annotations.
- *
- * @param annotationType the annotation type.
- * @param objects the accessible objects to be looked up
- * @param <T> the repeatable annotation type
- * @return a list with the annotations found (could be empty, but never null).
- */
- public static <T extends Annotation> T getAnnotation(
- Class<T> annotationType, AnnotatedElement... objects) {
- for (AnnotatedElement obj : objects) {
- T annot = obj.getAnnotation(annotationType);
- if (annot != null) {
- return annot;
- }
- }
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/main/java/org/apache/tamaya/inject/internal/package-info.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/package-info.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/package-info.java
deleted file mode 100644
index 55e8cf6..0000000
--- a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/package-info.java
+++ /dev/null
@@ -1,22 +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.
- */
-/**
- * This package provides default implementation of a purely SE based injection mechanism.
- */
-package org.apache.tamaya.inject.internal;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/main/java/org/apache/tamaya/inject/package-info.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/package-info.java b/modules/injection/src/main/java/org/apache/tamaya/inject/package-info.java
deleted file mode 100644
index 4119248..0000000
--- a/modules/injection/src/main/java/org/apache/tamaya/inject/package-info.java
+++ /dev/null
@@ -1,22 +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.
- */
-/**
- * Main SE based injection API.
- */
-package org.apache.tamaya.inject;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/main/resources/META-INF/services/org.apache.tamaya.inject.ConfigurationInjector
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/resources/META-INF/services/org.apache.tamaya.inject.ConfigurationInjector b/modules/injection/src/main/resources/META-INF/services/org.apache.tamaya.inject.ConfigurationInjector
deleted file mode 100644
index 7204749..0000000
--- a/modules/injection/src/main/resources/META-INF/services/org.apache.tamaya.inject.ConfigurationInjector
+++ /dev/null
@@ -1,19 +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 current 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.
-#
-org.apache.tamaya.inject.internal.DefaultConfigurationInjector
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/test/java/annottext/AnnotatedConfigBean.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/test/java/annottext/AnnotatedConfigBean.java b/modules/injection/src/test/java/annottext/AnnotatedConfigBean.java
deleted file mode 100644
index 3420977..0000000
--- a/modules/injection/src/test/java/annottext/AnnotatedConfigBean.java
+++ /dev/null
@@ -1,78 +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 annottext;
-
-import org.apache.tamaya.inject.api.DynamicValue;
-import org.apache.tamaya.inject.api.NoConfig;
-import org.apache.tamaya.inject.api.Config;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An example showing some basic annotations, using an interface to be proxied by the
- * configuration system, nevertheless extending the overall Configuration interface.
- * Created by Anatole on 15.02.14.
- */
-public class AnnotatedConfigBean {
-
- @Config(value = {"foo.bar.myprop", "mp", "common.testdata.myProperty"}, defaultValue = "ET")
- // @ConfigLoadPolicy(listener = MyListener.class)
- public String myParameter;
-
- @Config("simple_value")
- public String simpleValue;
-
- @Config
- String anotherValue;
-
- @Config("host.name")
- private String hostName;
-
- @Config("host.name")
- private DynamicValue<String> dynamicHostname;
-
- @NoConfig
- public String javaVersion;
-
- public String getAnotherValue(){
- return anotherValue;
- }
-
- public String getHostName(){
- return hostName;
- }
-
- public DynamicValue<String> getDynamicValue(){
- return dynamicHostname;
- }
-
- @NoConfig
- private List<String> events = new ArrayList<>();
-
- // verify we don't try to inject final fields
- public static final String CONSTANT = "a constant";
-
-
- @Config("java.version")
- void setJavaVersion(String version){
- this.javaVersion = version;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/test/java/annottext/AnnotatedConfigTemplate.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/test/java/annottext/AnnotatedConfigTemplate.java b/modules/injection/src/test/java/annottext/AnnotatedConfigTemplate.java
deleted file mode 100644
index 8c6d692..0000000
--- a/modules/injection/src/test/java/annottext/AnnotatedConfigTemplate.java
+++ /dev/null
@@ -1,47 +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 annottext;
-
-import org.apache.tamaya.inject.api.DynamicValue;
-import org.apache.tamaya.inject.api.Config;
-
-/**
- * An example showing some basic annotations, using an interface to be proxied by the
- * configuration system.
- * Created by Anatole on 15.02.14.
- */
-public interface AnnotatedConfigTemplate {
-
- @Config(value = {"foo.bar.myprop", "mp","common.testdata.myProperty"}, defaultValue = "ET")
- // @ConfigLoadPolicy(listener = MyListener.class)
- String myParameter();
-
- @Config("simple_value")
- String simpleValue();
-
- @Config
- String simplestValue();
-
- @Config("host.name")
- String hostName();
-
- @Config("host.name")
- DynamicValue<String> getDynamicValue();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/test/java/annottext/NonAnnotatedConfigBean.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/test/java/annottext/NonAnnotatedConfigBean.java b/modules/injection/src/test/java/annottext/NonAnnotatedConfigBean.java
deleted file mode 100644
index 87f8be7..0000000
--- a/modules/injection/src/test/java/annottext/NonAnnotatedConfigBean.java
+++ /dev/null
@@ -1,45 +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 annottext;
-
-import org.apache.tamaya.inject.api.Config;
-import org.apache.tamaya.inject.api.DynamicValue;
-import org.apache.tamaya.inject.api.NoConfig;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An example showing some basic annotations, using an interface to be proxied by the
- * configuration system, nevertheless extending the overall Configuration interface.
- * Created by Anatole on 15.02.14.
- */
-public class NonAnnotatedConfigBean {
-
- public String simple_value = "Should be overridden!";
-
- public String fieldKey;
-
- public String classFieldKey = "Foo";
-
- public String fullKey;
-
- public String test2 = "This is not set.";
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/test/java/org/apache/tamaya/inject/TamayaInjectionTest.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/test/java/org/apache/tamaya/inject/TamayaInjectionTest.java b/modules/injection/src/test/java/org/apache/tamaya/inject/TamayaInjectionTest.java
deleted file mode 100644
index d5a26c1..0000000
--- a/modules/injection/src/test/java/org/apache/tamaya/inject/TamayaInjectionTest.java
+++ /dev/null
@@ -1,87 +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.inject;
-
-import annottext.AnnotatedConfigBean;
-import annottext.AnnotatedConfigTemplate;
-import annottext.NonAnnotatedConfigBean;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Created by Anatole on 12.01.2015.
- */
-public class TamayaInjectionTest {
-
- @Test
- public void testInjectionNonAnnotatedClass(){
- assertNotNull(ConfigurationInjection.getConfigurationInjector());
- NonAnnotatedConfigBean testInstance = new NonAnnotatedConfigBean();
- assertEquals(testInstance.simple_value, "Should be overridden!");
- assertEquals(testInstance.classFieldKey, "Foo");
- assertEquals(testInstance.fieldKey, null);
- assertEquals(testInstance.fullKey, null);
- assertEquals(testInstance.test2, "This is not set.");
- ConfigurationInjection.getConfigurationInjector().configure(testInstance);
- assertEquals(testInstance.simple_value, "aSimpleValue");
- assertEquals(testInstance.classFieldKey, "Class-Field-Value");
- assertEquals(testInstance.fieldKey, "Field-Value");
- assertEquals(testInstance.fullKey, "Fullkey-Value");
- assertEquals(testInstance.test2, "This is not set.");
- }
-
- @Test
- public void testInjectionClass(){
- assertNotNull(ConfigurationInjection.getConfigurationInjector());
- AnnotatedConfigBean testInstance = new AnnotatedConfigBean();
- assertEquals(testInstance.getHostName(), null);
- assertEquals(testInstance.getAnotherValue(), null);
- assertEquals(testInstance.myParameter, null);
- assertEquals(testInstance.simpleValue, null);
- ConfigurationInjection.getConfigurationInjector().configure(testInstance);
- assertEquals(testInstance.getHostName(), "tamaya01.incubator.apache.org");
- assertEquals(testInstance.getAnotherValue(), "HALLO!");
- assertEquals(testInstance.myParameter, "ET");
- assertEquals(testInstance.simpleValue, "aSimpleValue");
- assertNotNull(testInstance.getDynamicValue());
- assertTrue(testInstance.getDynamicValue().isPresent());
- assertEquals(testInstance.getDynamicValue().get(), "tamaya01.incubator.apache.org");
- assertEquals(testInstance.getHostName(), testInstance.getDynamicValue().get());
- assertEquals(testInstance.javaVersion, System.getProperty("java.version"));
- }
-
- @Test
- public void testConfigTemplate(){
- assertNotNull(ConfigurationInjection.getConfigurationInjector());
- AnnotatedConfigTemplate testInstance = ConfigurationInjection.getConfigurationInjector()
- .createTemplate(AnnotatedConfigTemplate.class);
- assertEquals(testInstance.hostName(), "tamaya01.incubator.apache.org");
- assertEquals(testInstance.myParameter(), "ET");
- assertEquals(testInstance.simpleValue(), "aSimpleValue");
- assertNotNull(testInstance.getDynamicValue());
- assertTrue(testInstance.getDynamicValue().isPresent());
- assertEquals(testInstance.getDynamicValue().get(), "tamaya01.incubator.apache.org");
- assertEquals(testInstance.hostName(), testInstance.getDynamicValue().get());
-// assertEquals(testInstance.simplestValue(), "HALLO!");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/test/java/org/apache/tamaya/inject/TestPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/test/java/org/apache/tamaya/inject/TestPropertySource.java b/modules/injection/src/test/java/org/apache/tamaya/inject/TestPropertySource.java
deleted file mode 100644
index 0853fd1..0000000
--- a/modules/injection/src/test/java/org/apache/tamaya/inject/TestPropertySource.java
+++ /dev/null
@@ -1,68 +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.inject;
-
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertyValue;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Created by Anatole on 12.01.2015.
- */
-public class TestPropertySource implements PropertySource {
-
- private Map<String,String> properties = new HashMap<>();
-
- public TestPropertySource(){
- properties.put("env.stage", "ET");
- properties.put("simple_value", "aSimpleValue");
- properties.put("host.name", "tamaya01.incubator.apache.org");
- properties.put("anotherValue", "HALLO!");
- properties.put("NonAnnotatedConfigBean.classFieldKey", "Class-Field-Value");
- properties.put("NonAnnotatedConfigBean.fieldKey", "Field-Value");
- properties.put("annottext.NonAnnotatedConfigBean.fullKey", "Fullkey-Value");
- }
-
- @Override
- public int getOrdinal() {
- return 0;
- }
-
- @Override
- public String getName() {
- return getClass().getName();
- }
-
- @Override
- public PropertyValue get(String key) {
- return PropertyValue.of(key,properties.get(key),getName());
- }
-
- @Override
- public Map<String, String> getProperties() {
- return properties;
- }
-
- @Override
- public boolean isScannable() {
- return true;
- }
-}
[04/15] incubator-tamaya-extensions git commit: TAMAYA-189: Moved
format and injection modules into separate subtrees.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/test/java/org/apache/tamaya/inject/internal/DefaultDynamicValueTest.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/test/java/org/apache/tamaya/inject/internal/DefaultDynamicValueTest.java b/modules/injection/src/test/java/org/apache/tamaya/inject/internal/DefaultDynamicValueTest.java
deleted file mode 100644
index dd16f36..0000000
--- a/modules/injection/src/test/java/org/apache/tamaya/inject/internal/DefaultDynamicValueTest.java
+++ /dev/null
@@ -1,315 +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.inject.internal;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.ConfigurationProvider;
-import org.apache.tamaya.builder.ConfigurationBuilder;
-import org.apache.tamaya.inject.api.ConfiguredItemSupplier;
-import org.apache.tamaya.inject.api.DynamicValue;
-import org.apache.tamaya.inject.api.Config;
-import org.apache.tamaya.inject.api.UpdatePolicy;
-import org.apache.tamaya.spi.ConversionContext;
-import org.apache.tamaya.spi.PropertyConverter;
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertyValue;
-import org.junit.Test;
-
-import org.apache.tamaya.Configuration;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.junit.Assert.*;
-
-/**
- * Tests for {@link org.apache.tamaya.inject.internal.DefaultDynamicValue}.
- */
-public class DefaultDynamicValueTest {
-
- @Config("a")
- String myValue;
-
- @Config("a")
- String myValue2;
-
- @Config("a")
- void setterMethod(String value){
-
- }
-
- private PropertyChangeEvent event;
-
- private PropertyChangeListener consumer = new PropertyChangeListener() {
- @Override
- public void propertyChange(PropertyChangeEvent evt) {
- event = evt;
- }
- };
-
- private Map<String,String> properties = new HashMap<>();
- private Configuration config = new ConfigurationBuilder().addPropertySources(
- new PropertySource() {
- @Override
- public int getOrdinal() {
- return 0;
- }
-
- @Override
- public String getName() {
- return "test";
- }
-
- @Override
- public PropertyValue get(String key) {
- return PropertyValue.of(key,properties.get(key),getName());
- }
-
- @Override
- public Map<String, String> getProperties() {
- return properties;
- }
-
- @Override
- public boolean isScannable() {
- return false;
- }
- }
- ).build();
-
- @Test
- public void testOf_Field() throws Exception {
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
- ConfigurationProvider.getConfiguration());
- assertNotNull(val);
- }
-
- @Test
- public void testOf_Method() throws Exception {
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredMethod("setterMethod", String.class),
- config);
- assertNotNull(val);
- }
-
- @Test
- public void testCommitAndGet() throws Exception {
- properties.put("a","aValue");
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
- config);
- assertNotNull(val);
- assertEquals("aValue",val.evaluateValue());
- }
-
- @Test
- public void testCommitAndGets() throws Exception {
- properties.put("a","aValue");
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
- config);
- val.setUpdatePolicy(UpdatePolicy.EXPLCIT);
- assertNotNull(val);
- assertEquals("aValue",val.evaluateValue());
- // change config
- val.get();
- this.properties.put("a", "aValue2");
- assertTrue(val.updateValue());
- assertEquals("aValue2", val.commitAndGet());
- }
-
- @Test
- public void testCommit() throws Exception {
- properties.put("a", "aValue");
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
- config);
- val.setUpdatePolicy(UpdatePolicy.EXPLCIT);
- assertNotNull(val);
- assertEquals("aValue", val.evaluateValue());
- // change config
- val.get();
- this.properties.put("a", "aValue2");
- assertEquals("aValue2", val.evaluateValue());
- assertTrue(val.updateValue());
- val.commit();
- assertEquals("aValue2", val.get());
- }
-
- @Test
- public void testGetSetUpdatePolicy() throws Exception {
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
- config);
- for(UpdatePolicy pol: UpdatePolicy.values()) {
- val.setUpdatePolicy(pol);
- assertEquals(pol, val.getUpdatePolicy());
- }
- }
-
- @Test
- public void testAddRemoveListener() throws Exception {
- properties.put("a","aValue");
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
- config);
- val.setUpdatePolicy(UpdatePolicy.IMMEDEATE);
- val.addListener(consumer);
- // change config
- val.get();
- this.properties.put("a", "aValue2");
- val.get();
- assertNotNull(event);
- event = null;
- val.removeListener(consumer);
- this.properties.put("a", "aValue3");
- val.updateValue();
- assertNull(event);
- }
-
- @Test
- public void testGet() throws Exception {
- properties.put("a", "aValue");
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
- config);
- val.setUpdatePolicy(UpdatePolicy.IMMEDEATE);
- properties.put("a", "aValue2");
- val.updateValue();
- assertEquals("aValue2", val.get());
- }
-
- @Test
- public void testUpdateValue() throws Exception {
- properties.put("a","aValue");
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
- config);
- val.setUpdatePolicy(UpdatePolicy.EXPLCIT);
- assertNotNull(val.get());
- assertEquals("aValue", val.get());
- val.updateValue();
- assertEquals("aValue", val.get());
- val.setUpdatePolicy(UpdatePolicy.IMMEDEATE);
- val.updateValue();
- assertEquals("aValue",val.get());
- }
-
- @Test
- public void testEvaluateValue() throws Exception {
- properties.put("a","aValue");
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
- config);
- val.setUpdatePolicy(UpdatePolicy.EXPLCIT);
- assertNotNull(val.get());
- assertEquals("aValue",val.evaluateValue());
- properties.put("a", "aValue2");
- assertEquals("aValue2", val.evaluateValue());
- }
-
- @Test
- public void testGetNewValue() throws Exception {
- properties.put("a","aValue");
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
- config);
- val.setUpdatePolicy(UpdatePolicy.EXPLCIT);
- val.get();
- assertNull(val.getNewValue());
- properties.put("a", "aValue2");
- val.get();
- assertNotNull(val.getNewValue());
- assertEquals("aValue2", val.getNewValue());
- val.commit();
- assertNull(val.getNewValue());
- }
-
- @Test
- public void testIsPresent() throws Exception {
-
- }
-
- @Test
- public void testIfPresent() throws Exception {
- properties.put("a","aValue");
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
- config);
- val.setUpdatePolicy(UpdatePolicy.IMMEDEATE);
- assertTrue(val.isPresent());
- properties.remove("a");
- val.updateValue();
- assertFalse(val.isPresent());
- }
-
- @Test
- public void testOrElse() throws Exception {
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
- config);
- val.setUpdatePolicy(UpdatePolicy.IMMEDEATE);
- assertEquals("bla", val.orElse("bla"));
- properties.put("a","aValue");
- val.updateValue();
- assertEquals("aValue", val.orElse("bla"));
- }
-
- @Test
- public void testOrElseGet() throws Exception {
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
- config);
- val.setUpdatePolicy(UpdatePolicy.IMMEDEATE);
- assertEquals("bla", val.orElseGet(new ConfiguredItemSupplier() {
- @Override
- public Object get() {
- return "bla";
- }
- }));
- properties.put("a", "aValue");
- val.updateValue();
- assertEquals("aValue", val.orElseGet(new ConfiguredItemSupplier() {
- @Override
- public Object get() {
- return "bla";
- }
- }));
- }
-
- @Test(expected = ConfigException.class)
- public void testOrElseThrow() throws Throwable {
- DynamicValue val = DefaultDynamicValue.of(getClass().getDeclaredField("myValue"),
- config);
- val.setUpdatePolicy(UpdatePolicy.EXPLCIT);
- val.get();
- properties.put("a", "aValue");
- assertEquals("aValue", val.orElseThrow(new ConfiguredItemSupplier() {
- @Override
- public ConfigException get() {
- return new ConfigException("bla");
- }
- }));
- properties.remove("a");
- val.updateValue();
- assertEquals("aValue", val.orElseThrow(new ConfiguredItemSupplier() {
- @Override
- public ConfigException get() {
- return new ConfigException("bla");
- }
- }));
- }
-
- private static final class DoublicatingConverter implements PropertyConverter<String>{
-
- @Override
- public String convert(String value, ConversionContext context) {
- return value + value;
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
----------------------------------------------------------------------
diff --git a/modules/injection/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource b/modules/injection/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
deleted file mode 100644
index 5dfb894..0000000
--- a/modules/injection/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
+++ /dev/null
@@ -1,19 +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 current 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.
-#
-org.apache.tamaya.inject.TestPropertySource
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/pom.xml
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/pom.xml b/modules/injection/standalone/pom.xml
new file mode 100644
index 0000000..5d5c975
--- /dev/null
+++ b/modules/injection/standalone/pom.xml
@@ -0,0 +1,104 @@
+<!--
+ ~ 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-injection-all</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>tamaya-injection</artifactId>
+ <name>Apache Tamaya odules - Injection Standalone</name>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <jdkVersion>1.7</jdkVersion>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-injection-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-core</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-resolver</artifactId>
+ <version>${project.version}</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-builder</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-events</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>java-hamcrest</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.tamaya.inject
+ </Export-Package>
+ <Private-Package>
+ org.apache.tamaya.inject.internal
+ </Private-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/ConfigurationInjection.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/ConfigurationInjection.java b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/ConfigurationInjection.java
new file mode 100644
index 0000000..79d6218
--- /dev/null
+++ b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/ConfigurationInjection.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+import org.apache.tamaya.spi.ServiceContextManager;
+
+/**
+ * Singleton accessor class for accessing {@link ConfigurationInjector} instances.
+ */
+public final class ConfigurationInjection {
+
+ /**
+ * Singleton constructor.
+ */
+ private ConfigurationInjection() {
+ }
+
+ /**
+ * Get the current injector instance.
+ *
+ * @return the current injector, not null.
+ */
+ public static ConfigurationInjector getConfigurationInjector() {
+ return ServiceContextManager.getServiceContext().getService(ConfigurationInjector.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/ConfigurationInjector.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/ConfigurationInjector.java b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/ConfigurationInjector.java
new file mode 100644
index 0000000..563ae47
--- /dev/null
+++ b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/ConfigurationInjector.java
@@ -0,0 +1,94 @@
+/*
+ * 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;
+
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.inject.api.ConfiguredItemSupplier;
+
+/**
+ * Accessor interface for injection of configuration and configuration templates.
+ */
+public interface ConfigurationInjector {
+
+ /**
+ * Configures the current instance and registers necessary listener to forward config change events as
+ * defined by the current annotations in place.
+ *
+ * Unannotated types are ignored.
+ *
+ * @param <T> the type of the instance.
+ * @param instance the instance to be configured
+ * @return the configured instance (allows chaining of operations).
+ */
+ <T> T configure(T instance);
+
+ /**
+ * Configures the current instance and registers necessary listener to forward config change events as
+ * defined by the current annotations in place.
+ *
+ * Unannotated types are ignored.
+ *
+ * @param <T> the type of the instance.
+ * @param instance the instance to be configured
+ * @param config the configuration to be used for injection.
+ * @return the configured instance (allows chaining of operations).
+ */
+ <T> T configure(T instance, Configuration config);
+
+ /**
+ * Creates a template implementing the annotated methods based on current configuration data.
+ *
+ * @param <T> the type of the template.
+ * @param templateType the type of the template to be created.
+ * @return the configured template.
+ */
+ <T> T createTemplate(Class<T> templateType);
+
+ /**
+ * Creates a template implementting the annotated methods based on current configuration data.
+ *
+ * @param <T> the type of the template.
+ * @param config the configuration to be used for backing the template.
+ * @param templateType the type of the template to be created.
+ * @return the configured template.
+ */
+ <T> T createTemplate(Class<T> templateType, Configuration config);
+
+
+ /**
+ * Creates a supplier for configured instances of the given type {@code T}.
+ *
+ * @param supplier the supplier to create new instances.
+ * @param <T> the target type.
+ * @return a supplier creating configured instances of {@code T}.
+ */
+ <T> ConfiguredItemSupplier<T> getConfiguredSupplier(ConfiguredItemSupplier<T> supplier);
+
+ /**
+ * Creates a supplier for configured instances of the given type {@code T}.
+ *
+ * @param supplier the supplier to create new instances.
+ * @param config the configuration to be used for backing the supplier.
+ * @param <T> the target type.
+ * @return a supplier creating configured instances of {@code T}.
+ */
+ <T> ConfiguredItemSupplier<T> getConfiguredSupplier(ConfiguredItemSupplier<T> supplier, Configuration config);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfigTemplateInvocationHandler.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfigTemplateInvocationHandler.java b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfigTemplateInvocationHandler.java
new file mode 100644
index 0000000..5d634e1
--- /dev/null
+++ b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfigTemplateInvocationHandler.java
@@ -0,0 +1,73 @@
+/*
+ * 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.internal;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.inject.api.DynamicValue;
+import org.apache.tamaya.inject.spi.ConfiguredType;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Objects;
+
+/**
+ * Invocation handler that handles request against a configuration template.
+ */
+public final class ConfigTemplateInvocationHandler implements InvocationHandler {
+
+ /**
+ * The configured type.
+ */
+ private final ConfiguredType type;
+
+ /**
+ * Creates a new handler instance.
+ *
+ * @param type the target type, not null.
+ */
+ public ConfigTemplateInvocationHandler(Class<?> type) {
+ this.type = new ConfiguredTypeImpl(Objects.requireNonNull(type));
+ if (!type.isInterface()) {
+ throw new IllegalArgumentException("Can only proxy interfaces as configuration templates.");
+ }
+ InjectionHelper.sendConfigurationEvent(this.type);
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ if ("toString".equals(method.getName())) {
+ return "Configured Proxy -> " + this.type.getType().getName();
+ } else if ("hashCode".equals(method.getName())) {
+ return Objects.hashCode(proxy);
+ } else if ("equals".equals(method.getName())) {
+ return Objects.equals(proxy, args[0]);
+ } else if ("get".equals(method.getName())) {
+ return config;
+ }
+ if (method.getReturnType() == DynamicValue.class) {
+ return DefaultDynamicValue.of(method, config);
+ }
+ String[] retKey = new String[1];
+ String configValue = InjectionHelper.getConfigValue(method, retKey, config);
+ return InjectionHelper.adaptValue(method, TypeLiteral.of(method.getReturnType()), retKey[0], configValue);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfiguredFieldImpl.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfiguredFieldImpl.java b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfiguredFieldImpl.java
new file mode 100644
index 0000000..64b0c95
--- /dev/null
+++ b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfiguredFieldImpl.java
@@ -0,0 +1,170 @@
+/*
+ * 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.internal;
+
+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.DynamicValue;
+import org.apache.tamaya.inject.api.InjectionUtils;
+import org.apache.tamaya.inject.spi.ConfiguredField;
+
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+import java.util.Collection;
+import java.util.Objects;
+
+/**
+ * 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, converting any applying the
+ * final keys by reflection.
+ */
+public class ConfiguredFieldImpl implements ConfiguredField{
+ /**
+ * The configured field instance.
+ */
+ protected final Field annotatedField;
+
+ /**
+ * Models a configured field and provides mechanisms for injection.
+ *
+ * @param field the field instance.
+ */
+ public ConfiguredFieldImpl(Field field) {
+ Objects.requireNonNull(field);
+ this.annotatedField = field;
+ }
+
+
+ /**
+ * Evaluate the initial keys fromMap the configuration and applyChanges it to the field.
+ *
+ * @param target the target instance.
+ * @throws ConfigException if evaluation or conversion failed.
+ */
+ public void configure(Object target, Configuration config) throws ConfigException {
+ if (this.annotatedField.getType() == DynamicValue.class) {
+ applyDynamicValue(target);
+ } else {
+ applyValue(target, config, false);
+ }
+ }
+
+
+ /**
+ * This method instantiates and assigns a dynamic value.
+ *
+ * @param target the target instance, not null.
+ * @throws ConfigException if the configuration required could not be resolved or converted.
+ */
+ private void applyDynamicValue(Object target) throws ConfigException {
+ Objects.requireNonNull(target);
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ @Override
+ public Object run() throws Exception {
+ annotatedField.setAccessible(true);
+ return annotatedField;
+ }
+ });
+ annotatedField.set(target,
+ DefaultDynamicValue.of(annotatedField, ConfigurationProvider.getConfiguration()));
+ } catch (Exception e) {
+ throw new ConfigException("Failed to annotation configured field: " + this.annotatedField.getDeclaringClass()
+ .getName() + '.' + annotatedField.getName(), e);
+ }
+ }
+
+ /**
+ * This method applies a configuration to the field.
+ *
+ * @param target the target instance, not null.
+ * @param config The configuration to be used.
+ * @param resolve set to true, if expression resolution should be applied on the keys passed.
+ * @throws ConfigException if the configuration required could not be resolved or converted.
+ */
+ private void applyValue(Object target, Configuration config, boolean resolve) throws ConfigException {
+ Objects.requireNonNull(target);
+ try {
+ String[] retKey = new String[1];
+ String configValue = InjectionHelper.getConfigValue(this.annotatedField, retKey, config);
+ // Next step perform expression resolution, if any
+ String evaluatedValue = resolve && configValue != null
+ ? InjectionHelper.evaluateValue(configValue)
+ : configValue;
+
+ // Check for adapter/filter
+ Object value = InjectionHelper.adaptValue(this.annotatedField,
+ TypeLiteral.of(this.annotatedField.getType()), retKey[0], evaluatedValue);
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ @Override
+ public Object run() throws Exception {
+ annotatedField.setAccessible(true);
+ return annotatedField;
+ }
+ });
+ if(value!=null) {
+ annotatedField.set(target, value);
+ }
+ } catch (Exception e) {
+ throw new ConfigException("Failed to evaluate annotated field: " + this.annotatedField.getDeclaringClass()
+ .getName() + '.' + annotatedField.getName(), e);
+ }
+ }
+
+ /**
+ * Get the field's type.
+ * @return the field's type, not null.
+ */
+ @Override
+ public Class<?> getType(){
+ return this.annotatedField.getType();
+ }
+
+ /**
+ * Access the applyable configuration keys for this field.
+ * @return the configuration keys, never null.
+ */
+ @Override
+ public Collection<String> getConfiguredKeys(){
+ return InjectionUtils.getKeys(this.annotatedField);
+ }
+
+ @Override
+ public String toString() {
+ return "ConfiguredField[" + getSignature() + ']';
+ }
+
+ @Override
+ public String getName() {
+ return annotatedField.getName();
+ }
+
+ @Override
+ public String getSignature() {
+ return getName()+':'+getType().getName();
+ }
+
+ @Override
+ public Field getAnnotatedField() {
+ return annotatedField;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfiguredSetterMethod.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfiguredSetterMethod.java b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfiguredSetterMethod.java
new file mode 100644
index 0000000..b69df20
--- /dev/null
+++ b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfiguredSetterMethod.java
@@ -0,0 +1,139 @@
+/*
+ * 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.internal;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.inject.api.InjectionUtils;
+import org.apache.tamaya.inject.spi.ConfiguredMethod;
+
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+import java.util.Collection;
+import java.util.Objects;
+
+/**
+ * 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.
+ */
+public class ConfiguredSetterMethod implements ConfiguredMethod {
+
+ /**
+ * The configured field instance.
+ */
+ private Method setterMethod;
+ private Collection<String> configuredKeys;
+
+ /**
+ * Models a configured field and provides mechanisms for injection.
+ *
+ * @param method the method instance.
+ */
+ public ConfiguredSetterMethod(Method method) {
+ if (void.class.equals(method.getReturnType()) &&
+ method.getParameterTypes().length == 1) {
+ this.setterMethod = method;
+ }
+ }
+
+ @Override
+ public void configure(Object target, Configuration config) throws ConfigException {
+ String[] retKey = new String[1];
+ String configValue = InjectionHelper.getConfigValue(this.setterMethod, retKey, config);
+ Objects.requireNonNull(target);
+ try {
+ String evaluatedString = configValue != null
+ ? InjectionHelper.evaluateValue(configValue)
+ : configValue;
+
+ // Check for adapter/filter
+ Object value = InjectionHelper.adaptValue(
+ this.setterMethod, TypeLiteral.of(this.setterMethod.getParameterTypes()[0]),
+ retKey[0], evaluatedString);
+
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ @Override
+ public Object run() throws Exception {
+ setterMethod.setAccessible(true);
+ return setterMethod;
+ }
+ });
+
+ setterMethod.invoke(target, value);
+ } catch (Exception e) {
+ throw new ConfigException("Failed to annotation configured method: " + this.setterMethod.getDeclaringClass()
+ .getName() + '.' + setterMethod.getName(), e);
+ }
+ }
+
+
+ /**
+ * Access the applyable configuration keys for this field.
+ *
+ * @return the configuration keys, never null.
+ */
+ @Override
+ public Collection<String> getConfiguredKeys() {
+ return InjectionUtils.getKeys(this.setterMethod);
+ }
+
+ /**
+ * Get the type to be set on the setter method.
+ * @return the setter type.
+ */
+ @Override
+ public Class<?>[] getParameterTypes() {
+ return this.setterMethod.getParameterTypes();
+ }
+
+ /**
+ * Access the annotated method.
+ * @return the annotated method, not null.
+ */
+ @Override
+ public Method getAnnotatedMethod() {
+ return this.setterMethod;
+ }
+
+ @Override
+ public String getName() {
+ return this.setterMethod.getName();
+ }
+
+ @Override
+ public String getSignature() {
+ return "void " + this.setterMethod.getName()+'('+ printTypes(getParameterTypes())+')';
+ }
+
+ private String printTypes(Class<?>[] parameterTypes) {
+ StringBuilder b = new StringBuilder();
+ for(Class cl:parameterTypes){
+ b.append(cl.getName());
+ b.append(',');
+ }
+ if(b.length()>0){
+ b.setLength(b.length()-1);
+ }
+ return b.toString();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfiguredTypeImpl.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfiguredTypeImpl.java b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfiguredTypeImpl.java
new file mode 100644
index 0000000..b40f6c9
--- /dev/null
+++ b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/ConfiguredTypeImpl.java
@@ -0,0 +1,237 @@
+/*
+ * 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.internal;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.*;
+import java.util.logging.Logger;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.inject.api.ConfigAutoInject;
+import org.apache.tamaya.inject.api.NoConfig;
+import org.apache.tamaya.inject.api.Config;
+import org.apache.tamaya.inject.api.ConfigDefaultSections;
+import org.apache.tamaya.inject.spi.ConfiguredField;
+import org.apache.tamaya.inject.spi.ConfiguredMethod;
+import org.apache.tamaya.inject.spi.ConfiguredType;
+
+/**
+ * Structure that contains and manages configuration related things for a configured type registered.
+ * Created by Anatole on 03.10.2014.
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class ConfiguredTypeImpl implements ConfiguredType{
+ /** The log used. */
+ private static final Logger LOG = Logger.getLogger(ConfiguredTypeImpl.class.getName());
+ /**
+ * A list with all annotated instance variables.
+ */
+ private final List<ConfiguredField> configuredFields = new ArrayList<>();
+ /**
+ * A list with all annotated methods (templates).
+ */
+ private final List<ConfiguredMethod> configuredSetterMethods = new ArrayList<>();
+ /**
+ * The basic type.
+ */
+ private final Class type;
+
+ /**
+ * Creates an instance of this class hereby evaluating the config annotations given for later effective
+ * injection (configuration) of instances.
+ *
+ * @param type the instance type.
+ */
+ public ConfiguredTypeImpl(Class type) {
+ this.type = Objects.requireNonNull(type);
+ if(!isConfigured(type)){
+ LOG.info("Auto-Configuring type: " + type.getName());
+ initFields(type, true);
+ initMethods(type, true);
+ }else {
+ ConfigAutoInject autoInject = (ConfigAutoInject) type.getAnnotation(ConfigAutoInject.class);
+ if (autoInject != null) {
+ initFields(type, autoInject != null);
+ initMethods(type, autoInject != null);
+ } else {
+ initFields(type, false);
+ initMethods(type, false);
+ }
+ }
+ }
+
+ private void initFields(Class type, boolean autoConfigure) {
+ for (Field f : type.getDeclaredFields()) {
+ if (f.isAnnotationPresent(NoConfig.class)) {
+ LOG.finest("Ignored @NoConfig annotated field " + f.getClass().getName() + "#" +
+ f.toGenericString());
+ continue;
+ }
+ if (Modifier.isFinal(f.getModifiers())) {
+ LOG.finest("Ignored final field " + f.getClass().getName() + "#" +
+ f.toGenericString());
+ continue;
+ }
+ if (f.isSynthetic()) {
+ LOG.finest("Ignored synthetic field " + f.getClass().getName() + "#" +
+ f.toGenericString());
+ continue;
+ }
+ try {
+ if(isConfiguredField(f) || autoConfigure) {
+ ConfiguredField configuredField = new ConfiguredFieldImpl(f);
+ configuredFields.add(configuredField);
+ LOG.finer("Registered field " + f.getClass().getName() + "#" +
+ f.toGenericString());
+ }
+ } catch (Exception e) {
+ throw new ConfigException("Failed to initialized configured field: " +
+ f.getDeclaringClass().getName() + '.' + f.getName(), e);
+ }
+ }
+ }
+
+ private void initMethods(Class type, boolean autoConfigure) {
+ // TODO revisit this logic here...
+ for (Method m : type.getDeclaredMethods()) {
+ if (m.isAnnotationPresent(NoConfig.class)) {
+ LOG.finest("Ignored @NoConfig annotated method " + m.getClass().getName() + "#" +
+ m.toGenericString());
+ continue;
+ }
+ if (m.isSynthetic()) {
+ LOG.finest("Ignored synthetic method " + m.getClass().getName() + "#" +
+ m.toGenericString());
+ continue;
+ }
+ if(isConfiguredMethod(m) || autoConfigure) {
+ Config propAnnot = m.getAnnotation(Config.class);
+ if (addPropertySetter(m, propAnnot)) {
+ LOG.finer("Added configured setter: " + m.getClass().getName() + "#" +
+ m.toGenericString());
+ }
+ }
+ }
+ }
+
+ private boolean addPropertySetter(Method m, Config prop) {
+ if (prop!=null) {
+ if (m.getParameterTypes().length == 1) {
+ // getter method
+ Class<?> returnType = m.getReturnType();
+ if (void.class.equals(returnType)) {
+ try {
+ configuredSetterMethods.add(new ConfiguredSetterMethod(m));
+ return true;
+ } catch (Exception e) {
+ throw new ConfigException("Failed to initialized configured setter method: " +
+ m.getDeclaringClass().getName() + '.' + m.getName(), e);
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Method called to configure an instance.
+ *
+ * @param instance The instance to be configured.
+ */
+ public void configure(Object instance) {
+ configure(instance, ConfigurationProvider.getConfiguration());
+ }
+
+ @Override
+ public void configure(Object instance, Configuration config) {
+ for (ConfiguredField field : configuredFields) {
+ field.configure(instance, config);
+ }
+ for (ConfiguredMethod method : configuredSetterMethods) {
+ method.configure(instance, config);
+// // TODO, if method should be recalled on changes, corresponding callbacks could be registered here
+ }
+ }
+
+
+ public static boolean isConfigured(Class type) {
+ if (type.getAnnotation(ConfigDefaultSections.class) != null) {
+ return true;
+ }
+ // if no class level annotation is there we might have field level annotations only
+ for (Field field : type.getDeclaredFields()) {
+ if (isConfiguredField(field)) {
+ return true;
+ }
+ }
+ // if no class level annotation is there we might have method level annotations only
+ for (Method method : type.getDeclaredMethods()) {
+ if(isConfiguredMethod(method)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean isConfiguredField(Field field) {
+ return field.isAnnotationPresent(Config.class);
+ }
+
+ public static boolean isConfiguredMethod(Method method) {
+ return method.isAnnotationPresent(Config.class);
+ }
+
+ @Override
+ public Class getType() {
+ return this.type;
+ }
+
+ @Override
+ public String getName() {
+ return this.type.getName();
+ }
+
+ /**
+ * Get the registered configured fields.
+ * @return the registered configured fields, never null.
+ */
+ @Override
+ public Collection<ConfiguredField> getConfiguredFields(){
+ return configuredFields;
+ }
+
+ /**
+ * Get the registered annotated setter methods.
+ * @return the registered annotated setter methods, never null.
+ */
+ @Override
+ public Collection<ConfiguredMethod> getConfiguredMethods(){
+ return configuredSetterMethods;
+ }
+
+ @Override
+ public String toString() {
+ return "ConfigDefaultSections{"+ this.getType().getName() + '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/DefaultConfigurationInjector.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/DefaultConfigurationInjector.java b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/DefaultConfigurationInjector.java
new file mode 100644
index 0000000..a3a7015
--- /dev/null
+++ b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/DefaultConfigurationInjector.java
@@ -0,0 +1,179 @@
+/*
+ * 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.internal;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.inject.ConfigurationInjector;
+
+import javax.annotation.Priority;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.apache.tamaya.inject.api.ConfiguredItemSupplier;
+import org.apache.tamaya.inject.api.NoConfig;
+import org.apache.tamaya.inject.api.Config;
+import org.apache.tamaya.inject.api.ConfigDefaultSections;
+import org.apache.tamaya.inject.spi.ConfiguredType;
+
+/**
+ * Simple injector singleton that also registers instances configured using weak references.
+ */
+@Priority(0)
+public final class DefaultConfigurationInjector implements ConfigurationInjector {
+
+ private final Map<Class<?>, ConfiguredType> configuredTypes = new ConcurrentHashMap<>();
+
+ private static final Logger LOG = Logger.getLogger(DefaultConfigurationInjector.class.getName());
+
+ private boolean autoConfigureEnabled = true;
+
+ /**
+ * Extract the configuration annotation config and registers it per class, for later reuse.
+ *
+ * @param type the type to be configured.
+ * @return the configured type registered.
+ */
+ public ConfiguredType registerType(Class<?> type) {
+ ConfiguredType confType = configuredTypes.get(type);
+ if (confType == null) {
+ if(!isConfigAnnotated(type) && !autoConfigureEnabled){
+ return null;
+ }
+ confType = new ConfiguredTypeImpl(type);
+ configuredTypes.put(type, confType);
+ InjectionHelper.sendConfigurationEvent(confType);
+ }
+ return confType;
+ }
+
+ /**
+ * If set also non annotated instances can be configured or created as templates.
+ * @return true, if autoConfigureEnabled.
+ */
+ public boolean isAutoConfigureEnabled(){
+ return autoConfigureEnabled;
+ }
+
+ /**
+ * Setting to true enables also configuration/templating of non annotated classes or
+ * interfaces.
+ * @param enabled true enables also configuration/templating of
+ */
+ public void setAutoConfigureEnabled(boolean enabled){
+ this.autoConfigureEnabled = enabled;
+ }
+
+ /**
+ * CHecks if type is eligible for configuration injection.
+ * @param type the target type, not null.
+ * @return true, if the type, a method or field has Tamaya config annotation on it.
+ */
+ private boolean isConfigAnnotated(Class<?> type) {
+ if(type.getClass().isAnnotationPresent(ConfigDefaultSections.class)){
+ return true;
+ }
+ for (Field f : type.getDeclaredFields()) {
+ if (f.isAnnotationPresent(NoConfig.class) || f.isAnnotationPresent(Config.class)) {
+ return true;
+ }
+ }
+ for (Method m : type.getDeclaredMethods()) {
+ if (m.isAnnotationPresent(NoConfig.class) || m.isAnnotationPresent(Config.class)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Configured the current instance and reigsterd necessary listener to forward config change events as
+ * defined by the current annotations in place.
+ *
+ * @param instance the instance to be configured
+ */
+ @Override
+ public <T> T configure(T instance) {
+ return configure(instance, ConfigurationProvider.getConfiguration());
+ }
+
+ /**
+ * Configured the current instance and reigsterd necessary listener to forward config change events as
+ * defined by the current annotations in place.
+ *
+ * @param instance the instance to be configured
+ * @param config the target configuration, not null.
+ */
+ @Override
+ public <T> T configure(T instance, Configuration config) {
+ Class<?> type = Objects.requireNonNull(instance).getClass();
+ ConfiguredType configuredType = registerType(type);
+ if(configuredType!=null){
+ configuredType.configure(instance, config);
+ }else{
+ LOG.info("Instance passed is not configurable: " + instance);
+ }
+ return instance;
+ }
+
+ /**
+ * Create a template implementting the annotated methods based on current configuration data.
+ *
+ * @param templateType the type of the template to be created.
+ */
+ @Override
+ public <T> T createTemplate(Class<T> templateType) {
+ return createTemplate(templateType, ConfigurationProvider.getConfiguration());
+ }
+
+ /**
+ * Create a template implementting the annotated methods based on current configuration data.
+ *
+ * @param templateType the type of the template to be created.
+ * @param config the target configuration, not null.
+ */
+ @Override
+ public <T> T createTemplate(Class<T> templateType, Configuration config) {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if(cl==null){
+ cl = this.getClass().getClassLoader();
+ }
+ return templateType.cast(Proxy.newProxyInstance(cl, new Class[]{ConfiguredItemSupplier.class, Objects.requireNonNull(templateType)},
+ new ConfigTemplateInvocationHandler(templateType)));
+ }
+
+ @Override
+ public <T> ConfiguredItemSupplier<T> getConfiguredSupplier(final ConfiguredItemSupplier<T> supplier) {
+ return getConfiguredSupplier(supplier, ConfigurationProvider.getConfiguration());
+ }
+
+ @Override
+ public <T> ConfiguredItemSupplier<T> getConfiguredSupplier(final ConfiguredItemSupplier<T> supplier, final Configuration config) {
+ return new ConfiguredItemSupplier<T>() {
+ public T get() {
+ return configure(supplier.get(), config);
+ }
+ };
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/DefaultDynamicValue.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/DefaultDynamicValue.java b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/DefaultDynamicValue.java
new file mode 100644
index 0000000..2f051b3
--- /dev/null
+++ b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/DefaultDynamicValue.java
@@ -0,0 +1,498 @@
+/*
+ * 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.internal;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.inject.api.BaseDynamicValue;
+import org.apache.tamaya.inject.api.DynamicValue;
+import org.apache.tamaya.inject.api.InjectionUtils;
+import org.apache.tamaya.inject.api.LoadPolicy;
+import org.apache.tamaya.inject.api.UpdatePolicy;
+import org.apache.tamaya.inject.api.WithPropertyConverter;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * A accessor for a single configured value. This can be used to support values that may change during runtime,
+ * reconfigured or final. Hereby external code (could be Tamaya configuration listners or client code), can set a
+ * new value. Depending on the {@link UpdatePolicy} the new value is immedeately active or it requires an active commit
+ * by client code. Similarly an instance also can ignore all later changes to the value.
+ * <h3>Implementation Details</h3>
+ * This class is
+ * <ul>
+ * <li>Serializable, when also the item stored is serializable</li>
+ * <li>Thread safe</li>
+ * </ul>
+ *
+ * @param <T> The type of the value.
+ */
+final class DefaultDynamicValue<T> extends BaseDynamicValue<T> {
+
+ private static final long serialVersionUID = -2071172847144537443L;
+
+ /**
+ * The property name of the entry.
+ */
+ private final String propertyName;
+ /**
+ * The keys to be resolved.
+ */
+ private final String[] keys;
+ /**
+ * Back reference to the base configuration instance. This reference is used reevalaute the given property and
+ * compare the result with the previous value after a configuration change was triggered.
+ */
+ private final Configuration configuration;
+ /**
+ * The target type of the property used to lookup a matching {@link PropertyConverter}.
+ * If null, {@code propertyConverter} is set and used instead.
+ */
+ private final TypeLiteral<T> targetType;
+ /**
+ * The property converter to be applied, may be null. In the ladder case targetType is not null.
+ */
+ private final PropertyConverter<T> propertyConverter;
+ /**
+ * Policy that defines how new values are applied, be default it is applied initially once, but never updated
+ * anymore.
+ */
+ private UpdatePolicy updatePolicy;
+ /**
+ * Load policy.
+ */
+ private final LoadPolicy loadPolicy;
+
+ /**
+ * The current value, never null.
+ */
+ private transient T value;
+ /**
+ * The new value, or null.
+ */
+ private transient Object[] newValue;
+ /**
+ * List of listeners that listen for changes.
+ */
+ private transient WeakList<PropertyChangeListener> listeners;
+
+ /**
+ * Constructor.
+ *
+ * @param propertyName the name of the fields' property/method.
+ * @param keys the keys of the property, not null.
+ * @param configuration the configuration, not null.
+ * @param targetType the target type, not null.
+ * @param propertyConverter the optional converter to be used.
+ */
+ private DefaultDynamicValue(String propertyName, Configuration configuration, TypeLiteral<T> targetType,
+ PropertyConverter<T> propertyConverter, List<String> keys, LoadPolicy loadPolicy,
+ UpdatePolicy updatePolicy) {
+ this.propertyName = Objects.requireNonNull(propertyName);
+ this.keys = keys.toArray(new String[keys.size()]);
+ this.configuration = Objects.requireNonNull(configuration);
+ this.propertyConverter = propertyConverter;
+ this.targetType = targetType;
+ this.loadPolicy = Objects.requireNonNull(loadPolicy);
+ this.updatePolicy = Objects.requireNonNull(updatePolicy);
+ if(loadPolicy == LoadPolicy.INITIAL){
+ this.value = evaluateValue();
+ }
+ }
+
+ public static DynamicValue of(Field annotatedField, Configuration configuration) {
+ return of(annotatedField, configuration, LoadPolicy.ALWAYS, UpdatePolicy.IMMEDEATE);
+ }
+
+ public static DynamicValue of(Field annotatedField, Configuration configuration, LoadPolicy loadPolicy) {
+ return of(annotatedField, configuration, loadPolicy, UpdatePolicy.IMMEDEATE);
+ }
+
+ public static DynamicValue of(Field annotatedField, Configuration configuration, UpdatePolicy updatePolicy) {
+ return of(annotatedField, configuration, LoadPolicy.ALWAYS, updatePolicy);
+ }
+
+ public static DynamicValue of(Field annotatedField, Configuration configuration, LoadPolicy loadPolicy, UpdatePolicy updatePolicy) {
+ // Check for adapter/filter
+ Type targetType = annotatedField.getGenericType();
+ if (targetType == null) {
+ throw new ConfigException("Failed to evaluate target type for " + annotatedField.getDeclaringClass().getName()
+ + '.' + annotatedField.getName());
+ }
+ if (targetType instanceof ParameterizedType) {
+ ParameterizedType pt = (ParameterizedType) targetType;
+ Type[] types = pt.getActualTypeArguments();
+ if (types.length != 1) {
+ throw new ConfigException("Failed to evaluate target type for " + annotatedField.getDeclaringClass().getName()
+ + '.' + annotatedField.getName());
+ }
+ targetType = types[0];
+ }
+ PropertyConverter<?> propertyConverter = null;
+ WithPropertyConverter annot = annotatedField.getAnnotation(WithPropertyConverter.class);
+ if (annot != null) {
+ try {
+ propertyConverter = annot.value().newInstance();
+ } catch (Exception e) {
+ throw new ConfigException("Failed to instantiate annotated PropertyConverter on " +
+ annotatedField.getDeclaringClass().getName()
+ + '.' + annotatedField.getName(), e);
+ }
+ }
+ List<String> keys = InjectionUtils.getKeys(annotatedField);
+ return new DefaultDynamicValue(annotatedField.getName(), configuration,
+ TypeLiteral.of(targetType), propertyConverter, keys, loadPolicy, updatePolicy);
+ }
+
+ public static DynamicValue of(Method method, Configuration configuration) {
+ return of(method, configuration, LoadPolicy.ALWAYS, UpdatePolicy.IMMEDEATE);
+ }
+
+ public static DynamicValue of(Method method, Configuration configuration, UpdatePolicy updatePolicy) {
+ return of(method, configuration, LoadPolicy.ALWAYS, updatePolicy);
+ }
+
+ public static DynamicValue of(Method method, Configuration configuration, LoadPolicy loadPolicy) {
+ return of(method, configuration, loadPolicy, UpdatePolicy.IMMEDEATE);
+ }
+
+ public static DynamicValue of(Method method, Configuration configuration, LoadPolicy loadPolicy, UpdatePolicy updatePolicy) {
+ // Check for adapter/filter
+ Type targetType = method.getGenericReturnType();
+ if (targetType == null) {
+ throw new ConfigException("Failed to evaluate target type for " + method.getDeclaringClass()
+ .getName() + '.' + method.getName());
+ }
+ if (targetType instanceof ParameterizedType) {
+ ParameterizedType pt = (ParameterizedType) targetType;
+ Type[] types = pt.getActualTypeArguments();
+ if (types.length != 1) {
+ throw new ConfigException("Failed to evaluate target type for " + method.getDeclaringClass()
+ .getName() + '.' + method.getName());
+ }
+ targetType = types[0];
+ }
+ PropertyConverter<Object> propertyConverter = null;
+ WithPropertyConverter annot = method.getAnnotation(WithPropertyConverter.class);
+ if (annot != null) {
+ try {
+ propertyConverter = (PropertyConverter<Object>) annot.value().newInstance();
+ } catch (Exception e) {
+ throw new ConfigException("Failed to instantiate annotated PropertyConverter on " +
+ method.getDeclaringClass().getName()
+ + '.' + method.getName(), e);
+ }
+ }
+ return new DefaultDynamicValue<>(method.getName(),
+ configuration, TypeLiteral.of(targetType), propertyConverter, InjectionUtils.getKeys(method),
+ loadPolicy, updatePolicy);
+ }
+
+
+ /**
+ * Commits a new value that has not been committed yet, make it the new value of the instance. On change any
+ * registered listeners will be triggered.
+ */
+ public void commit() {
+ T oldValue = value;
+ value = newValue==null?null:(T)newValue[0];
+ newValue = null;
+ informListeners(oldValue, value);
+ }
+
+ private void informListeners(T value, T newValue) {
+ synchronized (this) {
+ PropertyChangeEvent evt = new PropertyChangeEvent(this, propertyName, value,
+ newValue);
+ if (listeners != null) {
+ for (PropertyChangeListener consumer : listeners.get()) {
+ consumer.propertyChange(evt);
+ }
+ }
+ }
+ }
+
+ /**
+ * Discards a new value that was published. No listeners will be informed.
+ */
+ public void discard() {
+ newValue = null;
+ }
+
+
+ /**
+ * Access the {@link UpdatePolicy} used for updating this value.
+ *
+ * @return the update policy, never null.
+ */
+ public UpdatePolicy getUpdatePolicy() {
+ return updatePolicy;
+ }
+
+ /**
+ * Sets a new {@link UpdatePolicy}.
+ *
+ * @param updatePolicy the new policy, not null.
+ */
+ public void setUpdatePolicy(UpdatePolicy updatePolicy) {
+ this.updatePolicy = Objects.requireNonNull(updatePolicy);
+ }
+
+ /**
+ * Add a listener to be called as weak reference, when this value has been changed.
+ *
+ * @param l the listener, not null
+ */
+ public void addListener(PropertyChangeListener l) {
+ if (listeners == null) {
+ listeners = new WeakList<>();
+ }
+ listeners.add(l);
+ }
+
+ /**
+ * Removes a listener to be called, when this value has been changed.
+ *
+ * @param l the listner to be removed, not null
+ */
+ public void removeListener(PropertyChangeListener l) {
+ if (listeners != null) {
+ listeners.remove(l);
+ }
+ }
+
+ /**
+ * If a value is present in this {@code DynamicValue}, returns the value,
+ * otherwise throws {@code ConfigException}.
+ *
+ * @return the non-null value held by this {@code Optional}
+ * @throws ConfigException if there is no value present
+ * @see DefaultDynamicValue#isPresent()
+ */
+ public T get() {
+ T newLocalValue;
+ if(loadPolicy!=LoadPolicy.INITIAL) {
+ newLocalValue = evaluateValue();
+ if (this.value == null) {
+ this.value = newLocalValue;
+ }
+ if(!Objects.equals(this.value, newLocalValue)){
+ switch (updatePolicy){
+ case IMMEDEATE:
+ commit();
+ break;
+ case EXPLCIT:
+ this.newValue = new Object[]{newLocalValue};
+ break;
+ case LOG_ONLY:
+ informListeners(this.value, newLocalValue);
+ this.newValue = null;
+ break;
+ case NEVER:
+ this.newValue = null;
+ break;
+ default:
+ this.newValue = null;
+ break;
+ }
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Method to check for and apply a new value. Depending on the {@link UpdatePolicy}
+ * the value is immediately or deferred visible (or it may even be ignored completely).
+ *
+ * @return true, if a new value has been detected. The value may not be visible depending on the current
+ * {@link UpdatePolicy} in place.
+ */
+ public boolean updateValue() {
+ if(this.value==null && this.newValue==null){
+ this.value = evaluateValue();
+ return false;
+ }
+ T newValue = evaluateValue();
+ if (Objects.equals(newValue, this.value)) {
+ return false;
+ }
+ switch (this.updatePolicy) {
+ case LOG_ONLY:
+ Logger.getLogger(getClass().getName()).info("Discard change on " + this + ", newValue=" + newValue);
+ informListeners(value, newValue);
+ this.newValue = null;
+ break;
+ case NEVER:
+ this.newValue = null;
+ break;
+ case EXPLCIT:
+ case IMMEDEATE:
+ default:
+ this.newValue = new Object[]{newValue};
+ commit();
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * Evaluates the current value dynamically from the underlying configuration.
+ *
+ * @return the current actual value, or null.
+ */
+ public T evaluateValue() {
+ T value = null;
+
+ for (String key : keys) {
+ ConversionContext ctx = new ConversionContext.Builder(key, targetType).build();
+ if (propertyConverter == null) {
+ value = configuration.get(key, targetType);
+ } else {
+ String source = configuration.get(key);
+ value = propertyConverter.convert(source, ctx);
+ }
+
+ if (value != null) {
+ break;
+ }
+ }
+
+ return value;
+ }
+
+ /**
+ * Access a new value that has not yet been committed.
+ *
+ * @return the uncommitted new value, or null.
+ */
+ public T getNewValue() {
+ T nv = newValue==null?null:(T)newValue[0];
+ if (nv != null) {
+ return nv;
+ }
+ return null;
+ }
+
+
+ /**
+ * Serialization implementation that strips away the non serializable Optional part.
+ *
+ * @param oos the output stream
+ * @throws IOException if serialization fails.
+ */
+ private void writeObject(ObjectOutputStream oos) throws IOException {
+ oos.writeObject(getUpdatePolicy());
+ oos.writeObject(get());
+ }
+
+ /**
+ * Reads an instance from the input stream.
+ *
+ * @param ois the object input stream
+ * @throws IOException if deserialization fails.
+ * @throws ClassNotFoundException
+ */
+ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+ this.updatePolicy = (UpdatePolicy) ois.readObject();
+ if (isPresent()) {
+ this.value = (T) ois.readObject();
+ }
+ newValue = null;
+ }
+
+
+ /**
+ * Simple helper that allows keeping the listeners registered as weak references, hereby avoiding any
+ * memory leaks.
+ *
+ * @param <I> the type
+ */
+ private class WeakList<I> {
+ final List<WeakReference<I>> refs = new LinkedList<>();
+
+ /**
+ * Adds a new instance.
+ *
+ * @param t the new instance, not null.
+ */
+ void add(I t) {
+ refs.add(new WeakReference<>(t));
+ }
+
+ /**
+ * Removes a instance.
+ *
+ * @param t the instance to be removed.
+ */
+ void remove(I t) {
+ synchronized (refs) {
+ for (Iterator<WeakReference<I>> iterator = refs.iterator(); iterator.hasNext(); ) {
+ WeakReference<I> ref = iterator.next();
+ I instance = ref.get();
+ if (instance == null || instance == t) {
+ iterator.remove();
+ break;
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Access a list (copy) of the current instances that were not discarded by the GC.
+ *
+ * @return the list of accessible items.
+ */
+ public List<I> get() {
+ synchronized (refs) {
+ List<I> res = new ArrayList<>();
+ for (Iterator<WeakReference<I>> iterator = refs.iterator(); iterator.hasNext(); ) {
+ WeakReference<I> ref = iterator.next();
+ I instance = ref.get();
+ if (instance == null) {
+ iterator.remove();
+ } else {
+ res.add(instance);
+ }
+ }
+ return res;
+ }
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/InjectionHelper.java
----------------------------------------------------------------------
diff --git a/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/InjectionHelper.java b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/InjectionHelper.java
new file mode 100644
index 0000000..305a660
--- /dev/null
+++ b/modules/injection/standalone/src/main/java/org/apache/tamaya/inject/internal/InjectionHelper.java
@@ -0,0 +1,244 @@
+/*
+ * 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.internal;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.events.ConfigEventManager;
+import org.apache.tamaya.events.spi.BaseConfigEvent;
+import org.apache.tamaya.inject.api.Config;
+import org.apache.tamaya.inject.api.ConfigDefaultSections;
+import org.apache.tamaya.inject.api.InjectionUtils;
+import org.apache.tamaya.inject.api.WithPropertyConverter;
+import org.apache.tamaya.inject.spi.ConfiguredType;
+import org.apache.tamaya.resolver.spi.ExpressionEvaluator;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+
+/**
+ * Utility class containing several aspects used in this module.
+ */
+@SuppressWarnings("unchecked")
+final class InjectionHelper {
+
+ private static final Logger LOG = Logger.getLogger(InjectionHelper.class.getName());
+
+ private static final boolean RESOLUTION_MODULE_LOADED = checkResolutionModuleLoaded();
+
+ private static final boolean EVENTS_AVAILABLE = checkForEvents();
+
+ private static boolean checkForEvents() {
+ try{
+ Class.forName("org.apache.tamaya.events.FrozenConfiguration");
+ LOG.info("Detected tamaya-events is loaded, will trigger ConfigEvents...");
+ return true;
+ } catch(Exception e){
+ LOG.info("Detected tamaya-events not found, will not trigger any ConfigEvents...");
+ return false;
+ }
+ }
+
+ private static boolean checkResolutionModuleLoaded() {
+ try {
+ Class.forName("org.apache.tamaya.resolver.internal.DefaultExpressionEvaluator");
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
+ private InjectionHelper() {
+ }
+
+ /**
+ * Internally evaluated the current valid configuration keys based on the given annotations present.
+ * @param method the method
+ * @return the keys to be returned, or null.
+ */
+ public static String getConfigValue(Method method, Configuration config) {
+ return getConfigValue(method, null, config);
+ }
+
+ /**
+ * Internally evaluated the current valid configuration keys based on the given annotations present.
+ * @param method the method
+ * @param retKey the array to return the key found, or null.
+ * @return the keys to be returned, or null.
+ */
+ public static String getConfigValue(Method method, String[] retKey, Configuration config) {
+ ConfigDefaultSections areasAnnot = method.getDeclaringClass().getAnnotation(ConfigDefaultSections.class);
+ return getConfigValueInternal(method, areasAnnot, retKey, config);
+ }
+
+ /**
+ * Internally evaluated the current valid configuration keys based on the given annotations present.
+ * @param field the field
+ * @return the keys to be returned, or null.
+ */
+ public static String getConfigValue(Field field, Configuration config) {
+ return getConfigValue(field, null, config);
+ }
+
+ /**
+ * Internally evaluated the current valid configuration keys based on the given annotations present.
+ * @param field the field
+ * @param retKey the array to return the key found, or null.
+ * @return the keys to be returned, or null.
+ */
+ public static String getConfigValue(Field field, String[] retKey, Configuration config) {
+ ConfigDefaultSections areasAnnot = field.getDeclaringClass().getAnnotation(ConfigDefaultSections.class);
+ return getConfigValueInternal(field, areasAnnot, retKey, config);
+ }
+
+ /**
+ * Internally evaluated the current valid configuration keys based on the given annotations present.
+ *
+ * @return the keys to be returned, or null.
+ */
+ private static String getConfigValueInternal(AnnotatedElement element, ConfigDefaultSections areasAnnot, String[] retKey, Configuration config) {
+ Config prop = element.getAnnotation(Config.class);
+ List<String> keys;
+ if (prop == null) {
+ keys = InjectionUtils.evaluateKeys((Member) element, areasAnnot);
+ } else {
+ keys = InjectionUtils.evaluateKeys((Member) element, areasAnnot, prop);
+ }
+ String configValue = evaluteConfigValue(keys, retKey, config);
+ if (configValue == null) {
+ if(prop==null || prop.defaultValue().isEmpty()){
+ return null;
+ }
+ return prop.defaultValue();
+ }
+ return configValue;
+ }
+
+
+ private static String evaluteConfigValue(List<String> keys, String[] retKey, Configuration config) {
+ String configValue = null;
+ for (String key : keys) {
+ configValue = config.get(key);
+ if (configValue != null) {
+ if(retKey!=null && retKey.length>0){
+ retKey[0] = key;
+ }
+ break;
+ }
+ }
+ return configValue;
+ }
+
+
+ @SuppressWarnings("rawtypes")
+ public static <T> T adaptValue(AnnotatedElement element, TypeLiteral<T> targetType, String key, String configValue) {
+ // Check for adapter/filter
+ T adaptedValue = null;
+ WithPropertyConverter converterAnnot = element.getAnnotation(WithPropertyConverter.class);
+ Class<? extends PropertyConverter<T>> converterType;
+ if (converterAnnot != null) {
+ converterType = (Class<? extends PropertyConverter<T>>) converterAnnot.value();
+ if (!converterType.getName().equals(WithPropertyConverter.class.getName())) {
+ try {
+ // TODO cache here...
+ ConversionContext ctx = new ConversionContext.Builder(key,targetType)
+ .setAnnotatedElement(element).build();
+
+ PropertyConverter<T> converter = PropertyConverter.class.cast(converterType.newInstance());
+ adaptedValue = converter.convert(configValue, ctx);
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE, "Failed to convert using explicit PropertyConverter on " + element +
+ ", trying default conversion.", e);
+ }
+ }
+ }
+ if (adaptedValue != null) {
+ return adaptedValue;
+ }
+ if (String.class == targetType.getType()) {
+ return (T) configValue;
+ } else{
+ if(configValue==null) {
+ return null;
+ }
+ ConfigurationContext configContext = ConfigurationProvider.getConfiguration().getContext();
+ List<PropertyConverter<T>> converters = configContext
+ .getPropertyConverters(targetType);
+ ConversionContext ctx = new ConversionContext.Builder(ConfigurationProvider.getConfiguration(),
+ configContext, key, targetType).setAnnotatedElement(element).build();
+ for (PropertyConverter<T> converter : converters) {
+ adaptedValue = converter.convert(configValue, ctx);
+ if (adaptedValue != null) {
+ return adaptedValue;
+ }
+ }
+ }
+ throw new ConfigException("Non convertible property type: " + element);
+ }
+
+ /**
+ * Method that allows to statically check, if the resolver module is loaded. If the module is loaded
+ * value expressions are automatically forwarded to the resolver module for resolution.
+ *
+ * @return true, if the resolver module is on the classpath.
+ */
+ public static boolean isResolutionModuleLoaded() {
+ return RESOLUTION_MODULE_LOADED;
+ }
+
+ /**
+ * Evaluates the given expression.
+ *
+ * @param expression the expression, not null.
+ * @return the evaluated expression.
+ */
+ public static String evaluateValue(String expression) {
+ if (!RESOLUTION_MODULE_LOADED) {
+ return expression;
+ }
+ ExpressionEvaluator evaluator = ServiceContextManager.getServiceContext().getService(ExpressionEvaluator.class);
+ if (evaluator != null) {
+ return evaluator.evaluateExpression("<injection>", expression, true);
+ }
+ return expression;
+ }
+
+ /**
+ * This method distributes the configuration event, if the Tamaya event module is accessible.
+ * When Tamaya events are not available, the call simply returns.
+ * @param event the event to be distributed, not null.
+ */
+ static void sendConfigurationEvent(ConfiguredType event) {
+ if(EVENTS_AVAILABLE){
+ ConfigEventManager.fireEvent(new BaseConfigEvent<ConfiguredType>(event, ConfiguredType.class) {});
+ }
+ }
+}
[12/15] incubator-tamaya-extensions git commit: TAMAYA-189: Moved
format and injection modules into separate subtrees.
Posted by an...@apache.org.
TAMAYA-189: Moved format and injection modules into separate subtrees.
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/fe7cd8f1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/tree/fe7cd8f1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/diff/fe7cd8f1
Branch: refs/heads/master
Commit: fe7cd8f1bb151a1891196e1899470e5f93abf7e9
Parents: c757d32
Author: anatole <an...@apache.org>
Authored: Sun Oct 30 22:57:31 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Sun Oct 30 22:57:31 2016 +0100
----------------------------------------------------------------------
modules/formats/common/pom.xml | 88 ++++
.../BaseFormatPropertySourceProvider.java | 154 ++++++
.../apache/tamaya/format/ConfigurationData.java | 206 ++++++++
.../tamaya/format/ConfigurationDataBuilder.java | 219 ++++++++
.../tamaya/format/ConfigurationFormat.java | 103 ++++
.../tamaya/format/ConfigurationFormats.java | 187 +++++++
.../format/FlattenedDefaultPropertySource.java | 118 +++++
.../tamaya/format/InputStreamFactory.java | 89 ++++
.../format/formats/IniConfigurationFormat.java | 95 ++++
.../tamaya/format/formats/PropertiesFormat.java | 71 +++
.../format/formats/PropertiesXmlFormat.java | 69 +++
.../tamaya/format/formats/package-info.java | 23 +
.../org/apache/tamaya/format/package-info.java | 28 ++
...org.apache.tamaya.format.ConfigurationFormat | 21 +
.../tamaya/format/ConfigurationFormatsTest.java | 68 +++
.../FlattenedDefaultPropertySourceTest.java | 98 ++++
.../tamaya/format/InputStreamFactoryTest.java | 145 ++++++
.../formats/common/src/test/resources/Test.ini | 26 +
.../common/src/test/resources/Test.properties | 21 +
modules/formats/json/pom.xml | 149 ++++++
.../java/org/apache/tamaya/json/JSONFormat.java | 85 ++++
.../apache/tamaya/json/JSONPropertySource.java | 149 ++++++
.../org/apache/tamaya/json/JSONVisitor.java | 119 +++++
...org.apache.tamaya.format.ConfigurationFormat | 19 +
.../json/CommonJSONTestCaseCollection.java | 190 +++++++
.../org/apache/tamaya/json/JSONFormatIT.java | 48 ++
.../org/apache/tamaya/json/JSONFormatTest.java | 75 +++
.../tamaya/json/JSONPropertySourceTest.java | 56 +++
.../json/src/test/resources/arquillian.xml | 30 ++
.../test/resources/configs/invalid/array.json | 21 +
.../resources/configs/invalid/empty-file.json | 18 +
.../configs/invalid/only-opening-bracket.json | 19 +
.../resources/configs/invalid/with-array.json | 27 +
.../test/resources/configs/valid/cyrillic.json | 22 +
.../configs/valid/empty-object-config.json | 20 +
.../valid/simple-flat-string-only-config.json | 23 +
.../simple-nested-string-only-config-1.json | 27 +
.../simple-nested-string-only-config-2.json | 26 +
.../configs/valid/with-explicit-priority.json | 25 +
modules/formats/pom.xml | 104 +---
.../BaseFormatPropertySourceProvider.java | 154 ------
.../apache/tamaya/format/ConfigurationData.java | 206 --------
.../tamaya/format/ConfigurationDataBuilder.java | 219 --------
.../tamaya/format/ConfigurationFormat.java | 103 ----
.../tamaya/format/ConfigurationFormats.java | 187 -------
.../format/FlattenedDefaultPropertySource.java | 118 -----
.../tamaya/format/InputStreamFactory.java | 89 ----
.../format/formats/IniConfigurationFormat.java | 95 ----
.../tamaya/format/formats/PropertiesFormat.java | 71 ---
.../format/formats/PropertiesXmlFormat.java | 69 ---
.../tamaya/format/formats/package-info.java | 23 -
.../org/apache/tamaya/format/package-info.java | 28 --
...org.apache.tamaya.format.ConfigurationFormat | 21 -
.../tamaya/format/ConfigurationFormatsTest.java | 68 ---
.../FlattenedDefaultPropertySourceTest.java | 98 ----
.../tamaya/format/InputStreamFactoryTest.java | 145 ------
modules/formats/src/test/resources/Test.ini | 26 -
.../formats/src/test/resources/Test.properties | 21 -
modules/formats/yaml/pom.xml | 119 +++++
.../java/org/apache/tamaya/json/YAMLFormat.java | 156 ++++++
.../apache/tamaya/json/YAMLPropertySource.java | 100 ++++
...org.apache.tamaya.format.ConfigurationFormat | 19 +
.../org/apache/tamaya/json/YAMLFormatTest.java | 73 +++
.../tamaya/json/YAMLPropertySourceTest.java | 54 ++
.../test/resources/configs/valid/contact.yaml | 46 ++
.../resources/configs/valid/test-with-prio.yaml | 39 ++
.../src/test/resources/configs/valid/test.yaml | 35 ++
modules/injection-api/pom.xml | 81 ---
.../tamaya/inject/api/BaseDynamicValue.java | 125 -----
.../org/apache/tamaya/inject/api/Config.java | 93 ----
.../tamaya/inject/api/ConfigAutoInject.java | 36 --
.../inject/api/ConfigDefaultSections.java | 44 --
.../inject/api/ConfiguredItemSupplier.java | 41 --
.../apache/tamaya/inject/api/DynamicValue.java | 161 ------
.../tamaya/inject/api/InjectionUtils.java | 127 -----
.../apache/tamaya/inject/api/LoadPolicy.java | 42 --
.../org/apache/tamaya/inject/api/NoConfig.java | 36 --
.../apache/tamaya/inject/api/UpdatePolicy.java | 40 --
.../tamaya/inject/api/WithConfigOperator.java | 45 --
.../inject/api/WithPropertyConverter.java | 46 --
.../apache/tamaya/inject/api/package-info.java | 22 -
.../tamaya/inject/spi/ConfiguredField.java | 68 ---
.../tamaya/inject/spi/ConfiguredMethod.java | 70 ---
.../tamaya/inject/spi/ConfiguredType.java | 63 ---
modules/injection/cdi-ee/pom.xml | 226 +++++++++
.../integration/cdi/CDIAwareServiceContext.java | 169 +++++++
.../integration/cdi/CDIConfiguredField.java | 77 +++
.../integration/cdi/CDIConfiguredMethod.java | 77 +++
.../integration/cdi/CDIConfiguredType.java | 94 ++++
.../integration/cdi/ConfigurationExtension.java | 290 +++++++++++
.../integration/cdi/ConfigurationProducer.java | 147 ++++++
.../integration/cdi/DefaultDynamicValue.java | 499 +++++++++++++++++++
.../cdi/ServiceLoaderServiceContext.java | 151 ++++++
.../integration/cdi/TamayaCDIIntegration.java | 52 ++
.../src/main/resources/META-INF/beans.xml | 19 +
.../javax.enterprise.inject.spi.Extension | 19 +
.../org.apache.tamaya.spi.ServiceContext | 38 ++
...onfigurationProducerFailedInjectionTest.java | 33 ++
.../cdi/ConfigurationProducerTest.java | 168 +++++++
.../cdi/ConfigurationResolverTest.java | 112 +++++
.../integration/cdi/EnvironmentsTest.java | 83 +++
.../integration/cdi/InterpolationTest.java | 62 +++
.../integration/cdi/NotFoundNoDefault.java | 78 +++
.../src/test/resources/META-INF/beans.xml | 19 +
.../META-INF/javaconfiguration.properties | 32 ++
.../cdi-ee/src/test/resources/base.properties | 32 ++
.../cdi-ee/src/test/resources/cert.properties | 20 +
.../cdi-ee/src/test/resources/dev.properties | 19 +
.../cdi-ee/src/test/resources/prod.properties | 20 +
.../cdi-ee/src/test/resources/qa.properties | 20 +
.../cdi-ee/src/test/resources/test.properties | 20 +
modules/injection/cdi-se/pom.xml | 212 ++++++++
.../integration/cdi/CDIAwareServiceContext.java | 169 +++++++
.../cdi/DefaultConfigurationContext.java | 296 +++++++++++
.../cdi/DefaultConfigurationContextBuilder.java | 152 ++++++
.../tamaya/integration/cdi/EnumConverter.java | 71 +++
.../cdi/PropertyConverterManager.java | 427 ++++++++++++++++
.../integration/cdi/SEInjectorCDIExtension.java | 112 +++++
.../cdi/ServiceLoaderServiceContext.java | 151 ++++++
.../integration/cdi/TamayaCDIIntegration.java | 52 ++
.../integration/cdi/TamayaConfigProvider.java | 55 ++
.../cdi/config/ConfiguredVetoExtension.java | 42 ++
.../src/main/resources/META-INF/beans.xml | 24 +
.../javax.enterprise.inject.spi.Extension | 20 +
.../org.apache.tamaya.spi.ServiceContext | 19 +
.../tamaya/integration/cdi/ConfiguredClass.java | 112 +++++
.../tamaya/integration/cdi/ConfiguredTest.java | 83 +++
.../tamaya/integration/cdi/InjectedClass.java | 62 +++
.../cdi/cfg/ProvidedPropertySource.java | 67 +++
.../integration/cdi/cfg/TestConfigProvider.java | 45 ++
.../integration/cdi/cfg/TestPropertySource.java | 79 +++
.../src/test/resources/META-INF/beans.xml | 24 +
.../META-INF/javaconfiguration.properties | 20 +
modules/injection/injection-api/pom.xml | 81 +++
.../tamaya/inject/api/BaseDynamicValue.java | 125 +++++
.../org/apache/tamaya/inject/api/Config.java | 93 ++++
.../tamaya/inject/api/ConfigAutoInject.java | 36 ++
.../inject/api/ConfigDefaultSections.java | 44 ++
.../inject/api/ConfiguredItemSupplier.java | 41 ++
.../apache/tamaya/inject/api/DynamicValue.java | 161 ++++++
.../tamaya/inject/api/InjectionUtils.java | 127 +++++
.../apache/tamaya/inject/api/LoadPolicy.java | 42 ++
.../org/apache/tamaya/inject/api/NoConfig.java | 36 ++
.../apache/tamaya/inject/api/UpdatePolicy.java | 40 ++
.../tamaya/inject/api/WithConfigOperator.java | 45 ++
.../inject/api/WithPropertyConverter.java | 46 ++
.../apache/tamaya/inject/api/package-info.java | 22 +
.../tamaya/inject/spi/ConfiguredField.java | 68 +++
.../tamaya/inject/spi/ConfiguredMethod.java | 70 +++
.../tamaya/inject/spi/ConfiguredType.java | 63 +++
modules/injection/pom.xml | 123 ++---
.../tamaya/inject/ConfigurationInjection.java | 42 --
.../tamaya/inject/ConfigurationInjector.java | 94 ----
.../ConfigTemplateInvocationHandler.java | 73 ---
.../inject/internal/ConfiguredFieldImpl.java | 170 -------
.../inject/internal/ConfiguredSetterMethod.java | 139 ------
.../inject/internal/ConfiguredTypeImpl.java | 237 ---------
.../internal/DefaultConfigurationInjector.java | 179 -------
.../inject/internal/DefaultDynamicValue.java | 498 ------------------
.../tamaya/inject/internal/InjectionHelper.java | 244 ---------
.../apache/tamaya/inject/internal/Utils.java | 128 -----
.../tamaya/inject/internal/package-info.java | 22 -
.../org/apache/tamaya/inject/package-info.java | 22 -
...g.apache.tamaya.inject.ConfigurationInjector | 19 -
.../java/annottext/AnnotatedConfigBean.java | 78 ---
.../java/annottext/AnnotatedConfigTemplate.java | 47 --
.../java/annottext/NonAnnotatedConfigBean.java | 45 --
.../tamaya/inject/TamayaInjectionTest.java | 87 ----
.../tamaya/inject/TestPropertySource.java | 68 ---
.../internal/DefaultDynamicValueTest.java | 315 ------------
.../org.apache.tamaya.spi.PropertySource | 19 -
modules/injection/standalone/pom.xml | 104 ++++
.../tamaya/inject/ConfigurationInjection.java | 42 ++
.../tamaya/inject/ConfigurationInjector.java | 94 ++++
.../ConfigTemplateInvocationHandler.java | 73 +++
.../inject/internal/ConfiguredFieldImpl.java | 170 +++++++
.../inject/internal/ConfiguredSetterMethod.java | 139 ++++++
.../inject/internal/ConfiguredTypeImpl.java | 237 +++++++++
.../internal/DefaultConfigurationInjector.java | 179 +++++++
.../inject/internal/DefaultDynamicValue.java | 498 ++++++++++++++++++
.../tamaya/inject/internal/InjectionHelper.java | 244 +++++++++
.../apache/tamaya/inject/internal/Utils.java | 128 +++++
.../tamaya/inject/internal/package-info.java | 22 +
.../org/apache/tamaya/inject/package-info.java | 22 +
...g.apache.tamaya.inject.ConfigurationInjector | 19 +
.../java/annottext/AnnotatedConfigBean.java | 78 +++
.../java/annottext/AnnotatedConfigTemplate.java | 47 ++
.../java/annottext/NonAnnotatedConfigBean.java | 45 ++
.../tamaya/inject/TamayaInjectionTest.java | 87 ++++
.../tamaya/inject/TestPropertySource.java | 68 +++
.../internal/DefaultDynamicValueTest.java | 315 ++++++++++++
.../org.apache.tamaya.spi.PropertySource | 19 +
modules/json/pom.xml | 149 ------
.../java/org/apache/tamaya/json/JSONFormat.java | 85 ----
.../apache/tamaya/json/JSONPropertySource.java | 149 ------
.../org/apache/tamaya/json/JSONVisitor.java | 119 -----
...org.apache.tamaya.format.ConfigurationFormat | 19 -
.../json/CommonJSONTestCaseCollection.java | 190 -------
.../org/apache/tamaya/json/JSONFormatIT.java | 48 --
.../org/apache/tamaya/json/JSONFormatTest.java | 75 ---
.../tamaya/json/JSONPropertySourceTest.java | 56 ---
modules/json/src/test/resources/arquillian.xml | 30 --
.../test/resources/configs/invalid/array.json | 21 -
.../resources/configs/invalid/empty-file.json | 18 -
.../configs/invalid/only-opening-bracket.json | 19 -
.../resources/configs/invalid/with-array.json | 27 -
.../test/resources/configs/valid/cyrillic.json | 22 -
.../configs/valid/empty-object-config.json | 20 -
.../valid/simple-flat-string-only-config.json | 23 -
.../simple-nested-string-only-config-1.json | 27 -
.../simple-nested-string-only-config-2.json | 26 -
.../configs/valid/with-explicit-priority.json | 25 -
modules/pom.xml | 4 +-
modules/yaml/pom.xml | 119 -----
.../java/org/apache/tamaya/json/YAMLFormat.java | 156 ------
.../apache/tamaya/json/YAMLPropertySource.java | 100 ----
...org.apache.tamaya.format.ConfigurationFormat | 19 -
.../org/apache/tamaya/json/YAMLFormatTest.java | 73 ---
.../tamaya/json/YAMLPropertySourceTest.java | 54 --
.../test/resources/configs/valid/contact.yaml | 46 --
.../resources/configs/valid/test-with-prio.yaml | 39 --
.../src/test/resources/configs/valid/test.yaml | 35 --
222 files changed, 12315 insertions(+), 7370 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/pom.xml
----------------------------------------------------------------------
diff --git a/modules/formats/common/pom.xml b/modules/formats/common/pom.xml
new file mode 100644
index 0000000..93f4bd2
--- /dev/null
+++ b/modules/formats/common/pom.xml
@@ -0,0 +1,88 @@
+<!--
+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 current 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-formats-all</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>tamaya-formats</artifactId>
+ <name>Apache Tamaya Modules Formats</name>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <jdkVersion>1.7</jdkVersion>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-resources</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <!-- Test scope only, do not create a code dependency! -->
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-core</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>java-hamcrest</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.tamaya.format,
+ org.apache.tamaya.format.formats
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/main/java/org/apache/tamaya/format/BaseFormatPropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/main/java/org/apache/tamaya/format/BaseFormatPropertySourceProvider.java b/modules/formats/common/src/main/java/org/apache/tamaya/format/BaseFormatPropertySourceProvider.java
new file mode 100644
index 0000000..84d6cfa
--- /dev/null
+++ b/modules/formats/common/src/main/java/org/apache/tamaya/format/BaseFormatPropertySourceProvider.java
@@ -0,0 +1,154 @@
+/*
+ * 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.format;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertySourceProvider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of a {@link PropertySourceProvider} that reads configuration from some given resource paths
+ * and using the given formats. The resource path are resolved as classpath resources. This can be changed by
+ * overriding {@link #getPropertySources()}.
+ * For each resource found the configuration formats passed get a chance to read the resource, if they succeed the
+ * result is taken as the providers PropertySources to be exposed.
+ */
+public abstract class BaseFormatPropertySourceProvider implements PropertySourceProvider {
+ /**
+ * The logger used.
+ */
+ private static final Logger LOG = Logger.getLogger(BaseFormatPropertySourceProvider.class.getName());
+ /**
+ * The config formats supported for the given location/resource paths.
+ */
+ private final List<ConfigurationFormat> configFormats = new ArrayList<>();
+ /**
+ * The paths to be evaluated.
+ */
+ private final Collection<URL> paths = new ArrayList<>();
+
+ /**
+ * Creates a new instance.
+ *
+ * @param formats the formats to be used, not null, not empty.
+ * @param paths the paths to be resolved, not null, not empty.
+ */
+ public BaseFormatPropertySourceProvider(
+ List<ConfigurationFormat> formats,
+ URL... paths) {
+ this.configFormats.addAll(Objects.requireNonNull(formats));
+ this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
+ }
+
+ /**
+ * Creates a new instance, hereby using the current thread context classloader, or if not available the classloader
+ * that loaded this class.
+ * @param formats the formats to be used, not null, not empty.
+ * @param paths the paths to be resolved, not null, not empty.
+ */
+ public BaseFormatPropertySourceProvider(
+ List<ConfigurationFormat> formats, String... paths) {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if(cl==null){
+ cl = getClass().getClassLoader();
+ }
+ this.configFormats.addAll(Objects.requireNonNull(formats));
+ for(String path:paths) {
+ Enumeration<URL> urls;
+ try {
+ urls = cl.getResources(path);
+ } catch (IOException e) {
+ LOG.log(Level.WARNING, "Failed to read resource: " + path, e);
+ continue;
+ }
+ while(urls.hasMoreElements()) {
+ this.paths.add(urls.nextElement());
+ }
+ }
+ }
+
+ /**
+ * Creates a new instance.
+ *
+ * @param classLoader the ClassLoader to be used, not null, not empty.
+ * @param formats the formats to be used, not null, not empty.
+ * @param paths the paths to be resolved, not null, not empty.
+ */
+ public BaseFormatPropertySourceProvider(
+ List<ConfigurationFormat> formats,
+ ClassLoader classLoader, String... paths) {
+ this.configFormats.addAll(Objects.requireNonNull(formats));
+ for(String path:paths) {
+ Enumeration<URL> urls;
+ try {
+ urls = classLoader.getResources(path);
+ } catch (IOException e) {
+ LOG.log(Level.WARNING, "Failed to read resource: " + path, e);
+ continue;
+ }
+ while(urls.hasMoreElements()) {
+ this.paths.add(urls.nextElement());
+ }
+ }
+ }
+
+
+ /**
+ * Method to create a {@link org.apache.tamaya.spi.PropertySource} based on the given entries read.
+ *
+ * @param data the configuration data, not null.
+ * @return the {@link org.apache.tamaya.spi.PropertySource} instance ready to be registered.
+ */
+ protected abstract Collection<PropertySource> getPropertySources(ConfigurationData data);
+
+ /**
+ * This method does dynamically resolve the paths using the current ClassLoader set. If no ClassLoader was
+ * explcitly set during creation the current Thread context ClassLoader is used. If none of the supported
+ * formats is able to parse a resource a WARNING log is written.
+ *
+ * @return the PropertySources successfully read
+ */
+ @Override
+ public Collection<PropertySource> getPropertySources() {
+ List<PropertySource> propertySources = new ArrayList<>();
+ for (URL res : this.paths) {
+ try(InputStream is = res.openStream()) {
+ for (ConfigurationFormat format : configFormats) {
+ ConfigurationData data = format.readConfiguration(res.toString(), is);
+ propertySources.addAll(getPropertySources(data));
+ }
+ } catch (Exception e) {
+ LOG.log(Level.WARNING, "Failed to put resource based config: " + res, e);
+ }
+ }
+ return propertySources;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationData.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationData.java b/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationData.java
new file mode 100644
index 0000000..b58d2ab
--- /dev/null
+++ b/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationData.java
@@ -0,0 +1,206 @@
+/*
+ * 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.format;
+
+import java.util.*;
+
+/**
+ * <p>Data that abstracts the data read from a configuration resources using a certain format. The data can be divided
+ * into different sections, similar to ini-files. Herebey different sections the best map to entries with different
+ * priorities to be applied, when integrated into PropertySource instances.</p>
+ * New instances of this class can be created using a {@link org.apache.tamaya.format.ConfigurationDataBuilder}.
+ * <h3>Implementation Specification</h3>
+ * This class is
+ * <ul>
+ * <li>immutable</li>
+ * <li>thread-safe</li>
+ * </ul>
+ */
+public final class ConfigurationData {
+ /**
+ * The properties of the default section (no name).
+ */
+ private Map<String, String> defaultProperties;
+ /**
+ * A normalized flattened set of this configuration data.
+ */
+ private Map<String, String> combinedProperties;
+ /**
+ * The sections read.
+ */
+ private Map<String, Map<String, String>> namedSections;
+ /** The format instance used to read this instance. */
+ private final ConfigurationFormat format;
+ /** The resource read. */
+ private final String resource;
+
+
+ /**
+ * COnstructor used by builder.
+ * @param builder the builder instance passing the read configuration data.
+ */
+ ConfigurationData(ConfigurationDataBuilder builder){
+ this.format = builder.format;
+ this.resource = builder.resource;
+ if (builder.defaultProperties != null) {
+ this.defaultProperties = new HashMap<>();
+ this.defaultProperties.putAll(builder.defaultProperties);
+ }
+ if (builder.combinedProperties != null) {
+ this.combinedProperties = new HashMap<>();
+ this.combinedProperties.putAll(builder.combinedProperties);
+ }
+ if (builder.namedSections != null) {
+ this.namedSections = new HashMap<>();
+ this.namedSections.putAll(builder.namedSections);
+ }
+ if (this.combinedProperties == null || this.combinedProperties.isEmpty()) {
+ this.combinedProperties = new HashMap<>();
+ this.combinedProperties.putAll(getDefaultProperties());
+ // popuilate it with sections...
+ for (String sectionName : getSectionNames()) {
+ Map<String, String> section = getSection(sectionName);
+ for (Map.Entry<String, String> en : section.entrySet()) {
+ String key = sectionName + '.' + en.getKey();
+ combinedProperties.put(key, en.getValue());
+ }
+ }
+ }
+ }
+
+ /**
+ * Get the {@link org.apache.tamaya.format.ConfigurationFormat} that read this data.
+ * @return the {@link org.apache.tamaya.format.ConfigurationFormat} that read this data, never null.
+ */
+ public ConfigurationFormat getFormat(){
+ return format;
+ }
+
+ /**
+ * Get the resource from which this data was read.
+ * @return the resource from which this data was read, never null.
+ */
+ public String getResource(){
+ return resource;
+ }
+
+ /**
+ * Access an immutable Set of all present section names, including the default section (if any).
+ * @return the set of present section names, never null.
+ */
+ public Set<String> getSectionNames() {
+ if (namedSections == null) {
+ return Collections.emptySet();
+ }
+ return namedSections.keySet();
+ }
+
+ /**
+ * Get a section's data.
+ * @param name the section name, not null.
+ * @return the data of this section, or null, if no such section exists.
+ */
+ public Map<String, String> getSection(String name) {
+ return this.namedSections.get(name);
+ }
+
+ /**
+ * Convenience accessor for accessing the default section.
+ * @return the default section's data, or null, if no such section exists.
+ */
+ public Map<String, String> getDefaultProperties() {
+ if (defaultProperties == null) {
+ return Collections.emptyMap();
+ }
+ return defaultProperties;
+ }
+
+ /**
+ * Get combined properties for this config data instance. If
+ *
+ * @return the normalized properties.
+ */
+ public Map<String, String> getCombinedProperties() {
+ if (combinedProperties == null) {
+ return Collections.emptyMap();
+ }
+ return combinedProperties;
+ }
+
+ /**
+ * Accessor used for easily creating a new builder based on a given data instance.
+ *
+ * @return the data contained, never null.
+ */
+ public Map<String, Map<String, String>> getSections() {
+ if (namedSections == null) {
+ return Collections.emptyMap();
+ }
+ return namedSections;
+ }
+
+ /**
+ * Immutable accessor to ckeck, if there are default properties present.
+ *
+ * @return true, if default properties are present.
+ */
+ public boolean hasDefaultProperties() {
+ return this.defaultProperties != null && !this.defaultProperties.isEmpty();
+ }
+
+ /**
+ * Immutable accessor to ckeck, if there are combined properties set.
+ *
+ * @return true, if combined properties are set.
+ */
+ public boolean hasCombinedProperties() {
+ return this.combinedProperties != null && !this.combinedProperties.isEmpty();
+ }
+
+ /**
+ * Immutable accessor to ckeck, if there are named sections present.
+ *
+ * @return true, if at least one named section is present.
+ */
+ private boolean hasSections() {
+ return this.namedSections != null && !this.namedSections.isEmpty();
+ }
+
+ /**
+ * Checks if no properties are contained in this data item.
+ *
+ * @return true, if no properties are contained in this data item.
+ */
+ public boolean isEmpty() {
+ return !hasCombinedProperties() && !hasDefaultProperties() && !hasSections();
+ }
+
+ @Override
+ public String toString() {
+ return "ConfigurationData{" +
+ "format=" + format +
+ ", default properties=" + defaultProperties +
+ ", combined properties=" + combinedProperties +
+ ", sections=" + namedSections +
+ ", resource=" + resource +
+ '}';
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java b/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java
new file mode 100644
index 0000000..da5fa35
--- /dev/null
+++ b/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java
@@ -0,0 +1,219 @@
+/*
+ * 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.format;
+
+import java.util.*;
+
+
+/**
+ * Builder for creating {@link org.apache.tamaya.format.ConfigurationData} instances. This class is not thread-safe.
+ */
+public final class ConfigurationDataBuilder {
+
+ /** The format instance used to read this instance. */
+ final ConfigurationFormat format;
+ /** The resource read. */
+ final String resource;
+ /**
+ * The properties of the default section (no name).
+ */
+ Map<String, String> defaultProperties;
+ /**
+ * A normalized flattened set of this configuration data.
+ */
+ Map<String, String> combinedProperties;
+ /**
+ * The sections read.
+ */
+ Map<String, Map<String, String>> namedSections;
+
+ /**
+ * Private constructor.
+ * @param resource the configuration resource URL, not null.
+ * @param format the format that read this data, not null.
+ */
+ private ConfigurationDataBuilder(String resource, ConfigurationFormat format){
+ this.format = Objects.requireNonNull(format);
+ this.resource = Objects.requireNonNull(resource);
+ }
+
+ /**
+ * Creates a new instance.
+ * @param resource the configuration resource URL, not null.
+ * @param format the format that read this data, not null.
+ * @return new instance of this class.
+ */
+ public static ConfigurationDataBuilder of(String resource, ConfigurationFormat format){
+ return new ConfigurationDataBuilder(resource, format);
+ }
+
+ /**
+ * Creates a new instance.
+ * @param data an existing ConfigurationData instances used to initialize the builder.
+ * @return new instance of this class from the given configuration.
+ */
+ public static ConfigurationDataBuilder of(ConfigurationData data){
+ ConfigurationDataBuilder b = new ConfigurationDataBuilder(data.getResource(), data.getFormat());
+ if (data.hasDefaultProperties()) {
+ b.getDefaultProperties().putAll(data.getDefaultProperties());
+ }
+ if (data.hasCombinedProperties()) {
+ b.getCombinedProperties().putAll(data.getCombinedProperties());
+ }
+ if (!data.getSections().isEmpty()) {
+ b.getSections().putAll(data.getSections());
+ }
+ return b;
+ }
+
+ /**
+ * Adds (empty) sections,if they are not yet existing. Already existing sections will not be touched.
+ * @param sections the new sections to put.
+ * @return the builder for chaining.
+ */
+ public ConfigurationDataBuilder addSections(String... sections){
+ for (String section : sections) {
+ if (!getSections().containsKey(section)) {
+ getSections().put(section, new HashMap<String, String>());
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Adds a single entry to a target section.
+ * @param section the target section (will be created if not existing).
+ * @param key the entry's key
+ * @param value the entry's value
+ * @return the builder for chaining.
+ */
+ public ConfigurationDataBuilder addSectionProperty(String section, String key, String value) {
+ Map<String, String> map = getSections().get(section);
+ if (map == null) {
+ map = new HashMap<>();
+ getSections().put(section, map);
+ }
+ map.put(key, value);
+ return this;
+ }
+
+ /**
+ * Adds a single entry to the <i>default</i> section.
+ * @param key the entry's key
+ * @param value the entry's value
+ * @return the builder for chaining.
+ */
+ public ConfigurationDataBuilder addProperty(String key, String value) {
+ getDefaultProperties().put(key, value);
+ return this;
+ }
+
+ /**
+ * Adds the given entries to the given section, all existing values will be overridden.
+ * @param section the target section (will be created if not existing).
+ * @param properties the entry's data
+ * @return the builder for chaining.
+ */
+ public ConfigurationDataBuilder addSectionProperties(String section, Map<String, String> properties) {
+ Map<String, String> map = getSections().get(section);
+ if (map == null) {
+ map = new HashMap<>();
+ getSections().put(section, map);
+ }
+ map.putAll(properties);
+ return this;
+ }
+
+ /**
+ * Adds the given entries to the <i>default</i> section, all existing values will be overridden.
+ * @param properties the entry's data
+ * @return the builder for chaining.
+ */
+ public ConfigurationDataBuilder addProperties(Map<String, String> properties) {
+ getDefaultProperties().putAll(properties);
+ return this;
+ }
+
+ /**
+ * Sets the given entries as the <i>combined</i> properties map, all existing properties of the
+ * combined map will be overridden.
+ *
+ * @param properties the entry's data
+ * @return the builder for chaining.
+ */
+ public ConfigurationDataBuilder setCombinedProperties(Map<String, String> properties) {
+ this.combinedProperties = new HashMap<>(properties);
+ return this;
+ }
+
+ /**
+ * Access the current default section, if not present a new instance is initialized.
+ *
+ * @return the current default section, never null.
+ */
+ public Map<String, String> getDefaultProperties() {
+ if (defaultProperties == null) {
+ defaultProperties = new HashMap<>();
+ }
+ return defaultProperties;
+ }
+
+ /**
+ * Access the current combined properties, if not present a new instance is initialized.
+ *
+ * @return the current combined properties, never null.
+ */
+ public Map<String, String> getCombinedProperties() {
+ if (combinedProperties == null) {
+ combinedProperties = new HashMap<>();
+ }
+ return combinedProperties;
+ }
+
+ /**
+ * Access the current named sections, if not present a new instance is initialized.
+ *
+ * @return the current named sections, never null.
+ */
+ public Map<String, Map<String, String>> getSections() {
+ if (namedSections == null) {
+ namedSections = new HashMap<>();
+ }
+ return namedSections;
+ }
+
+ /**
+ * Builds a new {@link org.apache.tamaya.format.ConfigurationData} instance.
+ * @return a new {@link org.apache.tamaya.format.ConfigurationData} instance, not null.
+ */
+ public ConfigurationData build(){
+ return new ConfigurationData(this);
+ }
+
+ @Override
+ public String toString() {
+ return "ConfigurationDataBuilder{" +
+ "format=" + format +
+ ", default properties=" + defaultProperties +
+ ", sections=" + namedSections +
+ ", combined properties=" + combinedProperties +
+ ", resource=" + resource +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java b/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java
new file mode 100644
index 0000000..997ef3a
--- /dev/null
+++ b/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java
@@ -0,0 +1,103 @@
+/*
+ * 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.format;
+
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * <p>Implementations current this class encapsulate the mechanism how to read a
+ * resource including interpreting the format correctly (e.g. xml vs.
+ * properties vs. ini). In most cases file only contains entries of the same priority, which would then
+ * result in only one {@link org.apache.tamaya.spi.PropertySource}. Complex file formats, however, may contain entries
+ * of different priorities. In this cases, each ordinal type found typically is returned as a separate section so the
+ * consuming {@link org.apache.tamaya.spi.PropertySourceProvider} implementation can distribute the different part to
+ * individual {@link org.apache.tamaya.spi.PropertySource}s.</p>
+ *
+ * <h3>Implementation Requirements</h3>
+ * Implementations of this type must be
+ * <ul>
+ * <li>thread-safe</li>
+ * </ul>
+ */
+public interface ConfigurationFormat {
+
+ /**
+ * Get a unique name of the format. This name can be used to access the format.
+ * @return the (unique) format's name, never null and not empty.
+ */
+ String getName();
+
+ /**
+ * Allows the format to examine the given resource, e.g. for a matching file ending. Only, if a format accepts an
+ * URL, it will be tried for reading the configuration.
+ * @param url the url to read the configuration data from (could be a file, a server location, a classpath
+ * resource or something else, not null.
+ * @return true, if this format accepts the given URL for reading.
+ */
+ boolean accepts(URL url);
+
+ /**
+ * Reads a configuration from an URL, hereby parsing the given {@link java.io.InputStream}. Dependening on
+ * the capabilities of the format the returned {@link org.apache.tamaya.format.ConfigurationData} may contain
+ * different levels of data:
+ * <ul>
+ * <li>Only a <i>default</i> section is returned, since the configuration format does not support
+ * hierarchies. This is the case for properties and xml properties.</li>
+ * <li>Hierarchical formats such as INI, XML and JSON can map each node to a section. Each section
+ * can have its own key/value pairs. This allows to map also complex formats in a generic way. A
+ * format implementation should then additionally flatten the whole data and store it in a accessible as
+ * {@link ConfigurationData#getCombinedProperties()}. This allows to use the properties as inout to a default mapping,
+ * which is always appropriate as long as no other semnatics
+ * are defined in the concrete target scenario.</li>
+ * <li>More complex custom scenarios should map their configuration data read into different
+ * sections. Typically the data will be mapped into different {@link org.apache.tamaya.spi.PropertySource}
+ * instances with different ordinal levels. As an example imagine a custom format that contains sections
+ * 'defaults', 'global-defaults', 'application', 'server-overrides'.</li>
+ * <li>Alternate formats</li>
+ * </ul>
+ *
+ * Summarizing implementations common formats should always provide
+ * <ul>
+ * <li>the data organized in sections as useful for the given format. If data is organized in one section, it
+ * should be mapped into the DEFAULT section.</li>
+ * <li>Formats that do provide multiple sections, should always provide a FLATTENED section as well, where
+ * all the data is organized as a flattened key/value pairs, enabling a generic mapping to a
+ * {@link org.apache.tamaya.spi.PropertySource}.</li>
+ * </ul>
+ *
+ * If the configuration format only contains entries of one ordinal type, normally only one single
+ * instance of PropertySource is returned (the corresponding key/values should end up in the DEFAULT section).
+ * Nevertheless custom formats may contain different sections or parts,
+ * where each part maps to a different target ordinal (eg defaults, domain config and app config). In the
+ * ladder case multiple PropertySources can be returned, each one with its own ordinal and the corresponding
+ * entries.
+ * @see org.apache.tamaya.spi.PropertySource
+ * @param resource a descriptive name for the resource, since an InputStream does not have any)
+ * @param inputStream the inputStream to read the configuration data from (could be a file, a server location, a classpath
+ * resource or something else.
+ * @return the corresponding {@link ConfigurationData} containing sections/properties read, never {@code null}.
+ * @throws org.apache.tamaya.ConfigException if parsing of the input fails.
+ */
+ ConfigurationData readConfiguration(String resource, InputStream inputStream);
+
+ //X TODO Add support to access a default format to see a correct formatting
+ //X String getFormatExample();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationFormats.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationFormats.java b/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationFormats.java
new file mode 100644
index 0000000..bc8aabd
--- /dev/null
+++ b/modules/formats/common/src/main/java/org/apache/tamaya/format/ConfigurationFormats.java
@@ -0,0 +1,187 @@
+/*
+ * 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.format;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tamaya.spi.ServiceContextManager;
+
+/**
+ * Small accessor and management class dealing with {@link org.apache.tamaya.format.ConfigurationFormat}
+ * instances.
+ */
+public final class ConfigurationFormats {
+ /**
+ * The logger used.
+ */
+ private static final Logger LOG = Logger.getLogger(ConfigurationFormats.class.getName());
+
+ /**
+ * Singleton constructor.
+ */
+ private ConfigurationFormats() {
+ }
+
+ /**
+ * Get all currently available formats, ordered by priority.
+ *
+ * @return the currently available formats, never null.
+ */
+ public static List<ConfigurationFormat> getFormats() {
+ return ServiceContextManager.getServiceContext().getServices(ConfigurationFormat.class);
+ }
+
+ /**
+ * Get all currently available formats, ordered by priority.
+ *
+ * @param formatNames available formats to be ordered.
+ * @return the currently available formats, never null.
+ */
+ public static List<ConfigurationFormat> getFormats(String... formatNames) {
+ final List<ConfigurationFormat> result = new ArrayList<>();
+ final Set<String> names = new HashSet<>(Arrays.asList(formatNames));
+ for (final ConfigurationFormat f : getFormats()) {
+ if (names.contains(f.getName())) {
+ result.add(f);
+ }
+ }
+ return result;
+ }
+
+ // Activate for JDK 8...
+// /**
+// * Get all currently available formats, ordered by priority.
+// *
+// * @return the currently available formats, never null.
+// */
+// public static List<ConfigurationFormat> getFormats(Predicate<String> namePredicate) {
+// List<ConfigurationFormat> result = new ArrayList<>();
+// for(ConfigurationFormat f:getFormats()){
+// if(namePredicate.test(f.getName()){
+// result.add(f);
+// }
+// }
+// return result;
+// }
+
+ /**
+ * Get all currently available formats, ordered by priority.
+ *
+ * @param url source to read configuration from.
+ * @return the currently available formats, never null.
+ */
+ public static List<ConfigurationFormat> getFormats(final URL url) {
+ final List<ConfigurationFormat> formats = getFormats();
+ final List<ConfigurationFormat> result = new ArrayList<>();
+ for (final ConfigurationFormat f : formats) {
+ if (f.accepts(url)) {
+ result.add(f);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Tries to read configuration data from a given URL, hereby traversing all known formats in order of precedence.
+ * Hereby the formats are first filtered to check if the URL is acceptable, before the input is being parsed.
+ *
+ * @param url the url from where to read, not null.
+ * @return the ConfigurationData read, or null.
+ * @throws IOException if the resource cannot be read.
+ */
+ public static ConfigurationData readConfigurationData(final URL url) throws IOException {
+ final List<ConfigurationFormat> formats = getFormats(url);
+ return readConfigurationData(url, formats.toArray(new ConfigurationFormat[formats.size()]));
+ }
+
+ /**
+ * Tries to read configuration data from a given URL, hereby explicitly trying all given formats in order.
+ *
+ * @param url the url from where to read, not null.
+ * @param formats the formats to try.
+ * @return the ConfigurationData read, or null.
+ * @throws IOException if the resource cannot be read.
+ */
+ public static ConfigurationData readConfigurationData(URL url, ConfigurationFormat... formats) throws IOException {
+ return readConfigurationData(url.toString(), url.openStream(), formats);
+ }
+
+ /**
+ * @param urls the urls from where to read, not null.
+ * @param formats the formats to try.
+ * @return the {@link org.apache.tamaya.format.ConfigurationData} of the files successfully decoded by the
+ * given formats.
+ */
+ public static Collection<ConfigurationData> getPropertySources(Collection<URL> urls, ConfigurationFormat... formats) {
+ final List<ConfigurationData> dataRead = new ArrayList<>();
+ for (final URL url : urls) {
+ try {
+ final ConfigurationData data = readConfigurationData(url, formats);
+ if (data != null) {
+ dataRead.add(data);
+ }
+ } catch (final Exception e) {
+ LOG.log(Level.SEVERE, "Error reading file: " + url.toExternalForm(), e);
+ }
+ }
+ return dataRead;
+ }
+
+ /**
+ * Tries to read configuration data from a given URL, hereby explicitly trying all given formats in order.
+ *
+ * @param resource a descriptive name for the resource, since an InputStream does not have any
+ * @param inputStream the inputStream from where to read, not null.
+ * @param formats the formats to try.
+ * @return the ConfigurationData read, or null.
+ * @throws IOException if the resource cannot be read.
+ */
+ public static ConfigurationData readConfigurationData(String resource, InputStream inputStream,
+ ConfigurationFormat... formats) throws IOException {
+ Objects.requireNonNull(inputStream);
+ Objects.requireNonNull(resource);
+ try(InputStreamFactory isFactory = new InputStreamFactory(inputStream)) {
+ for (final ConfigurationFormat format : formats) {
+ try (InputStream is = isFactory.createInputStream()) {
+ final ConfigurationData data = format.readConfiguration(resource, is);
+ if (data != null) {
+ return data;
+ }
+ } catch (final Exception e) {
+ LOG.log(Level.INFO,
+ "Format " + format.getClass().getName() + " failed to read resource " + resource, e);
+ }
+ }
+ }
+ return null;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/main/java/org/apache/tamaya/format/FlattenedDefaultPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/main/java/org/apache/tamaya/format/FlattenedDefaultPropertySource.java b/modules/formats/common/src/main/java/org/apache/tamaya/format/FlattenedDefaultPropertySource.java
new file mode 100644
index 0000000..9d2097f
--- /dev/null
+++ b/modules/formats/common/src/main/java/org/apache/tamaya/format/FlattenedDefaultPropertySource.java
@@ -0,0 +1,118 @@
+/*
+ * 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.format;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Flattened default PropertySource that uses the flattened config data read from an URL by a
+ * ${@link org.apache.tamaya.format.ConfigurationFormat}.
+ */
+public class FlattenedDefaultPropertySource implements PropertySource {
+ private static final Logger LOG = Logger.getLogger(FlattenedDefaultPropertySource.class.getName());
+ private final Map<String, String> properties;
+ private final ConfigurationData data;
+ private int defaultOrdinal = 0;
+
+
+ /*
+ * Constructor, uses hereby the flattened config data read from an URL by a
+ * ${@link org.apache.tamaya.format.ConfigurationFormat}, and if not present falls back to the default section.
+ */
+ public FlattenedDefaultPropertySource(ConfigurationData data) {
+ this.properties = populateData(data);
+ this.data = data;
+ }
+
+ /*
+ * Constructor, uses hereby the flattened config data read from an URL by a
+ * ${@link org.apache.tamaya.format.ConfigurationFormat}, and if not present falls back to the default section.
+ */
+ public FlattenedDefaultPropertySource(int defaultOrdinal, ConfigurationData data) {
+ this.properties = populateData(data);
+ this.data = data;
+ this.defaultOrdinal = defaultOrdinal;
+ }
+
+ protected Map<String, String> populateData(ConfigurationData data) {
+ Map<String, String> result = data.getCombinedProperties();
+ if (result.isEmpty()) {
+ result = data.getDefaultProperties();
+ }
+ if (result.isEmpty()) {
+ result = new HashMap<>();
+ }
+ if(result.isEmpty()){
+ for (String section : data.getSectionNames()) {
+ Map<String,String> sectionMap = data.getSection(section);
+ for(Map.Entry<String,String> en: sectionMap.entrySet()){
+ result.put(section + '.' + en.getKey(), en.getValue());
+ }
+ }
+ }
+ return Collections.unmodifiableMap(result);
+ }
+
+ @Override
+ public String getName() {
+ String name = this.properties.get("[meta].name");
+ if (name == null) {
+ name = this.data.getResource();
+ }
+ if (name == null) {
+ name = getClass().getSimpleName();
+ }
+ return name;
+ }
+
+ @Override
+ public int getOrdinal() {
+ String ordinalValue = this.properties.get(PropertySource.TAMAYA_ORDINAL);
+ if (ordinalValue != null) {
+ try {
+ return Integer.parseInt(ordinalValue.trim());
+ } catch (Exception e) {
+ LOG.log(Level.WARNING, "Failed to parse Tamaya ordinal from " + data.getResource(), e);
+ }
+ }
+ return defaultOrdinal;
+ }
+
+ @Override
+ public PropertyValue get(String key) {
+ return PropertyValue.of(key, properties.get(key), getName());
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ @Override
+ public boolean isScannable() {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/main/java/org/apache/tamaya/format/InputStreamFactory.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/main/java/org/apache/tamaya/format/InputStreamFactory.java b/modules/formats/common/src/main/java/org/apache/tamaya/format/InputStreamFactory.java
new file mode 100644
index 0000000..912dd08
--- /dev/null
+++ b/modules/formats/common/src/main/java/org/apache/tamaya/format/InputStreamFactory.java
@@ -0,0 +1,89 @@
+/*
+ * 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.format;
+
+import java.io.*;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Wrapper for a given {@link InputStream} to be able to close
+ * it via the try-with-resources construct of Java 7.
+ *
+ * <h1>Usage example</h1>
+ *
+ * <pre>
+ * public void readIt(InputStream inputStream) {
+ * try (InputStream is = new ParallelInputStream(inputStream) {
+ * // Consume the stream
+ * }
+ * }
+ * </pre>
+ */
+public class InputStreamFactory implements Closeable {
+ private static final Logger LOG = Logger.getLogger(InputStreamFactory.class.getName());
+
+ private byte[] data;
+
+ /**
+ * Creates a new InputStreamFactory.
+ *
+ * @param original the InputStream to be read for extract its data into memory.
+ * @throws IOException if thrown by the original during read.
+ */
+ public InputStreamFactory(InputStream original) throws IOException {
+ Objects.requireNonNull(original);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] bytes = new byte[256];
+ try {
+ int read = original.read(bytes);
+ while (read > 0) {
+ bos.write(bytes, 0, read);
+ read = original.read(bytes);
+ }
+ this.data = bos.toByteArray();
+ } finally {
+ try {
+ original.close();
+ } catch (IOException e) {
+ LOG.log(Level.FINEST, "Error closing stream: " + original, e);
+ }
+ }
+ }
+
+ /**
+ * Creates a new InputStream with the same data as provided by the InputStream passed on factory creation.
+ *
+ * @return a new InputStream , never null.
+ * @throws IOException if no data is available.
+ */
+ public InputStream createInputStream() throws IOException {
+ byte[] bytes = this.data;
+ if (bytes == null) {
+ throw new IOException("InputStreamFactory is closed.");
+ }
+ return new ByteArrayInputStream(bytes);
+ }
+
+ @Override
+ public void close() throws IOException {
+ this.data = null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/IniConfigurationFormat.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/IniConfigurationFormat.java b/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/IniConfigurationFormat.java
new file mode 100644
index 0000000..fe27ba7
--- /dev/null
+++ b/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/IniConfigurationFormat.java
@@ -0,0 +1,95 @@
+/*
+ * 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.format.formats;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.format.ConfigurationData;
+import org.apache.tamaya.format.ConfigurationDataBuilder;
+import org.apache.tamaya.format.ConfigurationFormat;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implements a ini file format.
+ */
+public class IniConfigurationFormat implements ConfigurationFormat {
+
+ /**
+ * The logger.
+ */
+ private final static Logger LOG = Logger.getLogger(IniConfigurationFormat.class.getName());
+
+ @Override
+ public String getName() {
+ return "ini";
+ }
+
+ @Override
+ public boolean accepts(URL url) {
+ String fileName = url.getFile();
+ return fileName.endsWith(".ini") || fileName.endsWith(".INI");
+ }
+
+ @Override
+ public ConfigurationData readConfiguration(String resource, InputStream inputStream) {
+ ConfigurationDataBuilder builder = ConfigurationDataBuilder.of(resource, this);
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"))) {
+ String line = reader.readLine();
+ int lineNum = 0;
+ String section = null;
+ while (line != null) {
+ lineNum++;
+ line = line.trim();
+ if (line.isEmpty()) {
+ line = reader.readLine();
+ continue;
+ }
+ if (line.startsWith("[")) {
+ int end = line.indexOf(']');
+ if (end < 0) {
+ throw new ConfigException(
+ "Invalid INI-Format, ']' expected, at " + lineNum + " in " + resource);
+ }
+ section = line.substring(1, end);
+ } else if (line.trim().startsWith("#")) {
+ // comment
+ } else {
+ int sep = line.indexOf('=');
+ String key = line.substring(0, sep);
+ String value = line.substring(sep + 1);
+ if (section != null) {
+ builder.addSectionProperty(section, key, value);
+ } else {
+ builder.addProperty(key, value);
+ }
+ }
+ line = reader.readLine();
+ }
+ return builder.build();
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE, "Could not read configuration: " + resource, e);
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/PropertiesFormat.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/PropertiesFormat.java b/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/PropertiesFormat.java
new file mode 100644
index 0000000..35cef77
--- /dev/null
+++ b/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/PropertiesFormat.java
@@ -0,0 +1,71 @@
+/*
+ * 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.format.formats;
+
+import org.apache.tamaya.format.ConfigurationData;
+import org.apache.tamaya.format.ConfigurationDataBuilder;
+import org.apache.tamaya.format.ConfigurationFormat;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of a {@link org.apache.tamaya.format.ConfigurationFormat} for -properties files.
+ *
+ * @see java.util.Properties#load(java.io.InputStream)
+ */
+public class PropertiesFormat implements ConfigurationFormat {
+ /**
+ * The logger.
+ */
+ private final static Logger LOG = Logger.getLogger(PropertiesFormat.class.getName());
+
+
+ @Override
+ public String getName() {
+ return "properties";
+ }
+
+ @Override
+ public boolean accepts(URL url) {
+ String fileName = url.getFile();
+ return fileName.endsWith(".properties") || fileName.endsWith(".PROPERTIES") ||
+ fileName.endsWith(".conf") || fileName.endsWith(".CONF");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public ConfigurationData readConfiguration(String resource, InputStream inputStream) {
+ Objects.requireNonNull(inputStream);
+ Objects.requireNonNull(resource);
+ try {
+ final Properties p = new Properties();
+ p.load(inputStream);
+ return ConfigurationDataBuilder.of(resource, this).addProperties(Map.class.cast(p)).build();
+ } catch (Exception e) {
+ LOG.log(Level.FINEST, "Failed to read config from resource: " + resource, e);
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/PropertiesXmlFormat.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/PropertiesXmlFormat.java b/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/PropertiesXmlFormat.java
new file mode 100644
index 0000000..c47b6f6
--- /dev/null
+++ b/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/PropertiesXmlFormat.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.format.formats;
+
+import org.apache.tamaya.format.ConfigurationData;
+import org.apache.tamaya.format.ConfigurationDataBuilder;
+import org.apache.tamaya.format.ConfigurationFormat;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of a {@link org.apache.tamaya.format.ConfigurationFormat} for xml property
+ * files.
+ *
+ * @see java.util.Properties#loadFromXML(java.io.InputStream)
+ */
+public class PropertiesXmlFormat implements ConfigurationFormat {
+ /**
+ * The logger.
+ */
+ private final static Logger LOG = Logger.getLogger(PropertiesXmlFormat.class.getName());
+
+ @Override
+ public String getName() {
+ return "xml-properties";
+ }
+
+ @Override
+ public boolean accepts(URL url) {
+ String fileName = url.getFile();
+ return fileName.endsWith(".xml") || fileName.endsWith(".XML");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public ConfigurationData readConfiguration(String resource, InputStream inputStream) {
+ Objects.requireNonNull(inputStream);
+ Objects.requireNonNull(resource);
+
+ try {
+ final Properties p = new Properties();
+ p.loadFromXML(inputStream);
+ return ConfigurationDataBuilder.of(resource, this).addProperties(Map.class.cast(p)).build();
+ } catch (Exception e) {
+ LOG.log(Level.FINEST, "Failed to read config from resource: " + resource, e);
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/package-info.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/package-info.java b/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/package-info.java
new file mode 100644
index 0000000..db8987d
--- /dev/null
+++ b/modules/formats/common/src/main/java/org/apache/tamaya/format/formats/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+/**
+ * This package provides implementtion of {@link org.apache.tamaya.format.ConfigurationFormat}
+ * for properties, xml-properties and ini files.
+ */
+package org.apache.tamaya.format.formats;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/main/java/org/apache/tamaya/format/package-info.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/main/java/org/apache/tamaya/format/package-info.java b/modules/formats/common/src/main/java/org/apache/tamaya/format/package-info.java
new file mode 100644
index 0000000..39b5f0b
--- /dev/null
+++ b/modules/formats/common/src/main/java/org/apache/tamaya/format/package-info.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+/**
+ * This package provides an abstraction for parsing a configuration
+ * from an input strem, called {@link org.apache.tamaya.format.ConfigurationFormat}
+ * and corresponding helper artifacts.
+ *
+ * @see org.apache.tamaya.format.ConfigurationFormat
+ * @see org.apache.tamaya.format.ConfigurationData
+ * @see org.apache.tamaya.format.ConfigurationFormats
+ */
+package org.apache.tamaya.format;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat b/modules/formats/common/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
new file mode 100644
index 0000000..96e898f
--- /dev/null
+++ b/modules/formats/common/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
@@ -0,0 +1,21 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.format.formats.IniConfigurationFormat
+org.apache.tamaya.format.formats.PropertiesFormat
+org.apache.tamaya.format.formats.PropertiesXmlFormat
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/test/java/org/apache/tamaya/format/ConfigurationFormatsTest.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/test/java/org/apache/tamaya/format/ConfigurationFormatsTest.java b/modules/formats/common/src/test/java/org/apache/tamaya/format/ConfigurationFormatsTest.java
new file mode 100644
index 0000000..0839714
--- /dev/null
+++ b/modules/formats/common/src/test/java/org/apache/tamaya/format/ConfigurationFormatsTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.format;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Tests for {@link org.apache.tamaya.format.ConfigurationFormats}.
+ */
+public class ConfigurationFormatsTest {
+
+ @org.junit.Test
+ public void testGetFormats() throws Exception {
+ List<ConfigurationFormat> formats = ConfigurationFormats.getFormats();
+ assertNotNull(formats);
+ assertEquals(formats.size(), 3);
+ }
+
+ @org.junit.Test
+ public void testReadConfigurationData() throws Exception {
+ List<ConfigurationFormat> formats = ConfigurationFormats.getFormats(getClass().getResource("/Test.ini"));
+ assertNotNull(formats);
+ assertEquals(formats.size(), 1);
+ formats = ConfigurationFormats.getFormats(getClass().getResource("/Test.properties"));
+ assertNotNull(formats);
+ assertEquals(formats.size(), 1);
+// formats = ConfigurationFormats.getFormats(getClass().getResource("/Test.xml"));
+// assertNotNull(formats);
+// assertEquals(formats.size(), 1);
+
+ }
+
+ @org.junit.Test
+ public void testReadConfigurationData_URL() throws Exception {
+ ConfigurationData data = ConfigurationFormats.readConfigurationData(getClass().getResource("/Test.ini"));
+ assertNotNull(data);
+ data = ConfigurationFormats.readConfigurationData(getClass().getResource("/Test.properties"));
+ assertNotNull(data);
+ }
+
+ @org.junit.Test
+ public void testReadConfigurationData2() throws Exception {
+ List<ConfigurationFormat> formats = ConfigurationFormats.getFormats();
+ ConfigurationData data = ConfigurationFormats.readConfigurationData(getClass().getResource("/Test.ini"),
+ formats.toArray(new ConfigurationFormat[formats.size()]));
+ assertNotNull(data);
+ System.out.println(data);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/test/java/org/apache/tamaya/format/FlattenedDefaultPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/test/java/org/apache/tamaya/format/FlattenedDefaultPropertySourceTest.java b/modules/formats/common/src/test/java/org/apache/tamaya/format/FlattenedDefaultPropertySourceTest.java
new file mode 100644
index 0000000..adc94f6
--- /dev/null
+++ b/modules/formats/common/src/test/java/org/apache/tamaya/format/FlattenedDefaultPropertySourceTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.format;
+
+import org.apache.tamaya.format.formats.PropertiesFormat;
+import org.apache.tamaya.spi.PropertySource;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Tests for {@link org.apache.tamaya.format.FlattenedDefaultPropertySource}.
+ */
+public class FlattenedDefaultPropertySourceTest {
+
+ @Test
+ public void testGetName() throws Exception {
+ FlattenedDefaultPropertySource ps = new FlattenedDefaultPropertySource(createConfigurationData("test1"));
+ assertEquals("test1", ps.getName());
+ }
+
+ private ConfigurationData createConfigurationData(String sourceName) {
+ return ConfigurationDataBuilder.of(sourceName, new PropertiesFormat())
+ .addProperty("a", "aValue").addSectionProperty("section1", "sectionKey1", "sectionValue11")
+ .addSections("section1", "section12")
+ .addSectionProperty("section2", "sectionKey1", "sectionValue21").build();
+ }
+
+ private ConfigurationData createConfigurationData(String sourceName, int ordinal) {
+ return ConfigurationDataBuilder.of(sourceName, new PropertiesFormat())
+ .addProperty("a", "aValue").addSectionProperty("section1", "sectionKey1", "sectionValue11")
+ .addSections("section1", "section12").addProperty(PropertySource.TAMAYA_ORDINAL, String.valueOf(ordinal))
+ .addSectionProperty("section2", "sectionKey1", "sectionValue21").build();
+ }
+
+ private ConfigurationData createConfigurationDataNoDefault(String sourceName) {
+ return ConfigurationDataBuilder.of(sourceName, new PropertiesFormat())
+ .addSectionProperty("section1", "sectionKey1", "sectionValue11")
+ .addSections("section1", "section12")
+ .addSectionProperty("section2", "sectionKey1", "sectionValue21").build();
+ }
+
+ @Test
+ public void testGetOrdinal() throws Exception {
+ FlattenedDefaultPropertySource ps = new FlattenedDefaultPropertySource(createConfigurationData("test1", 11));
+ assertEquals(11, ps.getOrdinal());
+ }
+
+ @Test
+ public void testGet() throws Exception {
+ FlattenedDefaultPropertySource ps = new FlattenedDefaultPropertySource(createConfigurationData("test2"));
+ assertEquals("aValue", ps.get("a").get("a"));
+ assertNotNull(ps.get("section1.sectionKey1").get("section1.sectionKey1"));
+ assertNotNull(ps.get("section2.sectionKey1").get("section2.sectionKey1"));
+ assertNull(ps.get("sectionKey1"));
+ ps = new FlattenedDefaultPropertySource(createConfigurationDataNoDefault("test2"));
+ assertEquals("sectionValue11", ps.get("section1.sectionKey1").get("section1.sectionKey1"));
+ assertEquals("sectionValue21", ps.get("section2.sectionKey1").get("section2.sectionKey1"));
+ assertNull(ps.get("a"));
+ assertNull(ps.get("section1"));
+ }
+
+ @Test
+ public void testGetProperties() throws Exception {
+ FlattenedDefaultPropertySource ps = new FlattenedDefaultPropertySource(createConfigurationData("test3"));
+ assertNotNull(ps.getProperties());
+ assertEquals("aValue", ps.getProperties().get("a"));
+ assertNotNull(ps.getProperties().get("section1.sectionKey1"));
+ assertNotNull(ps.getProperties().get("section2.sectionKey1"));
+ assertNull(ps.getProperties().get("section1.sectionKey2"));
+ assertNull(ps.getProperties().get("section2.sectionKey2"));
+ assertNull(ps.getProperties().get("sectionKey1"));
+ assertNull(ps.getProperties().get("sectionKey2"));
+ ps = new FlattenedDefaultPropertySource(createConfigurationDataNoDefault("test3"));
+ assertNotNull(ps.getProperties());
+ assertEquals("sectionValue11", ps.getProperties().get("section1.sectionKey1"));
+ assertEquals("sectionValue21", ps.getProperties().get("section2.sectionKey1"));
+ assertNull(ps.get("section1"));
+ }
+}
\ No newline at end of file
[08/15] incubator-tamaya-extensions git commit: TAMAYA-189: Moved
format and injection modules into separate subtrees.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationExtension.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationExtension.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationExtension.java
new file mode 100644
index 0000000..4524461
--- /dev/null
+++ b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationExtension.java
@@ -0,0 +1,290 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.ConfigOperator;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.inject.api.Config;
+import org.apache.tamaya.inject.api.ConfigDefaultSections;
+import org.apache.tamaya.inject.api.WithConfigOperator;
+import org.apache.tamaya.inject.api.WithPropertyConverter;
+import org.apache.tamaya.spi.PropertyConverter;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.ProcessBean;
+import javax.enterprise.inject.spi.ProcessProducerMethod;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+
+/**
+ * CDI Extension module that adds injection mechanism for configuration.
+ *
+ * @see org.apache.tamaya.inject.api.Config
+ * @see org.apache.tamaya.inject.api.ConfigDefaultSections
+ * @see ConfigException
+ */
+public class ConfigurationExtension implements Extension {
+
+ private static final Logger LOG = Logger.getLogger(ConfigurationExtension.class.getName());
+
+ static final Map<Class, ConfigOperator> CUSTOM_OPERATORS = new ConcurrentHashMap<>();
+ static final Map<Class, PropertyConverter> CUSTOM_CONVERTERS = new ConcurrentHashMap<>();
+
+ private final Set<Type> types = new HashSet<>();
+ private Bean<?> convBean;
+
+ /**
+ * Constructor for loading logging its load.
+ */
+ public ConfigurationExtension(){
+ LOG.finest("Loading Tamaya CDI Support...");
+ }
+
+ /**
+ * Method that checks the configuration injection points during deployment for available configuration.
+ * @param pb the bean to process.
+ * @param beanManager the bean manager to notify about new injections.
+ */
+ public void retrieveTypes(@Observes final ProcessBean<?> pb, BeanManager beanManager) {
+
+ final Set<InjectionPoint> ips = pb.getBean().getInjectionPoints();
+ CDIConfiguredType configuredType = new CDIConfiguredType(pb.getBean().getBeanClass());
+
+ boolean configured = false;
+ boolean logged = false;
+ for (InjectionPoint injectionPoint : ips) {
+ if (injectionPoint.getAnnotated().isAnnotationPresent(Config.class)) {
+ final Config annotation = injectionPoint.getAnnotated().getAnnotation(Config.class);
+ final ConfigDefaultSections typeAnnot = injectionPoint.getAnnotated().getAnnotation(ConfigDefaultSections.class);
+ final List<String> keys = evaluateKeys(injectionPoint.getMember().getName(),
+ annotation!=null?annotation.value():null,
+ typeAnnot!=null?typeAnnot.value():null);
+
+ final WithConfigOperator withOperatorAnnot = injectionPoint.getAnnotated().getAnnotation(WithConfigOperator.class);
+ if(withOperatorAnnot!=null){
+ tryLoadOpererator(withOperatorAnnot.value());
+ }
+ final WithPropertyConverter withConverterAnnot = injectionPoint.getAnnotated().getAnnotation(WithPropertyConverter.class);
+ if(withConverterAnnot!=null){
+ tryLoadConverter(withConverterAnnot.value());
+ }
+
+ // We don't want to wait until the injection really fails at runtime.
+ // If there is a non resolvable configuration, we want to know at startup.
+ Configuration config = ConfigurationProvider.getConfiguration();
+ String value = null;
+ for(String key:keys) {
+ value = config.get(key);
+ if(value!=null){
+ break;
+ }
+ }
+ if(value==null && !annotation.defaultValue().isEmpty()){
+ value = annotation.defaultValue();
+ }
+ if(value==null){
+ throw new ConfigException(String.format(
+ "Cannot resolve any of the possible configuration keys: %s. Please provide one of the given keys " +
+ "with a value in your configuration sources.",
+ keys.toString()));
+ }
+ types.add(injectionPoint.getType());
+ if(annotation!=null){
+ configured = true;
+ if(!logged) {
+ LOG.finest("Enabling Tamaya CDI Configuration on bean: " + configuredType.getName());
+ }
+ configuredType.addConfiguredMember(injectionPoint, keys);
+ }
+ }
+ }
+ if(configured) {
+ beanManager.fireEvent(configuredType);
+ }
+ }
+
+
+ public void captureConvertBean(@Observes final ProcessProducerMethod<?, ?> ppm) {
+ if (ppm.getAnnotated().isAnnotationPresent(Config.class)) {
+ convBean = ppm.getBean();
+ }
+
+ }
+
+ public void addConverter(@Observes final AfterBeanDiscovery abd, final BeanManager bm) {
+ if(!types.isEmpty()) {
+ abd.addBean(new ConverterBean(convBean, types));
+ }
+ }
+
+ private void tryLoadOpererator(Class<? extends ConfigOperator> operatorClass) {
+ Objects.requireNonNull(operatorClass);
+ if(ConfigOperator.class == operatorClass){
+ return;
+ }
+ try{
+ if(!CUSTOM_OPERATORS.containsKey(operatorClass)) {
+ CUSTOM_OPERATORS.put(operatorClass, operatorClass.newInstance());
+ }
+ } catch(Exception e){
+ throw new ConfigException("Custom ConfigOperator could not be loaded: " + operatorClass.getName(), e);
+ }
+ }
+
+ private void tryLoadConverter(Class<? extends PropertyConverter> converterClass) {
+ Objects.requireNonNull(converterClass);
+ if(PropertyConverter.class == converterClass){
+ return;
+ }
+ try{
+ if(!CUSTOM_CONVERTERS.containsKey(converterClass)) {
+ CUSTOM_CONVERTERS.put(converterClass, converterClass.newInstance());
+ }
+ } catch(Exception e){
+ throw new ConfigException("Custom PropertyConverter could not be loaded: " + converterClass.getName(), e);
+ }
+ }
+
+ /**
+ * Evaluates the effective keys to be used. if no {@code keys} are defined, {@code memberName} is used.
+ * The effective keys are then combined with the sections given (if any) and only, if the given keys are not
+ * absolute keys (surrounded by brackets).
+ * @param memberName the default member name, not null.
+ * @param keys the keys, may be empty, or null.
+ * @param sections the default sections, may be empty. May also be null.
+ * @return the list of keys to be finally used for configuration resolution in order of
+ * precedence. The first keys in the list that could be successfully resolved define the final
+ * configuration value.
+ */
+ public static List<String> evaluateKeys(String memberName, String[] keys, String[] sections) {
+ List<String> effKeys = new ArrayList<>();
+ if(keys!=null){
+ effKeys.addAll(Arrays.asList(keys));
+ }
+ if (effKeys.isEmpty()) {
+ effKeys.add(memberName);
+ }
+ ListIterator<String> iterator = effKeys.listIterator();
+ while (iterator.hasNext()) {
+ String next = iterator.next();
+ if (next.startsWith("[") && next.endsWith("]")) {
+ // absolute key, strip away brackets, take key as is
+ iterator.set(next.substring(1, next.length() - 1));
+ } else {
+ if (sections != null && sections.length>0) {
+ // Remove original entry, since it will be replaced with prefixed entries
+ iterator.remove();
+ // Add prefixed entries, including absolute (root) entry for "" area keys.
+ for (String area : sections) {
+ iterator.add(area.isEmpty() ? next : area + '.' + next);
+ }
+ }
+ }
+ }
+ return effKeys;
+ }
+
+
+ /**
+ * Internally used conversion bean.
+ */
+ private static class ConverterBean implements Bean<Object> {
+
+ private final Bean<Object> delegate;
+ private final Set<Type> types;
+
+ public ConverterBean(final Bean convBean, final Set<Type> types) {
+ this.types = types;
+ this.delegate = convBean;
+ }
+
+ @Override
+ public Set<Type> getTypes() {
+ return types;
+ }
+
+ @Override
+ public Class<?> getBeanClass() {
+ return delegate.getBeanClass();
+ }
+
+ @Override
+ public Set<InjectionPoint> getInjectionPoints() {
+ return delegate.getInjectionPoints();
+ }
+
+ @Override
+ public String getName() {
+ return delegate.getName();
+ }
+
+ @Override
+ public Set<Annotation> getQualifiers() {
+ return delegate.getQualifiers();
+ }
+
+ @Override
+ public Class<? extends Annotation> getScope() {
+ return delegate.getScope();
+ }
+
+ @Override
+ public Set<Class<? extends Annotation>> getStereotypes() {
+ return delegate.getStereotypes();
+ }
+
+ @Override
+ public boolean isAlternative() {
+ return delegate.isAlternative();
+ }
+
+ @Override
+ public boolean isNullable() {
+ return delegate.isNullable();
+ }
+
+ @Override
+ public Object create(CreationalContext<Object> creationalContext) {
+ return delegate.create(creationalContext);
+ }
+
+ @Override
+ public void destroy(Object instance, CreationalContext<Object> creationalContext) {
+ delegate.destroy(instance, creationalContext);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationProducer.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationProducer.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationProducer.java
new file mode 100644
index 0000000..bfbb51a
--- /dev/null
+++ b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationProducer.java
@@ -0,0 +1,147 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.ConfigOperator;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.inject.api.Config;
+import org.apache.tamaya.inject.api.ConfigDefaultSections;
+import org.apache.tamaya.inject.api.DynamicValue;
+import org.apache.tamaya.inject.api.WithConfigOperator;
+import org.apache.tamaya.inject.api.WithPropertyConverter;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Producer bean for configuration properties.
+ */
+@ApplicationScoped
+public class ConfigurationProducer {
+
+ private static final Logger LOGGER = Logger.getLogger(ConfigurationProducer.class.getName());
+
+ private DynamicValue createynamicValue(final InjectionPoint injectionPoint) {
+ Member member = injectionPoint.getMember();
+ if (member instanceof Field) {
+ return DefaultDynamicValue.of((Field) member, ConfigurationProvider.getConfiguration());
+ } else if (member instanceof Method) {
+ return DefaultDynamicValue.of((Method) member, ConfigurationProvider.getConfiguration());
+ }
+ return null;
+ }
+
+ @Produces
+ @Config
+ public Object resolveAndConvert(final InjectionPoint injectionPoint) {
+ if (DynamicValue.class.equals(injectionPoint.getAnnotated().getBaseType())) {
+ return createynamicValue(injectionPoint);
+ }
+ final Config annotation = injectionPoint.getAnnotated().getAnnotation(Config.class);
+ final ConfigDefaultSections typeAnnot = injectionPoint.getAnnotated().getAnnotation(ConfigDefaultSections.class);
+ final List<String> keys = ConfigurationExtension.evaluateKeys(injectionPoint.getMember().getName(),
+ annotation != null ? annotation.value() : null,
+ typeAnnot != null ? typeAnnot.value() : null);
+
+ final WithConfigOperator withOperatorAnnot = injectionPoint.getAnnotated().getAnnotation(WithConfigOperator.class);
+ ConfigOperator operator = null;
+ if (withOperatorAnnot != null) {
+ operator = ConfigurationExtension.CUSTOM_OPERATORS.get(withOperatorAnnot.value());
+ }
+ PropertyConverter customConverter = null;
+ final WithPropertyConverter withConverterAnnot = injectionPoint.getAnnotated().getAnnotation(WithPropertyConverter.class);
+ if (withConverterAnnot != null) {
+ customConverter = ConfigurationExtension.CUSTOM_CONVERTERS.get(withConverterAnnot.value());
+ }
+
+ // unless the extension is not installed, this should never happen because the extension
+ // enforces the resolvability of the config
+ Configuration config = ConfigurationProvider.getConfiguration();
+ if (operator != null) {
+ config = operator.operate(config);
+ }
+ final Class<?> toType = (Class<?>) injectionPoint.getAnnotated().getBaseType();
+ String textValue = null;
+ String defaultTextValue = annotation.defaultValue().isEmpty() ? null : annotation.defaultValue();
+ String keyFound = null;
+ for (String key : keys) {
+ textValue = config.get(key);
+ if (textValue != null) {
+ keyFound = key;
+ break;
+ }
+ }
+ ConversionContext.Builder builder = new ConversionContext.Builder(config,
+ ConfigurationProvider.getConfiguration().getContext(), keyFound, TypeLiteral.of(toType));
+ if (injectionPoint.getMember() instanceof AnnotatedElement) {
+ builder.setAnnotatedElement((AnnotatedElement) injectionPoint.getMember());
+ }
+ ConversionContext conversionContext = builder.build();
+ Object value = null;
+ if (keyFound != null) {
+ if (customConverter != null) {
+ value = customConverter.convert(textValue, conversionContext);
+ }
+ if (value == null) {
+ value = config.get(keyFound, toType);
+ }
+ } else if (defaultTextValue != null) {
+ value = defaultTextValue;
+ if (customConverter != null) {
+ value = customConverter.convert((String)value, conversionContext);
+ }
+ if (value != null) {
+ List<PropertyConverter<Object>> converters = ConfigurationProvider.getConfiguration().getContext()
+ .getPropertyConverters(TypeLiteral.of(toType));
+ for (PropertyConverter<Object> converter : converters) {
+ try {
+ value = converter.convert(defaultTextValue, conversionContext);
+ if (value != null) {
+ LOGGER.log(Level.FINEST, "Parsed default value from '" + defaultTextValue + "' into " +
+ injectionPoint);
+ break;
+ }
+ } catch (Exception e) {
+ LOGGER.log(Level.FINEST, "Failed to convert default value '" + defaultTextValue + "' for " +
+ injectionPoint, e);
+ }
+ }
+ }
+ }
+ if (value == null) {
+ throw new ConfigException(String.format(
+ "Can't resolve any of the possible config keys: %s to the required target type: %s, supported formats: %s",
+ keys.toString(), toType.getName(), conversionContext.getSupportedFormats().toString()));
+ }
+ LOGGER.finest(String.format("Injecting %s for key %s in class %s", keyFound, value.toString(), injectionPoint.toString()));
+ return value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/DefaultDynamicValue.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/DefaultDynamicValue.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/DefaultDynamicValue.java
new file mode 100644
index 0000000..98ee05a
--- /dev/null
+++ b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/DefaultDynamicValue.java
@@ -0,0 +1,499 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.inject.api.BaseDynamicValue;
+import org.apache.tamaya.inject.api.DynamicValue;
+import org.apache.tamaya.inject.api.InjectionUtils;
+import org.apache.tamaya.inject.api.LoadPolicy;
+import org.apache.tamaya.inject.api.UpdatePolicy;
+import org.apache.tamaya.inject.api.WithPropertyConverter;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * A accessor for a single configured value. This can be used to support values that may change during runtime,
+ * reconfigured or final. Hereby external code (could be Tamaya configuration listners or client code), can set a
+ * new value. Depending on the {@link UpdatePolicy} the new value is immedeately active or it requires an active commit
+ * by client code. Similarly an instance also can ignore all later changes to the value.
+ * <h3>Implementation Details</h3>
+ * This class is
+ * <ul>
+ * <li>Serializable, when also the item stored is serializable</li>
+ * <li>Thread safe</li>
+ * </ul>
+ *
+ * @param <T> The type of the value.
+ */
+final class DefaultDynamicValue<T> extends BaseDynamicValue<T> {
+
+ private static final long serialVersionUID = -2071172847144537443L;
+
+ /**
+ * The property name of the entry.
+ */
+ private final String propertyName;
+ /**
+ * The keys to be resolved.
+ */
+ private final String[] keys;
+ /**
+ * Back reference to the base configuration instance. This reference is used reevalaute the given property and
+ * compare the result with the previous value after a configuration change was triggered.
+ */
+ private final Configuration configuration;
+ /**
+ * The target type of the property used to lookup a matching {@link PropertyConverter}.
+ * If null, {@code propertyConverter} is set and used instead.
+ */
+ private final TypeLiteral<T> targetType;
+ /**
+ * The property converter to be applied, may be null. In the ladder case targetType is not null.
+ */
+ private final PropertyConverter<T> propertyConverter;
+ /**
+ * Policy that defines how new values are applied, be default it is applied initially once, but never updated
+ * anymore.
+ */
+ private UpdatePolicy updatePolicy;
+ /**
+ * Load policy.
+ */
+ private final LoadPolicy loadPolicy;
+
+ /**
+ * The current value, never null.
+ */
+ private transient T value;
+ /**
+ * The new value, or null.
+ */
+ private transient Object[] newValue;
+ /**
+ * List of listeners that listen for changes.
+ */
+ private transient WeakList<PropertyChangeListener> listeners;
+
+ /**
+ * Constructor.
+ *
+ * @param propertyName the name of the fields' property/method.
+ * @param keys the keys of the property, not null.
+ * @param configuration the configuration, not null.
+ * @param targetType the target type, not null.
+ * @param propertyConverter the optional converter to be used.
+ */
+ private DefaultDynamicValue(String propertyName, Configuration configuration, TypeLiteral<T> targetType,
+ PropertyConverter<T> propertyConverter, List<String> keys, LoadPolicy loadPolicy,
+ UpdatePolicy updatePolicy) {
+ this.propertyName = Objects.requireNonNull(propertyName);
+ this.keys = keys.toArray(new String[keys.size()]);
+ this.configuration = Objects.requireNonNull(configuration);
+ this.propertyConverter = propertyConverter;
+ this.targetType = targetType;
+ this.loadPolicy = Objects.requireNonNull(loadPolicy);
+ this.updatePolicy = Objects.requireNonNull(updatePolicy);
+ if(loadPolicy == LoadPolicy.INITIAL){
+ this.value = evaluateValue();
+ }
+ }
+
+ public static DynamicValue of(Field annotatedField, Configuration configuration) {
+ return of(annotatedField, configuration, LoadPolicy.ALWAYS, UpdatePolicy.IMMEDEATE);
+ }
+
+ public static DynamicValue of(Field annotatedField, Configuration configuration, LoadPolicy loadPolicy) {
+ return of(annotatedField, configuration, loadPolicy, UpdatePolicy.IMMEDEATE);
+ }
+
+ public static DynamicValue of(Field annotatedField, Configuration configuration, UpdatePolicy updatePolicy) {
+ return of(annotatedField, configuration, LoadPolicy.ALWAYS, updatePolicy);
+ }
+
+ public static DynamicValue of(Field annotatedField, Configuration configuration, LoadPolicy loadPolicy, UpdatePolicy updatePolicy) {
+ // Check for adapter/filter
+ Type targetType = annotatedField.getGenericType();
+ if (targetType == null) {
+ throw new ConfigException("Failed to evaluate target type for " + annotatedField.getDeclaringClass().getName()
+ + '.' + annotatedField.getName());
+ }
+ if (targetType instanceof ParameterizedType) {
+ ParameterizedType pt = (ParameterizedType) targetType;
+ Type[] types = pt.getActualTypeArguments();
+ if (types.length != 1) {
+ throw new ConfigException("Failed to evaluate target type for " + annotatedField.getDeclaringClass().getName()
+ + '.' + annotatedField.getName());
+ }
+ targetType = types[0];
+ }
+ PropertyConverter<?> propertyConverter = null;
+ WithPropertyConverter annot = annotatedField.getAnnotation(WithPropertyConverter.class);
+ if (annot != null) {
+ try {
+ propertyConverter = annot.value().newInstance();
+ } catch (Exception e) {
+ throw new ConfigException("Failed to instantiate annotated PropertyConverter on " +
+ annotatedField.getDeclaringClass().getName()
+ + '.' + annotatedField.getName(), e);
+ }
+ }
+ List<String> keys = InjectionUtils.getKeys(annotatedField);
+ return new DefaultDynamicValue(annotatedField.getName(), configuration,
+ TypeLiteral.of(targetType), propertyConverter, keys, loadPolicy, updatePolicy);
+ }
+
+ public static DynamicValue of(Method method, Configuration configuration) {
+ return of(method, configuration, LoadPolicy.ALWAYS, UpdatePolicy.IMMEDEATE);
+ }
+
+ public static DynamicValue of(Method method, Configuration configuration, UpdatePolicy updatePolicy) {
+ return of(method, configuration, LoadPolicy.ALWAYS, updatePolicy);
+ }
+
+ public static DynamicValue of(Method method, Configuration configuration, LoadPolicy loadPolicy) {
+ return of(method, configuration, loadPolicy, UpdatePolicy.IMMEDEATE);
+ }
+
+ public static DynamicValue of(Method method, Configuration configuration, LoadPolicy loadPolicy, UpdatePolicy updatePolicy) {
+ // Check for adapter/filter
+ Type targetType = method.getGenericReturnType();
+ if (targetType == null) {
+ throw new ConfigException("Failed to evaluate target type for " + method.getDeclaringClass()
+ .getName() + '.' + method.getName());
+ }
+ if (targetType instanceof ParameterizedType) {
+ ParameterizedType pt = (ParameterizedType) targetType;
+ Type[] types = pt.getActualTypeArguments();
+ if (types.length != 1) {
+ throw new ConfigException("Failed to evaluate target type for " + method.getDeclaringClass()
+ .getName() + '.' + method.getName());
+ }
+ targetType = types[0];
+ }
+ PropertyConverter<Object> propertyConverter = null;
+ WithPropertyConverter annot = method.getAnnotation(WithPropertyConverter.class);
+ if (annot != null) {
+ try {
+ propertyConverter = (PropertyConverter<Object>) annot.value().newInstance();
+ } catch (Exception e) {
+ throw new ConfigException("Failed to instantiate annotated PropertyConverter on " +
+ method.getDeclaringClass().getName()
+ + '.' + method.getName(), e);
+ }
+ }
+ return new DefaultDynamicValue<>(method.getName(),
+ configuration, TypeLiteral.of(targetType), propertyConverter, InjectionUtils.getKeys(method),
+ loadPolicy, updatePolicy);
+ }
+
+
+ /**
+ * Commits a new value that has not been committed yet, make it the new value of the instance. On change any
+ * registered listeners will be triggered.
+ */
+ public void commit() {
+ T oldValue = value;
+ value = newValue==null?null:(T)newValue[0];
+ newValue = null;
+ informListeners(oldValue, value);
+ }
+
+ private void informListeners(T value, T newValue) {
+ synchronized (this) {
+ PropertyChangeEvent evt = new PropertyChangeEvent(this, propertyName, value,
+ newValue);
+ if (listeners != null) {
+ for (PropertyChangeListener consumer : listeners.get()) {
+ consumer.propertyChange(evt);
+ }
+ }
+ }
+ }
+
+ /**
+ * Discards a new value that was published. No listeners will be informed.
+ */
+ public void discard() {
+ newValue = null;
+ }
+
+
+ /**
+ * Access the {@link UpdatePolicy} used for updating this value.
+ *
+ * @return the update policy, never null.
+ */
+ public UpdatePolicy getUpdatePolicy() {
+ return updatePolicy;
+ }
+
+ /**
+ * Sets a new {@link UpdatePolicy}.
+ *
+ * @param updatePolicy the new policy, not null.
+ */
+ public void setUpdatePolicy(UpdatePolicy updatePolicy) {
+ this.updatePolicy = Objects.requireNonNull(updatePolicy);
+ }
+
+ /**
+ * Add a listener to be called as weak reference, when this value has been changed.
+ *
+ * @param l the listener, not null
+ */
+ public void addListener(PropertyChangeListener l) {
+ if (listeners == null) {
+ listeners = new WeakList<>();
+ }
+ listeners.add(l);
+ }
+
+ /**
+ * Removes a listener to be called, when this value has been changed.
+ *
+ * @param l the listner to be removed, not null
+ */
+ public void removeListener(PropertyChangeListener l) {
+ if (listeners != null) {
+ listeners.remove(l);
+ }
+ }
+
+ /**
+ * If a value is present in this {@code DynamicValue}, returns the value,
+ * otherwise throws {@code ConfigException}.
+ *
+ * @return the non-null value held by this {@code Optional}
+ * @throws ConfigException if there is no value present
+ * @see DefaultDynamicValue#isPresent()
+ */
+ public T get() {
+ T newLocalValue;
+ if(loadPolicy!=LoadPolicy.INITIAL) {
+ newLocalValue = evaluateValue();
+ if (this.value == null) {
+ this.value = newLocalValue;
+ }
+ if(!Objects.equals(this.value, newLocalValue)){
+ switch (updatePolicy){
+ case IMMEDEATE:
+ commit();
+ break;
+ case EXPLCIT:
+ this.newValue = new Object[]{newLocalValue};
+ break;
+ case LOG_ONLY:
+ informListeners(this.value, newLocalValue);
+ this.newValue = null;
+ break;
+ case NEVER:
+ this.newValue = null;
+ break;
+ default:
+ this.newValue = null;
+ break;
+ }
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Method to check for and apply a new value. Depending on the {@link UpdatePolicy}
+ * the value is immediately or deferred visible (or it may even be ignored completely).
+ *
+ * @return true, if a new value has been detected. The value may not be visible depending on the current
+ * {@link UpdatePolicy} in place.
+ */
+ public boolean updateValue() {
+ if(this.value==null && this.newValue==null){
+ this.value = evaluateValue();
+ return false;
+ }
+ T newValue = evaluateValue();
+ if (Objects.equals(newValue, this.value)) {
+ return false;
+ }
+ switch (this.updatePolicy) {
+ case LOG_ONLY:
+ Logger.getLogger(getClass().getName()).info("Discard change on " + this + ", newValue=" + newValue);
+ informListeners(value, newValue);
+ this.newValue = null;
+ break;
+ case NEVER:
+ this.newValue = null;
+ break;
+ case EXPLCIT:
+ case IMMEDEATE:
+ default:
+ this.newValue = new Object[]{newValue};
+ commit();
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * Evaluates the current value dynamically from the underlying configuration.
+ *
+ * @return the current actual value, or null.
+ */
+ public T evaluateValue() {
+ T value = null;
+
+ for (String key : keys) {
+ if (propertyConverter == null) {
+ value = configuration.get(key, targetType);
+ } else {
+ String source = configuration.get(key);
+ ConversionContext ctx = new ConversionContext.Builder(configuration,
+ configuration.getContext(), key, targetType).build();
+ value = propertyConverter.convert(source, ctx);
+ }
+
+ if (value != null) {
+ break;
+ }
+ }
+
+ return value;
+ }
+
+ /**
+ * Access a new value that has not yet been committed.
+ *
+ * @return the uncommitted new value, or null.
+ */
+ public T getNewValue() {
+ T nv = newValue==null?null:(T)newValue[0];
+ if (nv != null) {
+ return nv;
+ }
+ return null;
+ }
+
+
+ /**
+ * Serialization implementation that strips away the non serializable Optional part.
+ *
+ * @param oos the output stream
+ * @throws IOException if serialization fails.
+ */
+ private void writeObject(ObjectOutputStream oos) throws IOException {
+ oos.writeObject(getUpdatePolicy());
+ oos.writeObject(get());
+ }
+
+ /**
+ * Reads an instance from the input stream.
+ *
+ * @param ois the object input stream
+ * @throws IOException if deserialization fails.
+ * @throws ClassNotFoundException
+ */
+ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+ this.updatePolicy = (UpdatePolicy) ois.readObject();
+ if (isPresent()) {
+ this.value = (T) ois.readObject();
+ }
+ newValue = null;
+ }
+
+
+ /**
+ * Simple helper that allows keeping the listeners registered as weak references, hereby avoiding any
+ * memory leaks.
+ *
+ * @param <I> the type
+ */
+ private class WeakList<I> {
+ final List<WeakReference<I>> refs = new LinkedList<>();
+
+ /**
+ * Adds a new instance.
+ *
+ * @param t the new instance, not null.
+ */
+ void add(I t) {
+ refs.add(new WeakReference<>(t));
+ }
+
+ /**
+ * Removes a instance.
+ *
+ * @param t the instance to be removed.
+ */
+ void remove(I t) {
+ synchronized (refs) {
+ for (Iterator<WeakReference<I>> iterator = refs.iterator(); iterator.hasNext(); ) {
+ WeakReference<I> ref = iterator.next();
+ I instance = ref.get();
+ if (instance == null || instance == t) {
+ iterator.remove();
+ break;
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Access a list (copy) of the current instances that were not discarded by the GC.
+ *
+ * @return the list of accessible items.
+ */
+ public List<I> get() {
+ synchronized (refs) {
+ List<I> res = new ArrayList<>();
+ for (Iterator<WeakReference<I>> iterator = refs.iterator(); iterator.hasNext(); ) {
+ WeakReference<I> ref = iterator.next();
+ I instance = ref.get();
+ if (instance == null) {
+ iterator.remove();
+ } else {
+ res.add(instance);
+ }
+ }
+ return res;
+ }
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java
new file mode 100644
index 0000000..5171d91
--- /dev/null
+++ b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java
@@ -0,0 +1,151 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.ServiceContext;
+
+import javax.annotation.Priority;
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class implements the (default) {@link ServiceContext} interface and hereby uses the JDK
+ * {@link ServiceLoader} to load the services required.
+ */
+final class ServiceLoaderServiceContext implements ServiceContext {
+ /**
+ * List current services loaded, per class.
+ */
+ private final ConcurrentHashMap<Class<?>, List<Object>> servicesLoaded = new ConcurrentHashMap<>();
+ /**
+ * Singletons.
+ */
+ private final Map<Class<?>, Object> singletons = new ConcurrentHashMap<>();
+
+ @Override
+ public <T> T getService(Class<T> serviceType) {
+ Object cached = singletons.get(serviceType);
+ if (cached == null) {
+ Collection<T> services = getServices(serviceType);
+ if (services.isEmpty()) {
+ cached = null;
+ } else {
+ cached = getServiceWithHighestPriority(services, serviceType);
+ }
+ if(cached!=null) {
+ singletons.put(serviceType, cached);
+ }
+ }
+ return serviceType.cast(cached);
+ }
+
+ /**
+ * Loads and registers services.
+ *
+ * @param <T> the concrete type.
+ * @param serviceType The service type.
+ * @return the items found, never {@code null}.
+ */
+ @Override
+ public <T> List<T> getServices(final Class<T> serviceType) {
+ List<T> found = (List<T>) servicesLoaded.get(serviceType);
+ if (found != null) {
+ return found;
+ }
+ List<T> services = new ArrayList<>();
+ try {
+ for (T t : ServiceLoader.load(serviceType)) {
+ services.add(t);
+ }
+ services = Collections.unmodifiableList(services);
+ } catch (Exception e) {
+ Logger.getLogger(ServiceLoaderServiceContext.class.getName()).log(Level.WARNING,
+ "Error loading services current type " + serviceType, e);
+ }
+ final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>) services));
+ return previousServices != null ? previousServices : services;
+ }
+
+ /**
+ * Checks the given instance for a @Priority annotation. If present the annotation's value s evaluated. If no such
+ * annotation is present, a default priority is returned (1);
+ * @param o the instance, not null.
+ * @return a priority, by default 1.
+ */
+ public static int getPriority(Object o){
+ int prio = 1; //X TODO discuss default priority
+ Priority priority = o.getClass().getAnnotation(Priority.class);
+ if (priority != null) {
+ prio = priority.value();
+ }
+ return prio;
+ }
+
+ /**
+ * @param services to scan
+ * @param <T> type of the service
+ *
+ * @return the service with the highest {@link Priority#value()}
+ *
+ * @throws ConfigException if there are multiple service implementations with the maximum priority
+ */
+ private <T> T getServiceWithHighestPriority(Collection<T> services, Class<T> serviceType) {
+
+ // we do not need the priority stuff if the list contains only one element
+ if (services.size() == 1) {
+ return services.iterator().next();
+ }
+
+ Integer highestPriority = null;
+ int highestPriorityServiceCount = 0;
+ T highestService = null;
+
+ for (T service : services) {
+ int prio = getPriority(service);
+ if (highestPriority == null || highestPriority < prio) {
+ highestService = service;
+ highestPriorityServiceCount = 1;
+ highestPriority = prio;
+ } else if (highestPriority == prio) {
+ highestPriorityServiceCount++;
+ }
+ }
+
+ if (highestPriorityServiceCount > 1) {
+ throw new ConfigException(MessageFormat.format("Found {0} implementations for Service {1} with Priority {2}: {3}",
+ highestPriorityServiceCount,
+ serviceType.getName(),
+ highestPriority,
+ services));
+ }
+
+ return highestService;
+ }
+
+ @Override
+ public int ordinal() {
+ return 1;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/TamayaCDIIntegration.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/TamayaCDIIntegration.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/TamayaCDIIntegration.java
new file mode 100644
index 0000000..3f62039
--- /dev/null
+++ b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/TamayaCDIIntegration.java
@@ -0,0 +1,52 @@
+/*
+ * 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.integration.cdi;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+
+/**
+ * Tamaya main integration with CDI, storing the BeanManager reference for implementation, where no
+ * JNDI is available or {@code java:comp/env/BeanManager} is not set correctly.
+ */
+public class TamayaCDIIntegration implements Extension {
+ /** The BeanManager references stored. */
+ private static BeanManager beanManager;
+
+ /**
+ * Initializes the current BeanManager with the instance passed.
+ * @param validation the event
+ * @param beanManager the BeanManager instance
+ */
+ @SuppressWarnings("all")
+ public void initBeanManager(@Observes AfterDeploymentValidation validation, BeanManager beanManager){
+ TamayaCDIIntegration.beanManager = beanManager;
+ }
+
+ /**
+ * Get the current {@link BeanManager} instance.
+ * @return the currently used bean manager.
+ */
+ public static BeanManager getBeanManager(){
+ return beanManager;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/main/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/main/resources/META-INF/beans.xml b/modules/injection/cdi-ee/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..562647f
--- /dev/null
+++ b/modules/injection/cdi-ee/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,19 @@
+<!--
+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 current 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.
+-->
+<beans></beans>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/modules/injection/cdi-ee/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000..e82118a
--- /dev/null
+++ b/modules/injection/cdi-ee/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.integration.cdi.ConfigurationExtension
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext b/modules/injection/cdi-ee/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
new file mode 100644
index 0000000..782b0ce
--- /dev/null
+++ b/modules/injection/cdi-ee/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
@@ -0,0 +1,38 @@
+#
+# 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.
+#
+
+#
+# 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 current 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.
+#
+org.apache.tamaya.integration.cdi.CDIAwareServiceContext
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerFailedInjectionTest.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerFailedInjectionTest.java b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerFailedInjectionTest.java
new file mode 100644
index 0000000..6bfda3a
--- /dev/null
+++ b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerFailedInjectionTest.java
@@ -0,0 +1,33 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.openejb.OpenEjbContainer;
+import org.junit.Test;
+
+import javax.ejb.embeddable.EJBContainer;
+
+public class ConfigurationProducerFailedInjectionTest {
+
+ @Test(expected = OpenEjbContainer.AssembleApplicationException.class)
+ public void notFoundShouldNotDeploy() {
+ // this explicitly tests that a non resolvable config makes
+ // the deployment fail and we won't have any failure at runtime
+ EJBContainer.createEJBContainer();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerTest.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerTest.java b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerTest.java
new file mode 100644
index 0000000..d128191
--- /dev/null
+++ b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerTest.java
@@ -0,0 +1,168 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.testing.Classes;
+import org.apache.openejb.testing.Module;
+import org.apache.tamaya.inject.api.Config;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.tomitribe.util.Duration;
+
+import javax.inject.Inject;
+import java.io.File;
+
+import static org.junit.Assert.*;
+
+@RunWith(ApplicationComposer.class)
+public class ConfigurationProducerTest {
+
+ @Module
+ @Classes(cdi = true, value = {
+ AllTypes.class,
+ ConfigurationExtension.class,
+ ConfigurationProducer.class
+ })
+ public EjbJar jar() {
+ return new EjbJar("config");
+ }
+
+ @Inject
+ private AllTypes allTypes;
+
+ @Test
+ public void defaultValues() {
+ assertNotNull(allTypes);
+ assertEquals("defaultString", allTypes.getDefaultString());
+ assertEquals(new File("./"), allTypes.getDefaultFile());
+ assertEquals(new Duration("2 hours and 54 minutes"), allTypes.getDefaultDuration());
+ assertEquals(true, allTypes.getDefaultBoolean());
+ assertEquals(45, (int) allTypes.getDefaultInteger());
+ }
+
+ @Test
+ public void actualPropertyValues() {
+ assertNotNull(allTypes);
+ assertEquals("hello", allTypes.getString());
+ assertEquals(new File("./conf"), allTypes.getFile());
+ assertEquals(new Duration("10 minutes and 57 seconds"), allTypes.getDuration());
+ assertEquals(true, allTypes.getaBoolean());
+ assertEquals(123, (int) allTypes.getInteger());
+ }
+
+ static class AllTypes {
+
+ @Inject
+ @Config(value = "string.value", defaultValue = "defaultString")
+ private String string;
+
+ @Inject
+ @Config(value = "defaultString.value", defaultValue = "defaultString")
+ private String defaultString;
+
+ @Inject
+ @Config(value = "file.value", defaultValue = "./")
+ private File file;
+
+ @Inject
+ @Config(value = "defaultFile.value", defaultValue = "./")
+ private File defaultFile;
+
+ @Inject
+ @Config(value = "duration.value", defaultValue = "2 hours and 54 minutes")
+ private Duration duration;
+
+ @Inject
+ @Config(value = "defaultDuration.value", defaultValue = "2 hours and 54 minutes")
+ private Duration defaultDuration;
+
+ @Inject
+ @Config(value = "boolean.value", defaultValue = "true")
+ private Boolean aBoolean;
+
+ @Inject
+ @Config(value = "defaultBoolean.value", defaultValue = "true")
+ private Boolean defaultBoolean;
+
+ @Inject
+ @Config(value = "integer.value", defaultValue = "45")
+ private Integer integer;
+
+ @Inject
+ @Config(value = "defaultInteger.value", defaultValue = "45")
+ private Integer defaultInteger;
+
+ public String getString() {
+ return string;
+ }
+
+ public File getFile() {
+ return file;
+ }
+
+ public Duration getDuration() {
+ return duration;
+ }
+
+ public Boolean getaBoolean() {
+ return aBoolean;
+ }
+
+ public Integer getInteger() {
+ return integer;
+ }
+
+ public String getDefaultString() {
+ return defaultString;
+ }
+
+ public File getDefaultFile() {
+ return defaultFile;
+ }
+
+ public Duration getDefaultDuration() {
+ return defaultDuration;
+ }
+
+ public Boolean getDefaultBoolean() {
+ return defaultBoolean;
+ }
+
+ public Integer getDefaultInteger() {
+ return defaultInteger;
+ }
+
+ @Override
+ public String toString() {
+ return "AllTypes{" +
+ "string='" + string + '\'' +
+ ", defaultString='" + defaultString + '\'' +
+ ", file=" + file +
+ ", defaultFile=" + defaultFile +
+ ", duration=" + duration +
+ ", defaultDuration=" + defaultDuration +
+ ", aBoolean=" + aBoolean +
+ ", defaultBoolean=" + defaultBoolean +
+ ", integer=" + integer +
+ ", defaultInteger=" + defaultInteger +
+ '}';
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationResolverTest.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationResolverTest.java b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationResolverTest.java
new file mode 100644
index 0000000..1c551b2
--- /dev/null
+++ b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationResolverTest.java
@@ -0,0 +1,112 @@
+///*
+// * 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.integration.cdi;
+//
+//import org.apache.openejb.loader.SystemInstance;
+//import org.junit.Before;
+//import org.junit.Test;
+//
+//import static org.junit.Assert.*;
+//
+//public class ConfigurationResolverTest {
+//
+// private ConfigurationResolver resolver;
+//
+// @Before
+// public void cleanEnv() {
+// SystemInstance.reset();
+// System.clearProperty("environment");
+//
+// resolver = new ConfigurationResolver();
+// }
+//
+// @Test
+// public void defaultEnvironment() {
+// assertEquals("test", resolver.getEnvironment());
+// }
+//
+// @Test
+// public void overrideDefaultEnvironment() {
+// System.setProperty("environment", "dev");
+//
+// // don't use the field cause before is invoked before we have a chance to set the environment
+// assertEquals("dev", new ConfigurationResolver().getEnvironment());
+// }
+//
+// @Test
+// public void isResolvable() {
+//
+// { // precondition
+// try {
+// resolver.isResolvableConfig(null, "value");
+// fail("a null key is not resolvable");
+//
+// } catch (final NullPointerException e) {
+// // expected
+// }
+// }
+// { // precondition
+// try {
+// resolver.isResolvableConfig("key", null);
+// fail("a null default value is not resolvable");
+//
+// } catch (final NullPointerException e) {
+// // expected
+// }
+// }
+//
+// // loaded from test.properties
+// assertTrue(resolver.isResolvableConfig("remote.wsdl.location", ""));
+// assertFalse(resolver.isResolvableConfig("something", ""));
+//
+// // loaded from base.properties
+// assertTrue(resolver.isResolvableConfig("remote.username", ""));
+// assertFalse(resolver.isResolvableConfig("bla", ""));
+// }
+//
+// @Test
+// public void found() {
+//
+// { // precondition
+// try {
+// resolver.isResolvableConfig(null, "value");
+// fail("a null key is not resolvable");
+//
+// } catch (final NullPointerException e) {
+// // expected
+// }
+// }
+// { // precondition
+// try {
+// resolver.isResolvableConfig("key", null);
+// fail("a null default value is not resolvable");
+//
+// } catch (final NullPointerException e) {
+// // expected
+// }
+// }
+//
+// // loaded from test.properties
+// assertEquals("classpath:/service-wsdl.xml", resolver.resolve("remote.wsdl.location", ""));
+// assertEquals("something-else", resolver.resolve("something", "something-else"));
+//
+// // loaded from base.properties
+// assertEquals("joecool", resolver.resolve("remote.username", ""));
+// assertEquals("blabla", resolver.resolve("bla", "blabla"));
+// }
+//
+//}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/EnvironmentsTest.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/EnvironmentsTest.java b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/EnvironmentsTest.java
new file mode 100644
index 0000000..cb60307
--- /dev/null
+++ b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/EnvironmentsTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.integration.cdi;
+//
+//import org.junit.Test;
+//
+//import java.util.Map;
+//import java.util.Properties;
+//
+//import static org.junit.Assert.assertEquals;
+//
+///**
+// * Tests the related environment properties exist
+// */
+//public class EnvironmentsTest {
+//
+// @Test
+// public void testGetProperties() throws Exception {
+//
+// final Properties test = Environments.getProperties("test");
+//
+// // loaded from test.properties
+// assertEquals("classpath:/test-service-wsdl.xml", test.getProperty("remote.wsdl.location"));
+//
+// // loaded from base.properties
+// assertEquals("joecool", test.getProperty("remote.username"));
+// }
+//
+// @Test(expected = IllegalArgumentException.class)
+// public void noEnvFound() {
+// Environments.getProperties("does not exists");
+// }
+//
+// @Test
+// public void dev() throws Exception {
+//
+// final Properties test = Environments.getProperties("dev");
+//
+// assertEquals("org.apache.openejb.cipher.StaticDESPasswordCipher", test.getProperty("cipher"));
+// assertEquals("NjAq6q2agYVnvSMz+eYUZg==", test.getProperty("remote.password"));
+// assertEquals("1443", test.getProperty("remote.port"));
+// assertEquals("https://srv1114.supertribe.org:1443/remote/service/url", test.getProperty("remote.target.url"));
+// assertEquals("srv1114.supertribe.org:1443", test.getProperty("remote.address"));
+// assertEquals("srv1114.supertribe.org", test.getProperty("remote.host"));
+// assertEquals("classpath:/service-wsdl.xml", test.getProperty("remote.wsdl.location"));
+// assertEquals("joecool", test.getProperty("remote.username"));
+// }
+//
+// @Test
+// public void cert() throws Exception {
+// final Properties test = Environments.getProperties("cert");
+// assertEquals("srv1016.supertribe.org", test.getProperty("remote.host"));
+// assertEquals("joecool", test.getProperty("remote.username"));
+// }
+//
+// @Test
+// public void prod() throws Exception {
+// final Properties test = Environments.getProperties("prod");
+// assertEquals("remotedb001.supertribe.org", test.getProperty("remote.host"));
+// assertEquals("joecool", test.getProperty("remote.username"));
+// }
+//
+//
+// private static void generateAsserts(Properties test) {
+// for (Map.Entry<Object, Object> entry : test.entrySet()) {
+// System.out.printf("assertEquals(\"%s\", test.getProperty(\"%s\"));%n", entry.getValue(), entry.getKey());
+// }
+// }
+//}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/InterpolationTest.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/InterpolationTest.java b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/InterpolationTest.java
new file mode 100644
index 0000000..56cc8c9
--- /dev/null
+++ b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/InterpolationTest.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.integration.cdi;
+//
+//import org.junit.Test;
+//import org.tomitribe.util.IO;
+//
+//import java.net.URL;
+//import java.util.Properties;
+//
+//import static org.junit.Assert.assertEquals;
+//
+//public class InterpolationTest {
+//
+// @Test
+// public void testInterpolate() throws Exception {
+// final Properties interpolated;
+// {
+// final Properties properties = new Properties();
+// properties.setProperty("foo.host", "localhost");
+// properties.setProperty("foo.port", "1234");
+// properties.setProperty("address", "http://${foo.host}:${foo.port}");
+// properties.setProperty("url", "${address}/webapp");
+// properties.setProperty("urlUnchanged", "${not an address}/webapp");
+//
+// interpolated = Interpolation.interpolate(properties);
+// }
+//
+// assertEquals("localhost", interpolated.getProperty("foo.host"));
+// assertEquals("1234", interpolated.getProperty("foo.port"));
+// assertEquals("http://localhost:1234", interpolated.getProperty("address"));
+// assertEquals("http://localhost:1234/webapp", interpolated.getProperty("url"));
+// assertEquals("${not an address}/webapp", interpolated.getProperty("urlUnchanged"));
+// }
+//
+// @Test
+// public void test() throws Exception {
+//
+// final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+//
+// final URL resource = loader.getResource("test.properties");
+// final Properties properties = Interpolation.interpolate(IO.readProperties(resource));
+//
+// //remote.wsdl.location = classpath:/lx01116-zhr-active-partner-service-wsdl.xml
+// assertEquals("classpath:/test-service-wsdl.xml", properties.getProperty("remote.wsdl.location"));
+// }
+//
+//}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/NotFoundNoDefault.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/NotFoundNoDefault.java b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/NotFoundNoDefault.java
new file mode 100644
index 0000000..afeeb84
--- /dev/null
+++ b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/NotFoundNoDefault.java
@@ -0,0 +1,78 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.tamaya.inject.api.Config;
+import org.tomitribe.util.Duration;
+
+import javax.inject.Inject;
+import java.io.File;
+
+public class NotFoundNoDefault {
+
+ @Inject
+ @Config("string.bla")
+ private String string;
+
+ @Inject
+ @Config("file.bla")
+ private File file;
+
+ @Inject
+ @Config("duration.bla")
+ private Duration duration;
+
+ @Inject
+ @Config("boolean.bla")
+ private Boolean aBoolean;
+
+ @Inject
+ @Config("integer.bla")
+ private Integer integer;
+
+ public String getString() {
+ return string;
+ }
+
+ public File getFile() {
+ return file;
+ }
+
+ public Duration getDuration() {
+ return duration;
+ }
+
+ public Boolean getaBoolean() {
+ return aBoolean;
+ }
+
+ public Integer getInteger() {
+ return integer;
+ }
+
+ @Override
+ public String toString() {
+ return "NotFoundNoDefault{" +
+ "string='" + string + '\'' +
+ ", file=" + file +
+ ", duration=" + duration +
+ ", aBoolean=" + aBoolean +
+ ", integer=" + integer +
+ '}';
+ }
+
+ }
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/test/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/test/resources/META-INF/beans.xml b/modules/injection/cdi-ee/src/test/resources/META-INF/beans.xml
new file mode 100644
index 0000000..562647f
--- /dev/null
+++ b/modules/injection/cdi-ee/src/test/resources/META-INF/beans.xml
@@ -0,0 +1,19 @@
+<!--
+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 current 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.
+-->
+<beans></beans>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/test/resources/META-INF/javaconfiguration.properties
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/test/resources/META-INF/javaconfiguration.properties b/modules/injection/cdi-ee/src/test/resources/META-INF/javaconfiguration.properties
new file mode 100644
index 0000000..8d3c5c8
--- /dev/null
+++ b/modules/injection/cdi-ee/src/test/resources/META-INF/javaconfiguration.properties
@@ -0,0 +1,32 @@
+#
+# 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 current 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.
+#
+remote.wsdl.location = classpath:/service-wsdl.xml
+remote.port=1443
+remote.address=${remote.host}:${remote.port}
+remote.target.url = https://${remote.address}/remote/service/url
+remote.username = joecool
+# ciphered using built in StaticDESPasswordCipher
+remote.password = NjAq6q2agYVnvSMz+eYUZg==
+cipher=org.apache.openejb.cipher.StaticDESPasswordCipher
+
+string.value = hello
+file.value = ./conf
+duration.value = 10 minutes and 57 seconds
+boolean.value = true
+integer.value = 123
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/test/resources/base.properties
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/test/resources/base.properties b/modules/injection/cdi-ee/src/test/resources/base.properties
new file mode 100644
index 0000000..a4d9896
--- /dev/null
+++ b/modules/injection/cdi-ee/src/test/resources/base.properties
@@ -0,0 +1,32 @@
+#
+# 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 current 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.
+#
+remote.wsdl.location = classpath:/service-wsdl.xml
+remote.port=1443
+remote.address=${remote.host}:${remote.port}
+remote.target.url = https://${remote.address}/remote/service/url
+remote.username = joecool
+# ciphered using built in StaticDESPasswordCipher
+remote.password = NjAq6q2agYVnvSMz+eYUZg==
+cipher=org.apache.openejb.cipher.StaticDESPasswordCipher
+
+string.value = hello
+file.value = ./conf
+duration.value = 10 minutes and 57 seconds
+boolean.value = true
+integer.value = 123
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/test/resources/cert.properties
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/test/resources/cert.properties b/modules/injection/cdi-ee/src/test/resources/cert.properties
new file mode 100644
index 0000000..c2c3712
--- /dev/null
+++ b/modules/injection/cdi-ee/src/test/resources/cert.properties
@@ -0,0 +1,20 @@
+#
+# 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 current 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.
+#
+remote.host=srv1016.supertribe.org
+remote.password=vm9oNWJpN8Y=
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/test/resources/dev.properties
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/test/resources/dev.properties b/modules/injection/cdi-ee/src/test/resources/dev.properties
new file mode 100644
index 0000000..abd3e03
--- /dev/null
+++ b/modules/injection/cdi-ee/src/test/resources/dev.properties
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+remote.host=srv1114.supertribe.org
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/test/resources/prod.properties
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/test/resources/prod.properties b/modules/injection/cdi-ee/src/test/resources/prod.properties
new file mode 100644
index 0000000..9f1ad67
--- /dev/null
+++ b/modules/injection/cdi-ee/src/test/resources/prod.properties
@@ -0,0 +1,20 @@
+#
+# 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 current 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.
+#
+remote.host=remotedb001.supertribe.org
+remote.password=vm9oNWJpN8Y=
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/test/resources/qa.properties
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/test/resources/qa.properties b/modules/injection/cdi-ee/src/test/resources/qa.properties
new file mode 100644
index 0000000..3f43795
--- /dev/null
+++ b/modules/injection/cdi-ee/src/test/resources/qa.properties
@@ -0,0 +1,20 @@
+#
+# 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 current 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.
+#
+remote.host=srv1115.supertribe.org
+remote.password=vm9oNWJpN8Y=
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/test/resources/test.properties
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/test/resources/test.properties b/modules/injection/cdi-ee/src/test/resources/test.properties
new file mode 100644
index 0000000..8e08405
--- /dev/null
+++ b/modules/injection/cdi-ee/src/test/resources/test.properties
@@ -0,0 +1,20 @@
+#
+# 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 current 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.
+#
+remote.wsdl.location = classpath:/test-service-wsdl.xml
+
[14/15] incubator-tamaya-extensions git commit: TAMAYA-182:
Streamlined/unified builder API and fixed some bugs popping up during
testing.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/WritableXmlPropertiesSource.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/WritableXmlPropertiesSource.java b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/WritableXmlPropertiesSource.java
new file mode 100644
index 0000000..d6aa7ec
--- /dev/null
+++ b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/internal/WritableXmlPropertiesSource.java
@@ -0,0 +1,49 @@
+/*
+ * 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.mutableconfig.internal;
+
+import org.apache.tamaya.mutableconfig.propertysources.MutableXmlPropertiesPropertySource;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Writable test property source based on the {@link MutableXmlPropertiesPropertySource}.
+ */
+public class WritableXmlPropertiesSource extends MutableXmlPropertiesPropertySource {
+
+ public static File target = createFile();
+
+ private static File createFile() {
+ try {
+ return File.createTempFile("writableProps",".xml");
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new IllegalStateException("Cannot init test.", e);
+ }
+ }
+
+ /**
+ * Creates a new Properties based PropertySource based on the given URL.
+ */
+ public WritableXmlPropertiesSource() throws IOException {
+ super(target, 200);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/mutable-config/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource b/modules/mutable-config/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
new file mode 100644
index 0000000..609b9fe
--- /dev/null
+++ b/modules/mutable-config/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
@@ -0,0 +1,20 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.mutableconfig.internal.WritablePropertiesSource
+org.apache.tamaya.mutableconfig.internal.WritableXmlPropertiesSource
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/pom.xml
----------------------------------------------------------------------
diff --git a/modules/spi-support/pom.xml b/modules/spi-support/pom.xml
index c324481..edc8df3 100644
--- a/modules/spi-support/pom.xml
+++ b/modules/spi-support/pom.xml
@@ -23,7 +23,7 @@ under the License.
<parent>
<groupId>org.apache.tamaya.ext</groupId>
- <artifactId>tamaya-extensions</artifactId>
+ <artifactId>tamaya-extensions-all</artifactId>
<version>0.3-incubating-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
@@ -56,6 +56,10 @@ under the License.
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>java-hamcrest</artifactId>
+ </dependency>
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/CLIPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/CLIPropertySource.java b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/CLIPropertySource.java
new file mode 100644
index 0000000..ec0a532
--- /dev/null
+++ b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/CLIPropertySource.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.spisupport;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * PropertySource that allows to add the programs main arguments as configuration entries. Unix syntax using '--' and
+ * '-' params is supported.
+ */
+public class CLIPropertySource extends BasePropertySource{
+
+ /** The original main arguments. */
+ private static String[] args = new String[0];
+
+ /** The map of parsed main arguments. */
+ private static Map<String,String> mainArgs;
+
+ /** Initializes the initial state. */
+ static{
+ initMainArgs(args);
+ }
+
+
+ /**
+ * Creates a new instance.
+ */
+ public CLIPropertySource(){}
+
+ /**
+ * Configure the main arguments, hereby parsing and mapping the main arguments into
+ * configuration propertiesi as key-value pairs.
+ * @param args the main arguments, not null.
+ */
+ public static void initMainArgs(String... args){
+ CLIPropertySource.args = Objects.requireNonNull(args);
+ // TODO is there a way to figure out the args?
+ String argsProp = System.getProperty("main.args");
+ if(argsProp!=null){
+ CLIPropertySource.args = argsProp.split("\\s");
+ }
+ Map<String,String> result = null;
+ if(CLIPropertySource.args==null){
+ result = Collections.emptyMap();
+ }else{
+ result = new HashMap<>();
+ String prefix = System.getProperty("main.args.prefix");
+ if(prefix==null){
+ prefix="";
+ }
+ String key = null;
+ for(String arg:CLIPropertySource.args){
+ if(arg.startsWith("--")){
+ arg = arg.substring(2);
+ int index = arg.indexOf("=");
+ if(index>0){
+ key = arg.substring(0,index).trim();
+ result.put(prefix+key, arg.substring(index+1).trim());
+ key = null;
+ }else{
+ result.put(prefix+arg, arg);
+ }
+ }else if(arg.startsWith("-")){
+ key = arg.substring(1);
+ }else{
+ if(key!=null){
+ result.put(prefix+key, arg);
+ key = null;
+ }else{
+ result.put(prefix+arg, arg);
+ }
+ }
+ }
+ }
+ CLIPropertySource.mainArgs = Collections.unmodifiableMap(result);
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return Collections.unmodifiableMap(mainArgs);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java
index 52a0d11..56c6e3d 100644
--- a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java
+++ b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java
@@ -75,7 +75,7 @@ public class DefaultConfiguration implements Configuration {
if(configData==null){
return null;
}
- return PropertyFiltering.applyFilter(key, configData.getConfigEntries(), configurationContext);
+ return PropertyFilterManager.applyFilter(key, configData.getConfigEntries(), configurationContext);
}
/**
@@ -124,7 +124,7 @@ public class DefaultConfiguration implements Configuration {
*/
@Override
public Map<String, String> getProperties() {
- return PropertyFiltering.applyFilters(evaluateUnfilteredMap(), configurationContext);
+ return PropertyFilterManager.applyFilters(evaluateUnfilteredMap(), configurationContext);
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java
index 76f254b..fca6527 100644
--- a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java
+++ b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java
@@ -1,41 +1,36 @@
/*
* 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
+ * 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
+ * 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.
+ * 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.spisupport;
-import org.apache.tamaya.ConfigurationProvider;
import org.apache.tamaya.TypeLiteral;
import org.apache.tamaya.spi.ConfigurationContext;
import org.apache.tamaya.spi.ConfigurationContextBuilder;
import org.apache.tamaya.spi.PropertyConverter;
import org.apache.tamaya.spi.PropertyFilter;
import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertySourceProvider;
import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
import org.apache.tamaya.spi.ServiceContextManager;
-import javax.annotation.Priority;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
@@ -73,70 +68,54 @@ public class DefaultConfigurationContext implements ConfigurationContext {
* Lock for internal synchronization.
*/
private final ReentrantReadWriteLock propertySourceLock = new ReentrantReadWriteLock();
-
- /** Comparator used for ordering property sources. */
- private final PropertySourceComparator propertySourceComparator = new PropertySourceComparator();
-
- /** Comparator used for ordering property filters. */
- private final PropertyFilterComparator propertyFilterComparator = new PropertyFilterComparator();
-
+ /**
+ * Lock for internal synchronization.
+ */
+ private final ReentrantReadWriteLock propertyFilterLock = new ReentrantReadWriteLock();
/**
- * The first time the Configuration system gets invoked we do initialize
- * all our {@link PropertySource}s and
- * {@link PropertyFilter}s which are known at startup.
+ * Creates an empty Configuration context.
*/
- public DefaultConfigurationContext() {
- List<PropertySource> propertySources = new ArrayList<>();
+ protected DefaultConfigurationContext() {
+ this(new DefaultConfigurationContextBuilder());
+ }
+ DefaultConfigurationContext(DefaultConfigurationContextBuilder builder) {
+ List<PropertySource> propertySources = new ArrayList<>();
// first we load all PropertySources which got registered via java.util.ServiceLoader
- propertySources.addAll(ServiceContextManager.getServiceContext().getServices(PropertySource.class));
-
- // after that we add all PropertySources which get dynamically registered via their PropertySourceProviders
- propertySources.addAll(evaluatePropertySourcesFromProviders());
-
+ propertySources.addAll(builder.propertySources);
// now sort them according to their ordinal values
- Collections.sort(propertySources, new PropertySourceComparator());
-
immutablePropertySources = Collections.unmodifiableList(propertySources);
LOG.info("Registered " + immutablePropertySources.size() + " property sources: " +
immutablePropertySources);
// as next step we pick up the PropertyFilters pretty much the same way
- List<PropertyFilter> propertyFilters = new ArrayList<>();
- propertyFilters.addAll(ServiceContextManager.getServiceContext().getServices(PropertyFilter.class));
- Collections.sort(propertyFilters, new PropertyFilterComparator());
+ List<PropertyFilter> propertyFilters = new ArrayList<>(builder.getPropertyFilters());
immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
immutablePropertyFilters);
- immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
- LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
- immutablePropertyFilters);
- propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().getService(PropertyValueCombinationPolicy.class);
- if(propertyValueCombinationPolicy==null) {
+ // Finally add the converters
+ for(Map.Entry<TypeLiteral<?>, Collection<PropertyConverter<?>>> en:builder.getPropertyConverter().entrySet()) {
+ for (PropertyConverter converter : en.getValue()) {
+ this.propertyConverterManager.register(en.getKey(), converter);
+ }
+ }
+ LOG.info("Registered " + propertyConverterManager.getPropertyConverters().size() + " property converters: " +
+ propertyConverterManager.getPropertyConverters());
+
+ propertyValueCombinationPolicy = builder.combinationPolicy;
+ if(propertyValueCombinationPolicy==null){
+ propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().getService(PropertyValueCombinationPolicy.class);
+ }
+ if(propertyValueCombinationPolicy==null){
propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
}
LOG.info("Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
}
- /**
- * Pick up all {@link PropertySourceProvider}s and return all the
- * {@link PropertySource}s they like to register.
- */
- private Collection<? extends PropertySource> evaluatePropertySourcesFromProviders() {
- List<PropertySource> propertySources = new ArrayList<>();
- Collection<PropertySourceProvider> propertySourceProviders = ServiceContextManager.getServiceContext().getServices(PropertySourceProvider.class);
- for (PropertySourceProvider propertySourceProvider : propertySourceProviders) {
- Collection<PropertySource> sources = propertySourceProvider.getPropertySources();
- LOG.finer("PropertySourceProvider " + propertySourceProvider.getClass().getName() +
- " provided the following property sources: " + sources);
- propertySources.addAll(sources);
- }
-
- return propertySources;
- }
+ @Deprecated
@Override
public void addPropertySources(PropertySource... propertySourcesToAdd) {
Lock writeLock = propertySourceLock.writeLock();
@@ -152,77 +131,119 @@ public class DefaultConfigurationContext implements ConfigurationContext {
}
}
- /**
- * Comparator used for comparing PropertySources.
- */
- private static class PropertySourceComparator implements Comparator<PropertySource>, Serializable {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * Order property source reversely, the most important come first.
- *
- * @param source1 the first PropertySource
- * @param source2 the second PropertySource
- * @return the comparison result.
- */
- private int comparePropertySources(PropertySource source1, PropertySource source2) {
- if (source1.getOrdinal() < source2.getOrdinal()) {
- return -1;
- } else if (source1.getOrdinal() > source2.getOrdinal()) {
- return 1;
- } else {
- return source1.getClass().getName().compareTo(source2.getClass().getName());
- }
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof DefaultConfigurationContext)){
+ return false;
}
- @Override
- public int compare(PropertySource source1, PropertySource source2) {
- return comparePropertySources(source1, source2);
+ DefaultConfigurationContext that = (DefaultConfigurationContext) o;
+
+ if (!propertyConverterManager.equals(that.propertyConverterManager)) {
+ return false;
+ }
+ if (!immutablePropertySources.equals(that.immutablePropertySources)) {
+ return false;
+ }
+ if (!immutablePropertyFilters.equals(that.immutablePropertyFilters)) {
+ return false;
}
+ return getPropertyValueCombinationPolicy().equals(that.getPropertyValueCombinationPolicy());
+
}
- /**
- * Comparator used for comparing PropertyFilters.
- */
- private static class PropertyFilterComparator implements Comparator<PropertyFilter>, Serializable{
-
- private static final long serialVersionUID = 1L;
-
- /**
- * Compare 2 filters for ordering the filter chain.
- *
- * @param filter1 the first filter
- * @param filter2 the second filter
- * @return the comparison result
- */
- private int comparePropertyFilters(PropertyFilter filter1, PropertyFilter filter2) {
- Priority prio1 = filter1.getClass().getAnnotation(Priority.class);
- Priority prio2 = filter2.getClass().getAnnotation(Priority.class);
- int ord1 = prio1 != null ? prio1.value() : 0;
- int ord2 = prio2 != null ? prio2.value() : 0;
-
- if (ord1 < ord2) {
- return -1;
- } else if (ord1 > ord2) {
- return 1;
- } else {
- return filter1.getClass().getName().compareTo(filter2.getClass().getName());
+ @Override
+ public int hashCode() {
+ int result = propertyConverterManager.hashCode();
+ result = 31 * result + immutablePropertySources.hashCode();
+ result = 31 * result + immutablePropertyFilters.hashCode();
+ result = 31 * result + getPropertyValueCombinationPolicy().hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder("ConfigurationContext{\n");
+ b.append(" Property Sources\n");
+ b.append(" ----------------\n");
+ b.append(" CLASS NAME ORDINAL SCANNABLE SIZE\n");
+ for(PropertySource ps:getPropertySources()){
+ b.append(" ");
+ appendFormatted(b, ps.getClass().getSimpleName(), 30);
+ appendFormatted(b, ps.getName(), 70);
+ appendFormatted(b, String.valueOf(ps.getOrdinal()), 8);
+ appendFormatted(b, String.valueOf(ps.isScannable()), 10);
+ if(ps.isScannable()) {
+ appendFormatted(b, String.valueOf(ps.getProperties().size()), 8);
+ }else{
+ appendFormatted(b, "-", 8);
+ }
+ b.append('\n');
+ }
+ b.append("\n");
+ b.append(" Property Filters\n");
+ b.append(" ----------------\n");
+ b.append(" CLASS INFO\n");
+ for(PropertyFilter filter:getPropertyFilters()){
+ b.append(" ");
+ appendFormatted(b, filter.getClass().getSimpleName(), 30);
+ b.append(removeNewLines(filter.toString()));
+ b.append('\n');
+ }
+ b.append("\n\n");
+ b.append(" Property Converters\n");
+ b.append(" -------------------\n");
+ b.append(" CLASS TYPE INFO\n");
+ for(Map.Entry<TypeLiteral<?>, List<PropertyConverter<?>>> converterEntry:getPropertyConverters().entrySet()){
+ for(PropertyConverter converter: converterEntry.getValue()){
+ b.append(" ");
+ appendFormatted(b, converter.getClass().getSimpleName(), 30);
+ appendFormatted(b, converterEntry.getKey().getRawType().getSimpleName(), 30);
+ b.append(removeNewLines(converter.toString()));
+ b.append('\n');
}
}
+ b.append('}');
+ return b.toString();
+ }
- @Override
- public int compare(PropertyFilter filter1, PropertyFilter filter2) {
- return comparePropertyFilters(filter1, filter2);
+ private void appendFormatted(StringBuilder b, String text, int length) {
+ int padding;
+ if(text.length() <= (length)){
+ b.append(text);
+ padding = length - text.length();
+ }else{
+ b.append(text.substring(0, length-1));
+ padding = 1;
+ }
+ for(int i=0;i<padding;i++){
+ b.append(' ');
}
}
+ private String removeNewLines(String s) {
+ return s.replace('\n', ' ').replace('\r', ' ');
+ }
+
@Override
public List<PropertySource> getPropertySources() {
return immutablePropertySources;
}
@Override
+ public PropertySource getPropertySource(String name) {
+ for(PropertySource ps:getPropertySources()){
+ if(name.equals(ps.getName())){
+ return ps;
+ }
+ }
+ return null;
+ }
+
+ @Override
public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
propertyConverterManager.register(typeToConvert, propertyConverter);
LOG.info("Added PropertyConverter: " + propertyConverter.getClass().getName());
@@ -250,7 +271,7 @@ public class DefaultConfigurationContext implements ConfigurationContext {
@Override
public ConfigurationContextBuilder toBuilder() {
- return ConfigurationProvider.getConfigurationContextBuilder().setContext(this);
+ return new DefaultConfigurationContextBuilder(this);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContextBuilder.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContextBuilder.java b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContextBuilder.java
new file mode 100644
index 0000000..edf8173
--- /dev/null
+++ b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContextBuilder.java
@@ -0,0 +1,410 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertySourceProvider;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Default implementation of {@link ConfigurationContextBuilder}.
+ */
+public class DefaultConfigurationContextBuilder implements ConfigurationContextBuilder {
+
+ private static final Logger LOG = Logger.getLogger(DefaultConfigurationContextBuilder.class.getName());
+
+ public static final Comparator<PropertySource> DEFAULT_PROPERTYSOURCE_COMPARATOR = new PropertySourceComparator();
+ public static final Comparator<?> DEFAULT_PROPERTYFILTER_COMPARATOR = new PriorityServiceComparator();
+
+ List<PropertyFilter> propertyFilters = new ArrayList<>();
+ List<PropertySource> propertySources = new ArrayList<>();
+ PropertyValueCombinationPolicy combinationPolicy =
+ PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+ Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> propertyConverters = new HashMap<>();
+
+ /**
+ * Flag if the config has already been built.
+ * Configuration can be built only once
+ */
+ private boolean built;
+
+
+
+ /**
+ * Creates a new builder instance.
+ */
+ public DefaultConfigurationContextBuilder() {
+ }
+
+ /**
+ * Creates a new builder instance.
+ */
+ public DefaultConfigurationContextBuilder(ConfigurationContext context) {
+ this.propertyConverters.putAll(context.getPropertyConverters());
+ this.propertyFilters.addAll(context.getPropertyFilters());
+ for(PropertySource ps:context.getPropertySources()) {
+ addPropertySources(ps);
+ }
+ this.combinationPolicy = context.getPropertyValueCombinationPolicy();
+ }
+
+ /**
+ * Allows to set configuration context during unit tests.
+ */
+ ConfigurationContextBuilder setConfigurationContext(ConfigurationContext configurationContext) {
+ checkBuilderState();
+ //noinspection deprecation
+ this.propertyFilters.clear();
+ this.propertyFilters.addAll(configurationContext.getPropertyFilters());
+ this.propertySources.clear();
+ for(PropertySource ps:configurationContext.getPropertySources()) {
+ addPropertySources(ps);
+ }
+ this.propertyConverters.clear();
+ this.propertyConverters.putAll(configurationContext.getPropertyConverters());
+ this.combinationPolicy = configurationContext.getPropertyValueCombinationPolicy();
+ return this;
+ }
+
+
+ @Override
+ public ConfigurationContextBuilder setContext(ConfigurationContext context) {
+ checkBuilderState();
+ this.propertyConverters.putAll(context.getPropertyConverters());
+ for(PropertySource ps:context.getPropertySources()){
+ this.propertySources.add(ps);
+ }
+ this.propertyFilters.addAll(context.getPropertyFilters());
+ this.combinationPolicy = context.getPropertyValueCombinationPolicy();
+ return this;
+ }
+
+ @Override
+ public ConfigurationContextBuilder addPropertySources(PropertySource... sources){
+ return addPropertySources(Arrays.asList(sources));
+ }
+
+ @Override
+ public ConfigurationContextBuilder addPropertySources(Collection<PropertySource> sources){
+ checkBuilderState();
+ for(PropertySource source:sources) {
+ if (!this.propertySources.contains(source)) {
+ this.propertySources.add(source);
+ }
+ }
+ return this;
+ }
+
+ protected DefaultConfigurationContextBuilder loadDefaultPropertyFilters() {
+ checkBuilderState();
+ for(PropertyFilter pf:ServiceContextManager.getServiceContext().getServices(PropertyFilter.class)){
+ addPropertyFilters(pf);
+ }
+ return this;
+ }
+
+ protected DefaultConfigurationContextBuilder loadDefaultPropertySources() {
+ checkBuilderState();
+ for(PropertySource ps:ServiceContextManager.getServiceContext().getServices(PropertySource.class)){
+ addPropertySources(ps);
+ }
+ for(PropertySourceProvider pv:ServiceContextManager.getServiceContext().getServices(PropertySourceProvider.class)){
+ for(PropertySource ps:pv.getPropertySources()){
+ addPropertySources(ps);
+ }
+ }
+ return this;
+ }
+
+ protected DefaultConfigurationContextBuilder loadDefaultPropertyConverters() {
+ checkBuilderState();
+ for(Map.Entry<TypeLiteral, Collection<PropertyConverter>> en:getDefaultPropertyConverters().entrySet()){
+ for(PropertyConverter pc: en.getValue()) {
+ addPropertyConverters(en.getKey(), pc);
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public ConfigurationContextBuilder removePropertySources(PropertySource... propertySources) {
+ return removePropertySources(Arrays.asList(propertySources));
+ }
+
+ @Override
+ public ConfigurationContextBuilder removePropertySources(Collection<PropertySource> propertySources) {
+ checkBuilderState();
+ this.propertySources.removeAll(propertySources);
+ return this;
+ }
+
+ private PropertySource getPropertySource(String name) {
+ for(PropertySource ps:propertySources){
+ if(ps.getName().equals(name)){
+ return ps;
+ }
+ }
+ throw new IllegalArgumentException("No such PropertySource: "+name);
+ }
+
+ @Override
+ public List<PropertySource> getPropertySources() {
+ return this.propertySources;
+ }
+
+ @Override
+ public ConfigurationContextBuilder increasePriority(PropertySource propertySource) {
+ checkBuilderState();
+ int index = propertySources.indexOf(propertySource);
+ if(index<0){
+ throw new IllegalArgumentException("No such PropertySource: " + propertySource);
+ }
+ if(index<(propertySources.size()-1)){
+ propertySources.remove(propertySource);
+ propertySources.add(index+1, propertySource);
+ }
+ return this;
+ }
+
+ @Override
+ public ConfigurationContextBuilder decreasePriority(PropertySource propertySource) {
+ checkBuilderState();
+ int index = propertySources.indexOf(propertySource);
+ if(index<0){
+ throw new IllegalArgumentException("No such PropertySource: " + propertySource);
+ }
+ if(index>0){
+ propertySources.remove(propertySource);
+ propertySources.add(index-1, propertySource);
+ }
+ return this;
+ }
+
+ @Override
+ public ConfigurationContextBuilder highestPriority(PropertySource propertySource) {
+ checkBuilderState();
+ int index = propertySources.indexOf(propertySource);
+ if(index<0){
+ throw new IllegalArgumentException("No such PropertySource: " + propertySource);
+ }
+ if(index<(propertySources.size()-1)){
+ propertySources.remove(propertySource);
+ propertySources.add(propertySource);
+ }
+ return this;
+ }
+
+ @Override
+ public ConfigurationContextBuilder lowestPriority(PropertySource propertySource) {
+ checkBuilderState();
+ int index = propertySources.indexOf(propertySource);
+ if(index<0){
+ throw new IllegalArgumentException("No such PropertySource: " + propertySource);
+ }
+ if(index>0){
+ propertySources.remove(propertySource);
+ propertySources.add(0, propertySource);
+ }
+ return this;
+ }
+
+ @Override
+ public ConfigurationContextBuilder addPropertyFilters(PropertyFilter... filters){
+ return addPropertyFilters(Arrays.asList(filters));
+ }
+
+ @Override
+ public ConfigurationContextBuilder addPropertyFilters(Collection<PropertyFilter> filters){
+ checkBuilderState();
+ for(PropertyFilter f:filters) {
+ if (!this.propertyFilters.contains(f)) {
+ this.propertyFilters.add(f);
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public ConfigurationContextBuilder removePropertyFilters(PropertyFilter... filters) {
+ return removePropertyFilters(Arrays.asList(filters));
+ }
+
+ @Override
+ public ConfigurationContextBuilder removePropertyFilters(Collection<PropertyFilter> filters) {
+ checkBuilderState();
+ this.propertyFilters.removeAll(filters);
+ return this;
+ }
+
+
+ @Override
+ public <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+ PropertyConverter<T>... converters) {
+ return removePropertyConverters(typeToConvert, Arrays.asList(converters));
+ }
+
+ @Override
+ public <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+ Collection<PropertyConverter<T>> converters) {
+ Collection<PropertyConverter<?>> subConverters = this.propertyConverters.get(typeToConvert);
+ if(subConverters!=null) {
+ subConverters.removeAll(converters);
+ }
+ return this;
+ }
+
+ @Override
+ public ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert) {
+ this.propertyConverters.remove(typeToConvert);
+ return this;
+ }
+
+
+ @Override
+ public ConfigurationContextBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy combinationPolicy){
+ checkBuilderState();
+ this.combinationPolicy = Objects.requireNonNull(combinationPolicy);
+ return this;
+ }
+
+
+ @Override
+ public <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> type, PropertyConverter<T>... propertyConverters){
+ checkBuilderState();
+ Objects.requireNonNull(type);
+ Objects.requireNonNull(propertyConverters);
+ Collection<PropertyConverter<?>> converters = this.propertyConverters.get(type);
+ if(converters==null){
+ converters = new ArrayList<>();
+ this.propertyConverters.put(type, converters);
+ }
+ for(PropertyConverter<T> propertyConverter:propertyConverters) {
+ if (!converters.contains(propertyConverter)) {
+ converters.add(propertyConverter);
+ } else {
+ LOG.warning("Converter ignored, already registered: " + propertyConverter);
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> type, Collection<PropertyConverter<T>> propertyConverters){
+ checkBuilderState();
+ Objects.requireNonNull(type);
+ Objects.requireNonNull(propertyConverters);
+ Collection<PropertyConverter<?>> converters = this.propertyConverters.get(type);
+ if(converters==null){
+ converters = new ArrayList<>();
+ this.propertyConverters.put(type, converters);
+ }
+ for(PropertyConverter<T> propertyConverter:propertyConverters) {
+ if (!converters.contains(propertyConverter)) {
+ converters.add(propertyConverter);
+ } else {
+ LOG.warning("Converter ignored, already registered: " + propertyConverter);
+ }
+ }
+ return this;
+ }
+
+ protected ConfigurationContextBuilder loadDefaults() {
+ checkBuilderState();
+ this.combinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+ loadDefaultPropertySources();
+ loadDefaultPropertyFilters();
+ loadDefaultPropertyConverters();
+ return this;
+ }
+
+
+ private Map<TypeLiteral, Collection<PropertyConverter>> getDefaultPropertyConverters() {
+ Map<TypeLiteral, Collection<PropertyConverter>> result = new HashMap<>();
+ for (PropertyConverter conv : ServiceContextManager.getServiceContext().getServices(
+ PropertyConverter.class)) {
+ TypeLiteral target = TypeLiteral.of(TypeLiteral.of(conv.getClass()).getType());
+ Collection<PropertyConverter> convList = result.get(target);
+ if (convList == null) {
+ convList = new ArrayList<>();
+ result.put(target, convList);
+ }
+ convList.add(conv);
+ }
+ return result;
+ }
+
+
+ /**
+ * Builds a new configuration based on the configuration of this builder instance.
+ *
+ * @return a new {@link Configuration configuration instance},
+ * never {@code null}.
+ */
+ @Override
+ public ConfigurationContext build() {
+ checkBuilderState();
+ built = true;
+ return new DefaultConfigurationContext(this);
+ }
+
+ @Override
+ public ConfigurationContextBuilder sortPropertyFilter(Comparator<PropertyFilter> comparator) {
+ Collections.sort(propertyFilters, comparator);
+ return this;
+ }
+
+ @Override
+ public ConfigurationContextBuilder sortPropertySources(Comparator<PropertySource> comparator) {
+ Collections.sort(propertySources, comparator);
+ return this;
+ }
+
+ private void checkBuilderState() {
+ if (built) {
+ throw new IllegalStateException("Configuration has already been build.");
+ }
+ }
+
+ @Override
+ public List<PropertyFilter> getPropertyFilters() {
+ return propertyFilters;
+ }
+
+ @Override
+ public Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> getPropertyConverter() {
+ return Collections.unmodifiableMap(this.propertyConverters);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/EnvironmentPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/EnvironmentPropertySource.java b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/EnvironmentPropertySource.java
new file mode 100644
index 0000000..dca8060
--- /dev/null
+++ b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/EnvironmentPropertySource.java
@@ -0,0 +1,102 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * This {@link PropertySource} provides all Properties which are set
+ * via
+ * {@code export myprop=myval} on UNIX Systems or
+ * {@code set myprop=myval} on Windows. You can disable this feature by setting {@code tamaya.envprops.disable}
+ * or {@code tamaya.defaults.disable}.
+ */
+public class EnvironmentPropertySource implements PropertySource {
+
+ private static final Logger LOG = Logger.getLogger(EnvironmentPropertySource.class.getName());
+
+ /**
+ * default ordinal for {@link org.apache.tamaya.core.propertysource.EnvironmentPropertySource}
+ */
+ public static final int DEFAULT_ORDINAL = 300;
+
+ private final boolean disabled = evaluateDisabled();
+
+ private boolean evaluateDisabled() {
+ String value = System.getProperty("tamaya.envprops.disable");
+ if(value==null){
+ value = System.getenv("tamaya.envprops.disable");
+ }
+ if(value==null){
+ value = System.getProperty("tamaya.defaults.disable");
+ }
+ if(value==null){
+ value = System.getenv("tamaya.defaults.disable");
+ }
+ if(value==null){
+ return false;
+ }
+ return value.isEmpty() || Boolean.parseBoolean(value);
+ }
+
+ @Override
+ public int getOrdinal() {
+ return DEFAULT_ORDINAL;
+ }
+
+ @Override
+ public String getName() {
+ if(disabled){
+ return "environment-properties(disabled)";
+ }
+ return "environment-properties";
+ }
+
+ @Override
+ public PropertyValue get(String key) {
+ if(disabled){
+ return null;
+ }
+ return PropertyValue.of(key, System.getenv(key), getName());
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ if(disabled){
+ return Collections.emptyMap();
+ }
+ Map<String, String> entries = new HashMap<>(System.getenv());
+ for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
+ entries.put("_" + entry.getKey() + ".source", getName());
+ }
+ return entries;
+ }
+
+ @Override
+ public boolean isScannable() {
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java
index 2be6313..1f1a2a9 100644
--- a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java
+++ b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java
@@ -1,20 +1,20 @@
/*
* 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
+ * 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
+ * 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.
+ * 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.spisupport;
@@ -24,24 +24,18 @@ import org.apache.tamaya.spi.ConversionContext;
import org.apache.tamaya.spi.PropertyConverter;
import org.apache.tamaya.spi.ServiceContextManager;
-import javax.annotation.Priority;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Level;
import java.util.logging.Logger;
/**
@@ -70,7 +64,7 @@ public class PropertyConverterManager {
@Override
public int compare(Object o1, Object o2) {
- int prio = getPriority(o1) - getPriority(o2);
+ int prio = PriorityServiceComparator.getPriority(o1) - PriorityServiceComparator.getPriority(o2);
if (prio < 0) {
return 1;
} else if (prio > 0) {
@@ -82,21 +76,6 @@ public class PropertyConverterManager {
};
/**
- * Checks the given instance for a @Priority annotation. If present the annotation's value s evaluated. If no such
- * annotation is present, a default priority is returned (1);
- * @param o the instance, not null.
- * @return a priority, by default 1.
- */
- public static int getPriority(Object o){
- int prio = 1;
- Priority priority = o.getClass().getAnnotation(Priority.class);
- if (priority != null) {
- prio = priority.value();
- }
- return prio;
- }
-
- /**
* Constructor.
*/
public PropertyConverterManager() {
@@ -132,11 +111,16 @@ public class PropertyConverterManager {
try {
writeLock.lock();
List converters = List.class.cast(this.converters.get(targetType));
+ if(converters!=null && converters.contains(converter)){
+ return;
+ }
List<PropertyConverter<?>> newConverters = new ArrayList<>();
if (converters != null) {
newConverters.addAll(converters);
}
- newConverters.add(converter);
+ if(!newConverters.contains(converter)) {
+ newConverters.add(converter);
+ }
Collections.sort(newConverters, PRIORITY_COMPARATOR);
this.converters.put(targetType, Collections.unmodifiableList(newConverters));
// evaluate transitive closure for all inherited supertypes and implemented interfaces
@@ -185,8 +169,7 @@ public class PropertyConverterManager {
* @return true, if a converter for the given type is registered, or a default one can be created.
*/
public boolean isTargetTypeSupported(TypeLiteral<?> targetType) {
- return converters.containsKey(targetType) || transitiveConverters.containsKey(targetType)
- || createDefaultPropertyConverter(targetType) != null;
+ return converters.containsKey(targetType) || transitiveConverters.containsKey(targetType) || createDefaultPropertyConverter(targetType) != null;
}
/**
@@ -211,29 +194,25 @@ public class PropertyConverterManager {
* Get the list of all current registered converters for the given target type.
* If not converters are registered, they component tries to create and register a dynamic
* converter based on String costructor or static factory methods available.
- *
- * <p>The converters provided are of the following type and returned in the following order:</p>
- *
+ * The converters provided are of the following type and returned in the following order:
* <ul>
- * <li>Converters mapped explicitly to the required target type are returned first, ordered
- * by decreasing priority. This means, if explicit converters are registered these are used
- * primarly for converting a value.</li>
- * <li>The target type of each explicitly registered converter also can be transitively mapped to
- * 1) all directly implemented interfaces, 2) all its superclasses (except Object), 3) all the interfaces
- * implemented by its superclasses. These groups of transitive converters is returned similarly in the
- * order as mentioned, whereas also here a priority based decreasing ordering is applied.</li>
- * <li>java.lang wrapper classes and native types are automatically mapped.</li>
- * <li>If no explicit converters are registered, for Enum types a default implementation is provided that
- * compares the configuration values with the different enum members defined (cases sensitive mapping).</li>
+ * <li>Converters mapped explicitly to the required target type are returned first, ordered
+ * by decreasing priority. This means, if explicit converters are registered these are used
+ * primarly for converting a value.</li>
+ * <li>The target type of each explicitly registered converter also can be transitively mapped to
+ * 1) all directly implemented interfaces, 2) all its superclasses (except Object), 3) all the interfaces
+ * implemented by its superclasses. These groups of transitive converters is returned similarly in the
+ * order as mentioned, whereas also here a priority based decreasing ordering is applied.</li>
+ * <li>java.lang wrapper classes and native types are automatically mapped.</li>
+ * <li>If no explicit converters are registered, for Enum types a default implementation is provided that
+ * compares the configuration values with the different enum members defined (cases sensitive mapping).</li>
* </ul>
- *
- *
+ * <p>
* So given that list above directly registered mappings always are tried first, before any transitive mapping
* should be used. Also in all cases @Priority annotations are honored for ordering of the converters in place.
* Transitive conversion is supported for all directly implemented interfaces (including inherited ones) and
* the inheritance hierarchy (exception Object). Superinterfaces of implemented interfaces are ignored.
*
- *
* @param targetType the target type, not null.
* @param <T> the type class
* @return the ordered list of converters (may be empty for not convertible types).
@@ -246,55 +225,58 @@ public class PropertyConverterManager {
// direct mapped converters
try {
readLock.lock();
- converters = List.class.cast(this.converters.get(targetType));
- } finally {
- readLock.unlock();
- }
- if (converters != null) {
- converterList.addAll(converters);
- }
- // transitive converter
- try {
- readLock.lock();
- converters = List.class.cast(this.transitiveConverters.get(targetType));
+ addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList);
+ addConvertersToList(List.class.cast(this.transitiveConverters.get(targetType)), converterList);
} finally {
readLock.unlock();
}
- if (converters != null) {
- converterList.addAll(converters);
- }
- // handling of java.ui.lang wrapper classes
+ // handling of java.lang wrapper classes
TypeLiteral<T> boxedType = mapBoxedType(targetType);
if (boxedType != null) {
try {
readLock.lock();
- converters = List.class.cast(this.converters.get(boxedType));
+ addConvertersToList(List.class.cast(this.converters.get(boxedType)), converterList);
} finally {
readLock.unlock();
}
- if (converters != null) {
- converterList.addAll(converters);
- }
}
- if (converterList.isEmpty()) {
+ if (converterList.isEmpty() && !TypeLiteral.of(String.class).equals(targetType)) {
// adding any converters created on the fly, e.g. for enum types.
PropertyConverter<T> defaultConverter = createDefaultPropertyConverter(targetType);
if (defaultConverter != null) {
register(targetType, defaultConverter);
try {
readLock.lock();
- converters = List.class.cast(this.converters.get(targetType));
+ addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList);
} finally {
readLock.unlock();
}
}
- if (converters != null) {
- converterList.addAll(converters);
+ }
+ // check for parametrized types, ignoring param type
+ // direct mapped converters
+ if(targetType.getType()!=null) {
+ try {
+ readLock.lock();
+ addConvertersToList(List.class.cast(this.converters.get(
+ TypeLiteral.of(targetType.getRawType()))), converterList);
+ } finally {
+ readLock.unlock();
}
}
return converterList;
}
+ private <T> void addConvertersToList(Collection<PropertyConverter<T>> converters, List<PropertyConverter<T>> converterList) {
+ if (converters != null) {
+ for(PropertyConverter<T> conv:converters) {
+ if(!converterList.contains(conv)) {
+ converterList.add(conv);
+ }
+ }
+ }
+ }
+
/**
* Maps native types to the corresponding boxed types.
*
@@ -302,7 +284,6 @@ public class PropertyConverterManager {
* @param <T> the type
* @return the boxed type, or null.
*/
- @SuppressWarnings("all")
private <T> TypeLiteral<T> mapBoxedType(TypeLiteral<T> targetType) {
Type parameterType = targetType.getType();
if (parameterType == int.class) {
@@ -370,46 +351,40 @@ public class PropertyConverterManager {
PropertyConverter<T> converter = null;
final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "valueOf", "instanceOf", "getInstance", "from", "fromString", "parse");
if (factoryMethod != null) {
+ converter = new DefaultPropertyConverter<>(factoryMethod, targetType.getRawType());
+ }
+ if (converter == null) {
+ final Constructor<T> constr;
+ try {
+ constr = targetType.getRawType().getDeclaredConstructor(String.class);
+ } catch (NoSuchMethodException e) {
+ LOG.log(Level.FINEST, "No matching constrctor for " + targetType, e);
+ return null;
+ }
converter = new PropertyConverter<T>() {
- @Override
- public T convert(String value, ConversionContext context) {
- try {
- if (!Modifier.isStatic(factoryMethod.getModifiers())) {
- throw new ConfigException(factoryMethod.toGenericString() +
- " is not a static method. Only static " +
- "methods can be used as factory methods.");
- }
+ @Override
+ public T convert(String value, ConversionContext context) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
public Object run() {
- factoryMethod.setAccessible(true);
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ constr.setAccessible(true);
+ return null;
+ }
+ });
return null;
}
});
- Object invoke = factoryMethod.invoke(null, value);
- return targetType.getRawType().cast(invoke);
- } catch (Exception e) {
- throw new ConfigException("Failed to decode '" + value + "'", e);
- }
- }
- };
- }
- if (converter == null) {
- try {
- final Constructor<T> constr = targetType.getRawType().getDeclaredConstructor(String.class);
- converter = new PropertyConverter<T>() {
- @Override
- public T convert(String value, ConversionContext context) {
try {
- constr.setAccessible(true);
return constr.newInstance(value);
} catch (Exception e) {
- throw new ConfigException("Failed to decode '" + value + "'", e);
+ LOG.log(Level.SEVERE, "Error creating new PropertyConverter instance " + targetType, e);
}
+ return null;
}
};
- } catch (Exception e) {
- LOG.finest("Failed to construct instance of type: " + targetType.getRawType().getName() + ": " + e);
- }
}
return converter;
}
@@ -434,4 +409,61 @@ public class PropertyConverterManager {
return null;
}
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof PropertyConverterManager)) {
+ return false;
+ }
+ PropertyConverterManager that = (PropertyConverterManager) o;
+ return converters.equals(that.converters);
+
+ }
+
+ @Override
+ public int hashCode() {
+ return converters.hashCode();
+ }
+
+ /**
+ * Default converter im��ementation perfoming several lookups for String converion
+ * option.
+ * @param <T>
+ */
+ private static class DefaultPropertyConverter<T> implements PropertyConverter<T> {
+
+ private final Method factoryMethod;
+ private final Class<T> targetType;
+
+ DefaultPropertyConverter(Method factoryMethod, Class<T> targetType){
+ this.factoryMethod = Objects.requireNonNull(factoryMethod);
+ this.targetType = Objects.requireNonNull(targetType);
+ }
+
+ @Override
+ public T convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(), "<String -> "+factoryMethod.toGenericString());
+
+ if (!Modifier.isStatic(factoryMethod.getModifiers())) {
+ throw new ConfigException(factoryMethod.toGenericString() +
+ " is not a static method. Only static " +
+ "methods can be used as factory methods.");
+ }
+ try {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ factoryMethod.setAccessible(true);
+ return null;
+ }
+ });
+ Object invoke = factoryMethod.invoke(null, value);
+ return targetType.cast(invoke);
+ } catch (Exception e) {
+ throw new ConfigException("Failed to decode '" + value + "'", e);
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java
new file mode 100644
index 0000000..a7a5c66
--- /dev/null
+++ b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java
@@ -0,0 +1,60 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.spi.PropertyFilter;
+
+import javax.annotation.Priority;
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * Comparator for PropertyFilters based on their priority annotations.
+ */
+public class PropertyFilterComparator implements Comparator<PropertyFilter>, Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Compare 2 filters for ordering the filter chain.
+ *
+ * @param filter1 the first filter
+ * @param filter2 the second filter
+ * @return the comparison result
+ */
+ private int comparePropertyFilters(PropertyFilter filter1, PropertyFilter filter2) {
+ Priority prio1 = filter1.getClass().getAnnotation(Priority.class);
+ Priority prio2 = filter2.getClass().getAnnotation(Priority.class);
+ int ord1 = prio1 != null ? prio1.value() : 0;
+ int ord2 = prio2 != null ? prio2.value() : 0;
+
+ if (ord1 < ord2) {
+ return -1;
+ } else if (ord1 > ord2) {
+ return 1;
+ } else {
+ return filter1.getClass().getName().compareTo(filter2.getClass().getName());
+ }
+ }
+
+ @Override
+ public int compare(PropertyFilter filter1, PropertyFilter filter2) {
+ return comparePropertyFilters(filter1, filter2);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterManager.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterManager.java b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterManager.java
new file mode 100644
index 0000000..611722a
--- /dev/null
+++ b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/PropertyFilterManager.java
@@ -0,0 +1,131 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.FilterContext;
+import org.apache.tamaya.spi.PropertyFilter;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of the Configuration API. This class uses the current {@link ConfigurationContext} to evaluate the
+ * chain of {@link org.apache.tamaya.spi.PropertySource} and {@link PropertyFilter}
+ * instance to evaluate the current Configuration.
+ */
+public final class PropertyFilterManager {
+ /**
+ * The logger.
+ */
+ private static final Logger LOG = Logger.getLogger(PropertyFilterManager.class.getName());
+ /**
+ * The maximal number of filter cycles performed before aborting.
+ */
+ private static final int MAX_FILTER_LOOPS = 10;
+
+ /**
+ * Private singleton constructor.
+ */
+ private PropertyFilterManager(){}
+
+ public static String applyFilter(String key, Map<String,String> configData, ConfigurationContext configurationContext) {
+ // Apply filters to values, prevent values filtered to null!
+ String unfilteredValue = configData.get(key);
+ for (int i = 0; i < MAX_FILTER_LOOPS; i++) {
+ boolean changed = false;
+ // Apply filters to values, prevent values filtered to null!
+ for (PropertyFilter filter : configurationContext.getPropertyFilters()) {
+ String newValue = filter.filterProperty(unfilteredValue, new FilterContext(key, configData, true));
+ if (newValue != null && !newValue.equals(unfilteredValue)) {
+ changed = true;
+ if (LOG.isLoggable(Level.FINEST)) {
+ LOG.finest("Filter - " + key + ": " + unfilteredValue + " -> " + newValue + " by " + filter);
+ }
+ } else if (unfilteredValue != null && !unfilteredValue.equals(newValue)) {
+ changed = true;
+ if (LOG.isLoggable(Level.FINEST)) {
+ LOG.finest("Filter - " + key + ": " + unfilteredValue + " -> " + newValue + " by " + filter);
+ }
+ }
+ unfilteredValue = newValue;
+ }
+ if (!changed) {
+ LOG.finest("Finishing filter loop, no changes detected.");
+ break;
+ } else {
+ if (i == (MAX_FILTER_LOOPS - 1)) {
+ if (LOG.isLoggable(Level.WARNING)) {
+ LOG.warning("Maximal filter loop count reached, aborting filter evaluation after cycles: " + i);
+ }
+ } else {
+ LOG.finest("Repeating filter loop, changes detected.");
+ }
+ }
+ }
+ return unfilteredValue;
+ }
+
+ public static Map<String, String> applyFilters(Map<String, String> inputMap, ConfigurationContext configurationContext) {
+ Map<String, String> resultMap = new HashMap<>(inputMap);
+ // Apply filters to values, prevent values filtered to null!
+ for (int i = 0; i < MAX_FILTER_LOOPS; i++) {
+ AtomicInteger changes = new AtomicInteger();
+ for (PropertyFilter filter : configurationContext.getPropertyFilters()) {
+ for (Map.Entry<String, String> entry : inputMap.entrySet()) {
+ final String k = entry.getKey();
+ final String v = entry.getValue();
+
+ String newValue = filter.filterProperty(v, new FilterContext(k, inputMap, false));
+ if (newValue != null && !newValue.equals(v)) {
+ changes.incrementAndGet();
+ LOG.finest("Filter - " + k + ": " + v + " -> " + newValue + " by " + filter);
+ } else if (v != null && !v.equals(newValue)) {
+ changes.incrementAndGet();
+ LOG.finest("Filter - " + k + ": " + v + " -> " + newValue + " by " + filter);
+ }
+ // Remove null values
+ if (null != newValue) {
+ resultMap.put(k, newValue);
+ }else{
+ resultMap.remove(k);
+ }
+ }
+ }
+ if (changes.get() == 0) {
+ LOG.finest("Finishing filter loop, no changes detected.");
+ break;
+ } else {
+ if (i == (MAX_FILTER_LOOPS - 1)) {
+ if (LOG.isLoggable(Level.WARNING)) {
+ LOG.warning("Maximal filter loop count reached, aborting filter evaluation after cycles: " + i);
+ }
+ } else {
+ LOG.finest("Repeating filter loop, changes detected: " + changes.get());
+ }
+ changes.set(0);
+ }
+ }
+ return resultMap;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/SimplePropertySource.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/SimplePropertySource.java b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/SimplePropertySource.java
new file mode 100644
index 0000000..6c15e35
--- /dev/null
+++ b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/SimplePropertySource.java
@@ -0,0 +1,151 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.ConfigException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+/**
+ * Simple implementation of a {@link org.apache.tamaya.spi.PropertySource} for
+ * simple property files and XML property files.
+ */
+public class SimplePropertySource extends BasePropertySource {
+
+ private static final Logger LOG = Logger.getLogger(SimplePropertySource.class.getName());
+
+ /**
+ * The property source name.
+ */
+ private String name;
+
+ /**
+ * The current properties.
+ */
+ private Map<String, String> properties;
+
+ /**
+ * Creates a new Properties based PropertySource based on the given URL.
+ *
+ * @param propertiesLocation the URL encoded location, not null.
+ */
+ public SimplePropertySource(File propertiesLocation) {
+ super(0);
+ try {
+ this.name = propertiesLocation.toString();
+ this.properties = load(propertiesLocation.toURI().toURL());
+ } catch (IOException e) {
+ throw new ConfigException("Failed to load properties from " + propertiesLocation, e);
+ }
+ }
+
+ /**
+ * Creates a new Properties based PropertySource based on the given URL.
+ *
+ * @param propertiesLocation the URL encoded location, not null.
+ */
+ public SimplePropertySource(URL propertiesLocation) {
+ super(0);
+ this.properties = load(Objects.requireNonNull(propertiesLocation));
+ this.name = propertiesLocation.toString();
+ }
+
+ /**
+ * Creates a new Properties based PropertySource based on the given properties map.
+ *
+ * @param name the name, not null.
+ * @param properties the properties, not null.
+ */
+ public SimplePropertySource(String name, Map<String, String> properties) {
+ super(0);
+ this.properties = new HashMap<>(properties);
+ this.name = Objects.requireNonNull(name);
+ }
+
+ /**
+ * Creates a new Properties based PropertySource based on the given URL.
+ *
+ * @param name The property source name
+ * @param propertiesLocation the URL encoded location, not null.
+ */
+ public SimplePropertySource(String name, URL propertiesLocation) {
+ super(0);
+ this.properties = load(propertiesLocation);
+ this.name = Objects.requireNonNull(name);
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return this.properties;
+ }
+
+ /**
+ * loads the Properties from the given URL
+ *
+ * @param propertiesFile {@link URL} to load Properties from
+ * @return loaded {@link Properties}
+ * @throws IllegalStateException in case of an error while reading properties-file
+ */
+ private Map<String, String> load(URL propertiesFile) {
+ boolean isXML = isXMLPropertieFiles(propertiesFile);
+
+ Map<String, String> properties = new HashMap<>();
+ try (InputStream stream = propertiesFile.openStream()) {
+ Properties props = new Properties();
+ if (stream != null) {
+ if (isXML) {
+ props.loadFromXML(stream);
+ } else {
+ props.load(stream);
+ }
+ }
+
+ for (String key : props.stringPropertyNames()) {
+ properties.put(key, props.getProperty(key));
+ if (getName() == null){
+ LOG.warning("No property source name found for " + this +", ommitting source meta-entries.");
+ } else {
+ properties.put("_" + key + ".source", getName());
+ }
+ }
+ } catch (IOException e) {
+ throw new ConfigException("Error loading properties from " + propertiesFile, e);
+ }
+
+ return properties;
+ }
+
+ private boolean isXMLPropertieFiles(URL url) {
+ return url.getFile().endsWith(".xml");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/SystemPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/SystemPropertySource.java b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/SystemPropertySource.java
new file mode 100644
index 0000000..5f48738
--- /dev/null
+++ b/modules/spi-support/src/main/java/org/apache/tamaya/spisupport/SystemPropertySource.java
@@ -0,0 +1,125 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * This {@link PropertySource} manages the system properties. You can disable this feature by
+ * setting {@code tamaya.envprops.disable} or {@code tamaya.defaults.disable}.
+ */
+public class SystemPropertySource implements PropertySource {
+
+ /**
+ * default ordinal for {@link org.apache.tamaya.core.propertysource.SystemPropertySource}
+ */
+ public static final int DEFAULT_ORDINAL = 1000;
+
+ private volatile Map<String,String> cachedProperties;
+
+ /**
+ * previous System.getProperties().hashCode()
+ * so we can check if we need to reload
+ */
+ private int previousHash;
+
+ private final boolean disabled = evaluateDisabled();
+
+ private boolean evaluateDisabled() {
+ String value = System.getProperty("tamaya.sysprops.disable");
+ if(value==null){
+ value = System.getenv("tamaya.sysprops.disable");
+ }
+ if(value==null){
+ value = System.getProperty("tamaya.defaults.disable");
+ }
+ if(value==null){
+ value = System.getenv("tamaya.defaults.disable");
+ }
+ if(value==null){
+ return false;
+ }
+ return value.isEmpty() || Boolean.parseBoolean(value);
+ }
+
+
+
+ public SystemPropertySource() {
+ cachedProperties = loadProperties();
+ previousHash = System.getProperties().hashCode();
+ }
+
+ private Map<String, String> loadProperties() {
+ Map<String,String> props = new HashMap<>();
+ Properties sysProps = System.getProperties();
+ for(String name: sysProps.stringPropertyNames()) {
+ props.put(name,sysProps.getProperty(name));
+ props.put("_"+name+".source",getName());
+ }
+ return props;
+ }
+
+ @Override
+ public int getOrdinal() {
+ return DEFAULT_ORDINAL;
+ }
+
+ @Override
+ public String getName() {
+ if(disabled){
+ return "system-properties(disabled)";
+ }
+ return "system-properties";
+ }
+
+ @Override
+ public PropertyValue get(String key) {
+ if(disabled){
+ return null;
+ }
+ return PropertyValue.of(key, System.getProperty(key), getName());
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ if(disabled){
+ return Collections.emptyMap();
+ }
+ // only need to reload and fill our map if something has changed
+ // synchronization was removed, Instance was marked as volatile. In the worst case it
+ // is reloaded twice, but the values will be the same.
+ if (previousHash != System.getProperties().hashCode()) {
+ Map<String, String> properties = loadProperties();
+ this.cachedProperties = Collections.unmodifiableMap(properties);
+ previousHash = System.getProperties().hashCode();
+ }
+ return this.cachedProperties;
+ }
+
+ @Override
+ public boolean isScannable() {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/A.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/A.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/A.java
new file mode 100644
index 0000000..4101f1e
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/A.java
@@ -0,0 +1,29 @@
+/*
+ * 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.spisupport;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+class A implements AutoCloseable{
+ @Override
+ public void close() throws Exception {
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/3aca9112/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/B.java
----------------------------------------------------------------------
diff --git a/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/B.java b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/B.java
new file mode 100644
index 0000000..584b923
--- /dev/null
+++ b/modules/spi-support/src/test/java/org/apache/tamaya/spisupport/B.java
@@ -0,0 +1,29 @@
+/*
+ * 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.spisupport;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+public class B extends A implements Runnable{
+ @Override
+ public void run() {
+
+ }
+}
[09/15] incubator-tamaya-extensions git commit: TAMAYA-189: Moved
format and injection modules into separate subtrees.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/yaml/src/test/resources/configs/valid/test-with-prio.yaml
----------------------------------------------------------------------
diff --git a/modules/formats/yaml/src/test/resources/configs/valid/test-with-prio.yaml b/modules/formats/yaml/src/test/resources/configs/valid/test-with-prio.yaml
new file mode 100644
index 0000000..05b5dbf
--- /dev/null
+++ b/modules/formats/yaml/src/test/resources/configs/valid/test-with-prio.yaml
@@ -0,0 +1,39 @@
+#
+# 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 current 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.
+#
+version: 1.0
+released: 2012-11-30
+
+# tamaya specifics...
+tamaya:
+ ordinal: 16784
+
+# Connection parameters
+connection:
+ url: jdbc:mysql://localhost:3306/db
+ poolSize: 5
+
+# Protocols
+protocols:
+ - http
+ - https
+
+# Users
+users:
+ tom: passwd
+ bob: passwd
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/yaml/src/test/resources/configs/valid/test.yaml
----------------------------------------------------------------------
diff --git a/modules/formats/yaml/src/test/resources/configs/valid/test.yaml b/modules/formats/yaml/src/test/resources/configs/valid/test.yaml
new file mode 100644
index 0000000..697e9f3
--- /dev/null
+++ b/modules/formats/yaml/src/test/resources/configs/valid/test.yaml
@@ -0,0 +1,35 @@
+#
+# 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 current 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.
+#
+version: 1.0
+released: 2012-11-30
+
+# Connection parameters
+connection:
+ url: jdbc:mysql://localhost:3306/db
+ poolSize: 5
+
+# Protocols
+protocols:
+ - http
+ - https
+
+# Users
+users:
+ tom: passwd
+ bob: passwd
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/pom.xml
----------------------------------------------------------------------
diff --git a/modules/injection-api/pom.xml b/modules/injection-api/pom.xml
deleted file mode 100644
index 8db431e..0000000
--- a/modules/injection-api/pom.xml
+++ /dev/null
@@ -1,81 +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 current 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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.tamaya.ext</groupId>
- <artifactId>tamaya-extensions</artifactId>
- <version>0.3-incubating-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>tamaya-injection-api</artifactId>
- <name>Apache Tamaya Injection Support API</name>
- <packaging>bundle</packaging>
-
- <properties>
- <jdkVersion>1.7</jdkVersion>
- <geronimo-atinject-1.0-spec.version>1.0</geronimo-atinject-1.0-spec.version>
- <geronimo-jcdi-1.1-spec.version>1.0</geronimo-jcdi-1.1-spec.version>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.tamaya</groupId>
- <artifactId>tamaya-api</artifactId>
- <version>${project.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-atinject_1.0_spec</artifactId>
- <version>${geronimo-atinject-1.0-spec.version}</version>
- <scope>provided</scope>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-jcdi_1.1_spec</artifactId>
- <version>${geronimo-jcdi-1.1-spec.version}</version>
- <scope>provided</scope>
- <optional>true</optional>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>
- org.apache.tamaya.inject.api,
- org.apache.tamaya.inject.spi
- </Export-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/BaseDynamicValue.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/BaseDynamicValue.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/BaseDynamicValue.java
deleted file mode 100644
index 2f8c559..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/BaseDynamicValue.java
+++ /dev/null
@@ -1,125 +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.inject.api;
-
-
-import java.io.Serializable;
-
-/**
- * <p>A accessor for a single configured value. This can be used to support values that may change during runtime,
- * reconfigured or final. Hereby external code (could be Tamaya configuration listners or client code), can set a
- * new value. Depending on the {@link UpdatePolicy} the new value is immedeately active or it requires an active commit
- * by client code. Similarly an instance also can ignore all later changes to the value.</p>
- *
- * <p>Types of this interface can be used as injection targets in injected beans or as template resiult on configuration
- * templates.</p>
- *
- * <h3>Implementation Specification</h3>
- * Implementation of this interface must be
- * <ul>
- * <li>Serializable, when also the item stored is serializable</li>
- * <li>Thread safe</li>
- * </ul>
- *
- * @param <T> The type of the value.
- */
-public abstract class BaseDynamicValue<T> implements DynamicValue<T>, Serializable {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * Performs a commit, if necessary, and returns the current value.
- *
- * @return the non-null value held by this {@code DynamicValue}
- * @throws org.apache.tamaya.ConfigException if there is no value present
- * @see DynamicValue#isPresent()
- */
- public T commitAndGet() {
- commit();
- return get();
- }
-
- /**
- * Return {@code true} if there is a value present, otherwise {@code false}.
- *
- * @return {@code true} if there is a value present, otherwise {@code false}
- */
- public boolean isPresent() {
- return get() != null;
- }
-
-
- /**
- * Return the value if present, otherwise return {@code other}.
- *
- * @param other the value to be returned if there is no value present, may
- * be null
- * @return the value, if present, otherwise {@code other}
- */
- public T orElse(T other) {
- T value = get();
- if (value == null) {
- return other;
- }
- return value;
- }
-
- /**
- * Return the value if present, otherwise invoke {@code other} and return
- * the result of that invocation.
- *
- * @param other a {@code ConfiguredItemSupplier} whose result is returned if no value
- * is present
- * @return the value if present otherwise the result of {@code other.get()}
- * @throws NullPointerException if value is not present and {@code other} is
- * null
- */
- public T orElseGet(ConfiguredItemSupplier<? extends T> other) {
- T value = get();
- if (value == null) {
- return other.get();
- }
- return value;
- }
-
- /**
- * Return the contained value, if present, otherwise throw an exception
- * to be created by the provided supplier.
- * <p>
- * NOTE A method reference to the exception constructor with an empty
- * argument list can be used as the supplier. For example,
- * {@code IllegalStateException::new}
- *
- * @param <X> Type of the exception to be thrown
- * @param exceptionSupplier The supplier which will return the exception to
- * be thrown
- * @return the present value
- * @throws X if there is no value present
- * @throws NullPointerException if no value is present and
- * {@code exceptionSupplier} is null
- */
- public <X extends Throwable> T orElseThrow(ConfiguredItemSupplier<? extends X> exceptionSupplier) throws X {
- T value = get();
- if (value == null) {
- throw exceptionSupplier.get();
- }
- return value;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/Config.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/Config.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/Config.java
deleted file mode 100644
index 2484934..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/Config.java
+++ /dev/null
@@ -1,93 +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.inject.api;
-
-
-import javax.enterprise.util.Nonbinding;
-import javax.inject.Qualifier;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** todo The author of this should fix this invalid Javadoc. Oliver B. Fischer, 2015-12-27 */
-///**
-// * Annotation to enable injection current a configured property or define the returned data for
-// * a configuration template method. Hereby this annotation can be used in multiple ways and combined
-// * with other annotations such as {@link ConfigDefault}, {@link WithConfigOperator}, {@link WithPropertyConverter}.
-// *
-// * Below the most simple variant current a configured class is given:
-// * {@code
-// * pubic class ConfiguredItem{
-// *
-// * @ConfiguredProperty
-// * private String aValue;
-// * }
-// * When this class is configured, e.g. by passing it to {@link org.apache.tamaya.Configuration#configure(Object)},
-// * the following is happening:
-// * <ul>
-// * <li>The current valid Configuration is evaluated by calling {@code Configuration cfg = ConfigurationProvider.getConfiguration();}</li>
-// * <li>The current possible property keys are evaluated by calling {@code cfg.get("aValue");}</li>
-// * <li>if not successful, and a @ConfigDefault annotation is present, the default value is used.
-// * <li>If no value could be evaluated a ({@link org.apache.tamaya.ConfigException} is thrown.</li>
-// * <li>On success, since no type conversion is involved, the value is injected.</li>
-// * </ul>
-// *
-// * In the next example we explicitly define the property keys:
-// * {@code
-// * @ConfigDefaultSections("section1")
-// * pubic class ConfiguredItem{
-// *
-// * @ConfiguredProperty({"b", "[a.b.deprecated.keys]", "a"})
-// * @ConfigDefault("myDefaultValue")
-// * private String aValue;
-// * }
-// *
-// * Within this example we evaluate multiple possible keys (section1.b, a.b.deprecated.keys, section1.a). Evaluation is
-// * aborted if a key could be successfully resolved. Hereby the ordering current the annotations define the ordering
-// * current resolution, so in the example above
-// * resolution equals to {@code "section1.b", "a.b.deprecated.keys", "section1.a"}. If no value has bee found,
-// * the configured default {@code myDefaultValue} is returned.
-// */
-@Qualifier
-@Retention(RetentionPolicy.RUNTIME)
-@Target(value = { ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
-public @interface Config {
-
- /**
- * Get the property names to be used. Hereby the first non null keys evaluated is injected as property keys.
- *
- * @return the property names, not null. If missing the field or method name being injected is used by default.
- */
- @Nonbinding
- String[] value() default {};
-
- /**
- * The default value to be injected, if none of the configuration keys could be resolved. If no key has been
- * resolved and no default value is defined, it is handled as a deployment error. Depending on the extension loaded
- * default values can be fixed Strings or even themselves resolvable. For typed configuration of type T entries
- * that are not Strings the default value must be a valid input to the corresponding
- * {@link org.apache.tamaya.spi.PropertyConverter}.
- *
- * @return default value used in case resolution fails.
- */
- @Nonbinding
- String defaultValue() default "";
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigAutoInject.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigAutoInject.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigAutoInject.java
deleted file mode 100644
index 1ed659e..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigAutoInject.java
+++ /dev/null
@@ -1,36 +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.inject.api;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation to control injection of a configured bean. The configuration keys
- * to be resolved are basically determined by the {@link Config}
- * annotation(s). When this annotation is added the injection systems tries to inject all
- * fields found, also including fields not annotated with {@code @ConfigProperty}.
- * Fields not to be injected ccan be annotated with {@code @NoConfig} to exclude them
- * being eleceted for injection.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(value = { ElementType.TYPE })
-public @interface ConfigAutoInject {}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigDefaultSections.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigDefaultSections.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigDefaultSections.java
deleted file mode 100644
index 2037de6..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfigDefaultSections.java
+++ /dev/null
@@ -1,44 +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.inject.api;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** todo The author of this should fix this invalid Javadoc. Oliver B. Fischer, 2015-12-27 */
-///**
-// * Annotation to control injection and resolution current a configured bean. The configuration keys
-// * to be resolved are basically determined by the {@link org.apache.tamaya.inject.ConfigProperty}
-// * annotation(s). Nevertheless these annotations can also have relative key names. This annotation allows
-// * to define a configuration area that is prefixed to all relative configuration keys within the
-// * corresponding class/template interface.
-// */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(value = { ElementType.TYPE })
-public @interface ConfigDefaultSections {
-
- /**
- * Allows to declare an section names that are prepended to resolve relative configuration keys.
- * @return the section names to used for key resolution.
- */
- String[] value() default {};
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfiguredItemSupplier.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfiguredItemSupplier.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfiguredItemSupplier.java
deleted file mode 100644
index 5e57121..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/ConfiguredItemSupplier.java
+++ /dev/null
@@ -1,41 +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.inject.api;
-
-/**
- * Represents a supplier of results.
- *
- * There is no requirement that a new or distinct result be returned each
- * time the supplier is invoked.
- *
- * This is a functional interface,
- * whose functional method is {@link #get()}.
- *
- * @param <T> the type of results supplied by this supplier
- */
-//@FunctionalInterface
-public interface ConfiguredItemSupplier<T> {
-
- /**
- * Gets a result.
- *
- * @return a result
- */
- T get();
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/DynamicValue.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/DynamicValue.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/DynamicValue.java
deleted file mode 100644
index 4cc29da..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/DynamicValue.java
+++ /dev/null
@@ -1,161 +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.inject.api;
-
-import java.beans.PropertyChangeListener;
-
-
-/**
- * <p>A accessor for a single configured value. This can be used to support values that may change during runtime,
- * reconfigured or final. Hereby external code (could be Tamaya configuration listners or client code), can set a
- * new value. Depending on the {@link UpdatePolicy} the new value is immedeately active or it requires an active commit
- * by client code. Similarly an instance also can ignore all later changes to the value.</p>
- *
- * <p>Types of this interface can be used as injection targets in injected beans or as template resiult on configuration
- * templates.</p>
- *
- * <h3>Implementation Specification</h3>
- * Implementation of this interface must be
- * <ul>
- * <li>Serializable, when also the item stored is serializable</li>
- * <li>Thread safe</li>
- * </ul>
- *
- * @param <T> The type of the value.
- */
-public interface DynamicValue<T> {
-
- /**
- * Performs a commit, if necessary, and returns the current value.
- *
- * @return the non-null value held by this {@code DynamicValue}
- * @throws org.apache.tamaya.ConfigException if there is no value present
- *
- * @see DynamicValue#isPresent()
- */
- T commitAndGet();
-
- /**
- * Commits a new value that has not been committed yet, make it the new value of the instance. On change any
- * registered listeners will be triggered.
- */
- void commit();
-
- /**
- * Access the {@link UpdatePolicy} used for updating this value.
- * @return the update policy, never null.
- */
- UpdatePolicy getUpdatePolicy();
-
- /**
- * Add a listener to be called as weak reference, when this value has been changed.
- * @param l the listener, not null
- */
- void addListener(PropertyChangeListener l);
-
- /**
- * Removes a listener to be called, when this value has been changed.
- * @param l the listner to be removed, not null
- */
- void removeListener(PropertyChangeListener l);
-
- /**
- * If a value is present in this {@code DynamicValue}, returns the value,
- * otherwise throws {@code ConfigException}.
- *
- * @return the non-null value held by this {@code Optional}
- * @throws org.apache.tamaya.ConfigException if there is no value present
- *
- * @see DynamicValue#isPresent()
- */
- T get();
-
- /**
- * Method to check for and apply a new value. Depending on the {@link UpdatePolicy}
- * the value is immediately or deferred visible (or it may even be ignored completely).
- * @return true, if a new value has been detected. The value may not be visible depending on the current
- * {@link UpdatePolicy} in place.
- */
- boolean updateValue();
-
- /**
- * Evaluates the current value dynamically from the underlying configuration.
- * @return the current actual value, or null.
- */
- T evaluateValue();
-
- /**
- * Sets a new {@link UpdatePolicy}.
- * @param updatePolicy the new policy, not null.
- */
- void setUpdatePolicy(UpdatePolicy updatePolicy);
-
- /**
- * Access a new value that has not yet been committed.
- * @return the uncommitted new value, or null.
- */
- T getNewValue();
-
- /**
- * Return {@code true} if there is a value present, otherwise {@code false}.
- *
- * @return {@code true} if there is a value present, otherwise {@code false}
- */
- boolean isPresent();
-
- /**
- * Return the value if present, otherwise return {@code other}.
- *
- * @param other the value to be returned if there is no value present, may
- * be null
- * @return the value, if present, otherwise {@code other}
- */
- T orElse(T other);
-
- /**
- * Return the value if present, otherwise invoke {@code other} and return
- * the result of that invocation.
- *
- * @param other a {@code ConfiguredItemSupplier} whose result is returned if no value
- * is present
- * @return the value if present otherwise the result of {@code other.get()}
- * @throws NullPointerException if value is not present and {@code other} is
- * null
- */
- T orElseGet(ConfiguredItemSupplier<? extends T> other);
-
- /**
- * Return the contained value, if present, otherwise throw an exception
- * to be created by the provided supplier.
- *
- * NOTE A method reference to the exception constructor with an empty
- * argument list can be used as the supplier. For example,
- * {@code IllegalStateException::new}
- *
- * @param <X> Type of the exception to be thrown
- * @param exceptionSupplier The supplier which will return the exception to
- * be thrown
- * @return the present value
- * @throws X if there is no value present
- * @throws NullPointerException if no value is present and
- * {@code exceptionSupplier} is null
- */
- <X extends Throwable> T orElseThrow(ConfiguredItemSupplier<? extends X> exceptionSupplier) throws X;
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/InjectionUtils.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/InjectionUtils.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/InjectionUtils.java
deleted file mode 100644
index a010e96..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/InjectionUtils.java
+++ /dev/null
@@ -1,127 +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.inject.api;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.ListIterator;
-
-/**
- * Utility class with several commonly used functions.
- */
-public final class InjectionUtils {
-
- private InjectionUtils(){}
-
-
- /**
- * Collects all keys to be be accessed as defined by any annotations of type
- * {@link ConfigDefaultSections}, {@link Config}.
- * @param field the (optionally) annotated field instance
- * @return the regarding key list to be accessed fomr the {@link org.apache.tamaya.Configuration}.
- */
- public static List<String> getKeys(Field field) {
- ConfigDefaultSections areasAnnot = field.getDeclaringClass().getAnnotation(ConfigDefaultSections.class);
- return InjectionUtils.evaluateKeys(field, areasAnnot, field.getAnnotation(Config.class));
- }
-
- /**
- * Collects all keys to be be accessed as defined by any annotations of type
- * {@link ConfigDefaultSections}, {@link Config}.
- * @param method the (optionally) annotated method instance
- * @return the regarding key list to be accessed fomr the {@link org.apache.tamaya.Configuration}.
- */
- public static List<String> getKeys(Method method) {
- ConfigDefaultSections areasAnnot = method.getDeclaringClass().getAnnotation(ConfigDefaultSections.class);
- return InjectionUtils.evaluateKeys(method, areasAnnot, method.getAnnotation(Config.class));
- }
-
- /**
- * Evaluates all absolute configuration keys based on the member name found.
- *
- * @param member member to analyze.
- * @param areasAnnot the (optional) annotation defining areas to be looked up.
- * @return the list of current keys in order how they should be processed/looked up.
- */
- public static List<String> evaluateKeys(Member member, ConfigDefaultSections areasAnnot) {
- List<String> keys = new ArrayList<>();
- String name = member.getName();
- String mainKey;
- if (name.startsWith("get") || name.startsWith("set")) {
- mainKey = Character.toLowerCase(name.charAt(3)) + name.substring(4);
- } else {
- mainKey = Character.toLowerCase(name.charAt(0)) + name.substring(1);
- }
- keys.add(mainKey);
- if (areasAnnot != null) {
- // Add prefixed entries, including absolute (root) entry for "" area keys.
- for (String area : areasAnnot.value()) {
- if (!area.isEmpty()) {
- keys.add(area + '.' + mainKey);
- }
- }
- } else { // add package name
- keys.add(member.getDeclaringClass().getName() + '.' + mainKey);
- keys.add(member.getDeclaringClass().getSimpleName() + '.' + mainKey);
- }
- return keys;
- }
-
- /**
- * Evaluates all absolute configuration keys based on the annotations found in a class.
- *
- * @param member member to analyze.
- * @param areasAnnot the (optional) annotation definining areas to be looked up.
- * @param propertyAnnotation the annotation on field/method level that may defined one or
- * several keys to be looked up (in absolute or relative form).
- * @return the list current keys in order how they should be processed/looked up.
- */
- public static List<String> evaluateKeys(Member member, ConfigDefaultSections areasAnnot, Config propertyAnnotation) {
- if(propertyAnnotation==null){
- return evaluateKeys(member, areasAnnot);
- }
- List<String> keys = new ArrayList<>(Arrays.asList(propertyAnnotation.value()));
- if (keys.isEmpty()) {
- keys.add(member.getName());
- }
- ListIterator<String> iterator = keys.listIterator();
- while (iterator.hasNext()) {
- String next = iterator.next();
- if (next.startsWith("[") && next.endsWith("]")) {
- // absolute key, strip away brackets, take key as is
- iterator.set(next.substring(1, next.length() - 1));
- } else {
- if (areasAnnot != null && areasAnnot.value().length>0) {
- // Remove original entry, since it will be replaced with prefixed entries
- iterator.remove();
- // Add prefixed entries, including absolute (root) entry for "" area keys.
- for (String area : areasAnnot.value()) {
- iterator.add(area.isEmpty() ? next : area + '.' + next);
- }
- }
- }
- }
- return keys;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/LoadPolicy.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/LoadPolicy.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/LoadPolicy.java
deleted file mode 100644
index b9540fd..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/LoadPolicy.java
+++ /dev/null
@@ -1,42 +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.inject.api;
-
-/**
- * Available policies that describe how changes affecting configured values are published/reinjected
- * for a {@link DynamicValue}.
- * The policy also affects the cases were any configured listeners/listener methods are called for
- * propagation current configuration changes.
- */
-public enum LoadPolicy {
- /**
- * The configuration keys is evaluated once, when the owning component is loaded/configured, but never updated later.
- */
- INITIAL,
- /**
- * The configuration keys is evaluated exactly once on its first access/use lazily, but never updated later.
- * @see DynamicValue#get()
- * @see DynamicValue#commitAndGet()
- */
- LAZY,
- /**
- * The configuration value is evaluated evertime it is accessed.
- */
- ALWAYS
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/NoConfig.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/NoConfig.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/NoConfig.java
deleted file mode 100644
index c5234d3..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/NoConfig.java
+++ /dev/null
@@ -1,36 +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.inject.api;
-
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * This is a small marker annotations to inform Tamaya that the annotated element should never be injected with
- * configured data. This is useful because by default Tamaya tries to lookup and inject configuration also by
- * using property or method names without annotations. With that annotation none of these will be happen.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(value = { ElementType.FIELD, ElementType.METHOD })
-public @interface NoConfig {
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/UpdatePolicy.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/UpdatePolicy.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/UpdatePolicy.java
deleted file mode 100644
index 231b9b9..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/UpdatePolicy.java
+++ /dev/null
@@ -1,40 +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.inject.api;
-
-/**
- * Policy to control how new values are applied to a {@link DynamicValue}.
- */
-public enum UpdatePolicy {
- /** New values are applied immedately and registered listeners are informed about the change. */
- IMMEDEATE,
- /** New values or not applied, but stored in the newValue property. Explcit call to DynamicValue#commit
- of DynamicValue#commitAndGet are required to accept the change and inform the listeners about the change.
- * Registered listeners will be informed, when the commit was performed explicitly.
- */
- EXPLCIT,
- /**
- * New values are always immedately discarded, listeners are not triggered.
- */
- NEVER,
- /**
- * All listeners are informed about the change encountered, but the value will not be applied.
- */
- LOG_ONLY
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/WithConfigOperator.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/WithConfigOperator.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/WithConfigOperator.java
deleted file mode 100644
index 6630e53..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/WithConfigOperator.java
+++ /dev/null
@@ -1,45 +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.inject.api;
-
-import org.apache.tamaya.ConfigOperator;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation to define an configuration operator to be used before accessing a configured key.
- * This allows filtering the current configuration, e.g. to realize views or ensure security
- * constraints.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(value = {ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
-public @interface WithConfigOperator {
-
- /**
- * Define a custom adapter that should be used to adapt the configuration entry injected. This overrides any
- * general org.apache.tamaya.core.internal registered. If no adapter is defined (default) and no corresponding adapter is
- * registered, it is handled as a deployment error.
- * @return adapter used to transform the configuration entry.
- */
- Class<? extends ConfigOperator> value();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/WithPropertyConverter.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/WithPropertyConverter.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/WithPropertyConverter.java
deleted file mode 100644
index 499360c..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/WithPropertyConverter.java
+++ /dev/null
@@ -1,46 +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.inject.api;
-
-
-import org.apache.tamaya.spi.PropertyConverter;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation to define a type adapter to be used before injecting a configured key, or for applying changes.
- * This will override any other adapter for performing the type conversion before
- * injecting the field keys.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(value = {ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
-public @interface WithPropertyConverter {
-
- /**
- * Define a custom adapter or codec that should be used to adapt the configuration entry injected. This overrides any
- * general org.apache.tamaya.core.internal registered. If no adapter is defined (default) and no corresponding adapter is
- * registered, it is handled as a deployment error.
- * @return adapter used to change the configuration entry.
- */
- Class<? extends PropertyConverter<?>> value();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/package-info.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/package-info.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/package-info.java
deleted file mode 100644
index b5d8bc3..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/api/package-info.java
+++ /dev/null
@@ -1,22 +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.
- */
-/**
- * Common njection API.
- */
-package org.apache.tamaya.inject.api;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredField.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredField.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredField.java
deleted file mode 100644
index 94c0091..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredField.java
+++ /dev/null
@@ -1,68 +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.inject.spi;
-
-import org.apache.tamaya.Configuration;
-
-import java.lang.reflect.Field;
-import java.util.Collection;
-
-/**
- * Abstract model of an field used to inject configuration.
- */
-public interface ConfiguredField {
-
- /**
- * Get the field's type.
- * @return the field type, never null.
- */
- Class<?> getType();
-
- /**
- * Get a list of all target keys for the given field. The first resolvable key normally determines the
- * configuration value injected.
- * @return a list of evaluated keys.
- */
- Collection<String> getConfiguredKeys();
-
- /**
- * Get the field's name.
- * @return the name, not null.
- */
- String getName();
-
- /**
- * Get the field's full signature.
- * @return the signature, not null.
- */
- String getSignature();
-
- /**
- * Get the annotated field.
- * @return the field, not null.
- */
- Field getAnnotatedField();
-
- /**
- * Actually calls the annotated method on the instance, hereby passing the configuration values evaluated.
- * @param instance the instance, not null.
- * @param config the configuration, not null.
- */
- void configure(Object instance, Configuration config);
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredMethod.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredMethod.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredMethod.java
deleted file mode 100644
index 128946e..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredMethod.java
+++ /dev/null
@@ -1,70 +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.inject.spi;
-
-import org.apache.tamaya.Configuration;
-
-import java.lang.reflect.Method;
-import java.util.Collection;
-
-/**
- * Abstract model of an method used to inject configuration.
- */
-public interface ConfiguredMethod {
-
- /**
- * Get the key required to be evaluated.
- * @return the configured keys.
- */
- Collection<String> getConfiguredKeys();
-
- /**
- * Get the methods input parameter types.
- * @return the method param types, not null.
- */
- Class<?>[] getParameterTypes();
-
- /**
- * Get the underlying method reflection type.
- * @return the method element.
- */
- Method getAnnotatedMethod();
-
- /**
- * Get the method's name, e.g. {@code setName}.
- * @return the name, never null.
- */
- String getName();
-
- /**
- * Get the methods signature, e.g. {@code void setName(String)}.
- * @return he signature, never null.
- */
- String getSignature();
-
- /**
- * This method actually configures the given method on a instance of its parent type.
- * This evaluates the initial key closure and applies changes on the field.
- *
- * @param instance the target instance, not null.
- * @param config the configuration, not null.
- * @throws org.apache.tamaya.ConfigException if evaluation or conversion failed.
- */
- void configure(Object instance, Configuration config);
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredType.java
----------------------------------------------------------------------
diff --git a/modules/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredType.java b/modules/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredType.java
deleted file mode 100644
index 0f81dc7..0000000
--- a/modules/injection-api/src/main/java/org/apache/tamaya/inject/spi/ConfiguredType.java
+++ /dev/null
@@ -1,63 +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.inject.spi;
-
-import org.apache.tamaya.Configuration;
-
-import java.util.Collection;
-
-/**
- * Abstract model of an type used to inject configuration. This also includes instances passed programmatically.
- */
-public interface ConfiguredType{
-
- /**
- * Get the type's class.
- * @return the base type.
- */
- Class getType();
-
- /**
- * Get the type's name.
- * @return the type's name.
- */
- String getName();
-
- /**
- * Get the registered configured fields.
- * @return the registered configured fields, never null.
- */
- Collection<ConfiguredField> getConfiguredFields();
-
- /**
- * Get the registered configured methods.
- * @return the registered configured methods, never null.
- */
- Collection<ConfiguredMethod> getConfiguredMethods();
-
- /**
- * This method actually configures an instance using the given configuration data.
- *
- * @param instance The instance to be configured, not null.
- * @param config the target config, not null.
- */
- void configure(Object instance, Configuration config);
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/pom.xml
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/pom.xml b/modules/injection/cdi-ee/pom.xml
new file mode 100644
index 0000000..4804738
--- /dev/null
+++ b/modules/injection/cdi-ee/pom.xml
@@ -0,0 +1,226 @@
+<!--
+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 current 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-injection-all</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <artifactId>tamaya-cdi</artifactId>
+ <groupId>tamaya-integration</groupId>
+ <name>Apache Tamaya Modules - Injection CDI</name>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <owb.version>1.6.2</owb.version>
+ <weld.version>2.2.7.Final</weld.version>
+ <geronimo-jcdi-1.1-spec.version>1.0</geronimo-jcdi-1.1-spec.version>
+ <geronimo-interceptor-1.2-spec.version>1.0</geronimo-interceptor-1.2-spec.version>
+ <geronimo-atinject-1.0-spec.version>1.0</geronimo-atinject-1.0-spec.version>
+ <bval.version>0.5</bval.version>
+ <ds.version>1.1.0</ds.version>
+ <javaee-api.version>6.0-6</javaee-api.version>
+ <openejb.version>4.7.1</openejb.version>
+ <tomee.version>1.7.1</tomee.version>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>prepare-agent</id>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.tamaya.integration.cdi
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-injection-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>java-hamcrest</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-core</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>javaee-api</artifactId>
+ <version>${javaee-api.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.tomitribe</groupId>
+ <artifactId>tomitribe-util</artifactId>
+ <version>1.1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>openejb-core</artifactId>
+ <version>${openejb.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jcdi_1.1_spec</artifactId>
+ <version>${geronimo-jcdi-1.1-spec.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.deltaspike.modules</groupId>
+ <artifactId>deltaspike-test-control-module-api</artifactId>
+ <version>${ds.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.deltaspike.modules</groupId>
+ <artifactId>deltaspike-test-control-module-impl</artifactId>
+ <version>${ds.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <profiles>
+ <!--<profile>-->
+ <!--<id>OWB</id>-->
+ <!--<!– there is an issue with this profile:-->
+ <!--java.lang.NoClassDefFoundError: org/apache/webbeans/event/EventMetadata-->
+ <!--–>-->
+ <!--<activation>-->
+ <!--<activeByDefault>false</activeByDefault>-->
+ <!--</activation>-->
+ <!--<dependencies>-->
+ <!--<!– OWB specific dependencies–>-->
+ <!--<dependency>-->
+ <!--<groupId>org.apache.geronimo.specs</groupId>-->
+ <!--<artifactId>geronimo-atinject_1.0_spec</artifactId>-->
+ <!--<version>${geronimo-atinject-1.0-spec.version}</version>-->
+ <!--</dependency>-->
+ <!--<dependency>-->
+ <!--<groupId>org.apache.geronimo.specs</groupId>-->
+ <!--<artifactId>geronimo-interceptor_1.2_spec</artifactId>-->
+ <!--<version>${geronimo-interceptor-1.2-spec.version}</version>-->
+ <!--<scope>test</scope>-->
+ <!--</dependency>-->
+ <!--<dependency>-->
+ <!--<groupId>org.apache.geronimo.specs</groupId>-->
+ <!--<artifactId>geronimo-annotation_1.2_spec</artifactId>-->
+ <!--<version>1.0</version>-->
+ <!--<scope>test</scope>-->
+ <!--</dependency>-->
+ <!--<dependency>-->
+ <!--<groupId>org.apache.geronimo.specs</groupId>-->
+ <!--<artifactId>geronimo-el_2.2_spec</artifactId>-->
+ <!--<version>1.0.2</version>-->
+ <!--</dependency>-->
+
+ <!--<dependency>-->
+ <!--<groupId>org.apache.openwebbeans</groupId>-->
+ <!--<artifactId>openwebbeans-impl</artifactId>-->
+ <!--<version>${owb.version}</version>-->
+ <!--</dependency>-->
+ <!--<dependency>-->
+ <!--<groupId>org.apache.openwebbeans</groupId>-->
+ <!--<artifactId>openwebbeans-spi</artifactId>-->
+ <!--<version>${owb.version}</version>-->
+ <!--</dependency>-->
+ <!--<dependency>-->
+ <!--<groupId>org.apache.openwebbeans</groupId>-->
+ <!--<artifactId>openwebbeans-resource</artifactId>-->
+ <!--<version>${owb.version}</version>-->
+ <!--</dependency>-->
+
+ <!--<dependency>-->
+ <!--<groupId>org.apache.bval</groupId>-->
+ <!--<artifactId>bval-jsr303</artifactId>-->
+ <!--<version>${bval.version}</version>-->
+ <!--<scope>test</scope>-->
+ <!--</dependency>-->
+ <!--<dependency>-->
+ <!--<groupId>org.apache.deltaspike.cdictrl</groupId>-->
+ <!--<artifactId>deltaspike-cdictrl-owb</artifactId>-->
+ <!--<version>${ds.version}</version>-->
+ <!--<scope>test</scope>-->
+ <!--</dependency>-->
+ <!--</dependencies>-->
+ <!--</profile>-->
+ <profile>
+ <id>Weld</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.weld.se</groupId>
+ <artifactId>weld-se</artifactId>
+ <version>${weld.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.deltaspike.cdictrl</groupId>
+ <artifactId>deltaspike-cdictrl-weld</artifactId>
+ <version>${ds.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java
new file mode 100644
index 0000000..5bfb1c1
--- /dev/null
+++ b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java
@@ -0,0 +1,169 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.ServiceContext;
+
+import javax.annotation.Priority;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import java.text.MessageFormat;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+/**
+ * <p>This class implements a {@link ServiceContext}, which basically provides a similar loading mechanism as used
+ * by the {@link java.util.ServiceLoader}. Whereas the {@link java.util.ServiceLoader} only loads configurations
+ * and instances from one classloader, this loader manages configs found and the related instances for each
+ * classloader along the classloader hierarchies individually. It ensures instances are loaded on the classloader
+ * level, where they first are visible. Additionally it ensures the same configuration resource (and its
+ * declared services) are loaded multiple times, when going up the classloader hierarchy.</p>
+ *
+ * <p>Finally classloaders are not stored by reference by this class, to ensure they still can be garbage collected.
+ * Refer also the inherited parent class for further details.</p>
+ *
+ * <p>This class uses an ordinal of {@code 10}, so it overrides any default {@link ServiceContext} implementations
+ * provided with the Tamaya core modules.</p>
+ */
+public class CDIAwareServiceContext implements ServiceContext {
+
+ /**
+ * Singletons.
+ */
+ private final Map<Class<?>, Object> singletons = new ConcurrentHashMap<>();
+
+ private ServiceContext defaultServiceContext = new ServiceLoaderServiceContext();
+
+
+ @Override
+ public <T> T getService(Class<T> serviceType) {
+ Object cached = singletons.get(serviceType);
+ if (cached == null) {
+ Collection<T> services = getServices(serviceType);
+ if (services.isEmpty()) {
+ cached = null;
+ } else {
+ cached = getServiceWithHighestPriority(services, serviceType);
+ }
+ if(cached!=null) {
+ singletons.put(serviceType, cached);
+ }
+ }
+ return serviceType.cast(cached);
+ }
+
+ /**
+ * Loads and registers services.
+ *
+ * @param <T> the concrete type.
+ * @param serviceType The service type.
+ * @return the items found, never {@code null}.
+ */
+ @Override
+ public <T> List<T> getServices(final Class<T> serviceType) {
+ List<T> found = defaultServiceContext.getServices(serviceType);
+ BeanManager beanManager = TamayaCDIIntegration.getBeanManager();
+ Instance<T> cdiInstances = null;
+ if(beanManager!=null){
+ Set<Bean<?>> instanceBeans = beanManager.getBeans(Instance.class);
+ Bean<?> bean = instanceBeans.iterator().next();
+ cdiInstances = (Instance<T>)beanManager.getReference(bean, Instance.class,
+ beanManager.createCreationalContext(bean));
+ }
+ if(cdiInstances!=null){
+ for(T t:cdiInstances.select(serviceType)){
+ found.add(t);
+ }
+ }
+ return found;
+ }
+
+ /**
+ * Checks the given instance for a @Priority annotation. If present the annotation's value s evaluated. If no such
+ * annotation is present, a default priority is returned (1);
+ * @param o the instance, not null.
+ * @return a priority, by default 1.
+ */
+ public static int getPriority(Object o){
+ int prio = 1; //X TODO discuss default priority
+ Priority priority = o.getClass().getAnnotation(Priority.class);
+ if (priority != null) {
+ prio = priority.value();
+ }
+ return prio;
+ }
+
+ /**
+ * @param services to scan
+ * @param <T> type of the service
+ *
+ * @return the service with the highest {@link Priority#value()}
+ *
+ * @throws ConfigException if there are multiple service implementations with the maximum priority
+ */
+ private <T> T getServiceWithHighestPriority(Collection<T> services, Class<T> serviceType) {
+
+ // we do not need the priority stuff if the list contains only one element
+ if (services.size() == 1) {
+ return services.iterator().next();
+ }
+
+ Integer highestPriority = null;
+ int highestPriorityServiceCount = 0;
+ T highestService = null;
+
+ for (T service : services) {
+ int prio = getPriority(service);
+ if (highestPriority == null || highestPriority < prio) {
+ highestService = service;
+ highestPriorityServiceCount = 1;
+ highestPriority = prio;
+ } else if (highestPriority == prio) {
+ highestPriorityServiceCount++;
+ }
+ }
+
+ if (highestPriorityServiceCount > 1) {
+ throw new ConfigException(MessageFormat.format("Found {0} implementations for Service {1} with Priority {2}: {3}",
+ highestPriorityServiceCount,
+ serviceType.getName(),
+ highestPriority,
+ services));
+ }
+
+ return highestService;
+ }
+
+ /**
+ * Returns ordinal of 20, overriding defaults as well as the inherited (internally used) CLAwareServiceContext
+ * instance.
+ * @return ordinal of 20.
+ */
+ @Override
+ public int ordinal() {
+ return 20;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredField.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredField.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredField.java
new file mode 100644
index 0000000..fa826f5
--- /dev/null
+++ b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredField.java
@@ -0,0 +1,77 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.inject.spi.ConfiguredField;
+
+import javax.enterprise.inject.spi.InjectionPoint;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * CDI implementation for event publishing of configured instances.
+ */
+class CDIConfiguredField implements ConfiguredField{
+
+ private final Field field;
+ private List<String> keys = new ArrayList<>();
+
+ CDIConfiguredField(InjectionPoint injectionPoint, List<String> keys){
+ this.field = (Field)injectionPoint.getMember();
+ this.keys.addAll(keys);
+ this.keys = Collections.unmodifiableList(this.keys);
+ }
+
+ @Override
+ public Class<?> getType() {
+ return field.getType();
+ }
+
+ @Override
+ public Collection<String> getConfiguredKeys() {
+ return keys;
+ }
+
+ @Override
+ public Field getAnnotatedField() {
+ return field;
+ }
+
+ @Override
+ public String getName() {
+ return field.getName();
+ }
+
+ @Override
+ public String getSignature() {
+ return getName()+':'+field.getType().getName();
+ }
+
+ @Override
+ public void configure(Object instance, Configuration config) {
+ throw new UnsupportedOperationException("Use CDI annotations for configuration injection.");
+ }
+
+ @Override
+ public String toString() {
+ return "CDIConfiguredField["+getSignature()+']';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredMethod.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredMethod.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredMethod.java
new file mode 100644
index 0000000..ed8019a
--- /dev/null
+++ b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredMethod.java
@@ -0,0 +1,77 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.inject.spi.ConfiguredMethod;
+
+import javax.enterprise.inject.spi.InjectionPoint;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Implementation of a configured methods for CDI module.
+ */
+public class CDIConfiguredMethod implements ConfiguredMethod{
+
+ private final Method method;
+ private List<String> keys = new ArrayList<>();
+
+ CDIConfiguredMethod(InjectionPoint injectionPoint, List<String> keys){
+ this.method = (Method)injectionPoint.getMember();
+ this.keys.addAll(keys);
+ this.keys = Collections.unmodifiableList(this.keys);
+ }
+
+ @Override
+ public Collection<String> getConfiguredKeys() {
+ return keys;
+ }
+
+ @Override
+ public Class<?>[] getParameterTypes() {
+ return method.getParameterTypes();
+ }
+
+ @Override
+ public Method getAnnotatedMethod() {
+ return method;
+ }
+
+ @Override
+ public String getName() {
+ return method.getName();
+ }
+
+ @Override
+ public String getSignature() {
+ return null;
+ }
+
+ @Override
+ public void configure(Object instance, Configuration config) {
+ throw new UnsupportedOperationException("Use CDI annotations for configuration injection.");
+ }
+
+ @Override
+ public String toString() {
+ return "CDIConfiguredMethod["+getSignature()+']';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredType.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredType.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredType.java
new file mode 100644
index 0000000..c677065
--- /dev/null
+++ b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredType.java
@@ -0,0 +1,94 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.inject.spi.ConfiguredField;
+import org.apache.tamaya.inject.spi.ConfiguredMethod;
+import org.apache.tamaya.inject.spi.ConfiguredType;
+
+import javax.enterprise.inject.spi.InjectionPoint;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Event published for items configured by CDI extensions. This is for example used by the documentation module
+ * to automatically track the configuration endpoints for documentation.
+ */
+class CDIConfiguredType implements ConfiguredType{
+
+ private final Class<?> type;
+ private final List<CDIConfiguredMethod> methods = new ArrayList<>();
+ private final List<CDIConfiguredField> fields = new ArrayList<>();
+
+ public CDIConfiguredType(Class<?> type){
+ this.type = Objects.requireNonNull(type);
+ }
+
+ @Override
+ public Class getType() {
+ return type;
+ }
+
+ @Override
+ public String getName() {
+ return type.getName();
+ }
+
+ @Override
+ public Collection<ConfiguredField> getConfiguredFields() {
+ return null;
+ }
+
+ @Override
+ public Collection<ConfiguredMethod> getConfiguredMethods() {
+ return null;
+ }
+
+ @Override
+ public void configure(Object instance, Configuration config) {
+ throw new UnsupportedOperationException("Use CDI annotations for configuration injection.");
+ }
+
+ /**
+ * Used to build up during injection point processing.
+ * @param injectionPoint the CDI injection ppint, not null.
+ * @param keys the possible config keys, in order of precedence, not null.
+ */
+ void addConfiguredMember(InjectionPoint injectionPoint, List<String> keys) {
+ Member member = injectionPoint.getMember();
+ if(member instanceof Field){
+ this.fields.add(new CDIConfiguredField(injectionPoint, keys));
+ } else if(member instanceof Method){
+ this.methods.add(new CDIConfiguredMethod(injectionPoint, keys));
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "CDIConfiguredType{" +
+ "type=" + type +
+ ", methods=" + methods +
+ ", fields=" + fields +
+ '}';
+ }
+}
[10/15] incubator-tamaya-extensions git commit: TAMAYA-189: Moved
format and injection modules into separate subtrees.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java b/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java
deleted file mode 100644
index da5fa35..0000000
--- a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationDataBuilder.java
+++ /dev/null
@@ -1,219 +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.format;
-
-import java.util.*;
-
-
-/**
- * Builder for creating {@link org.apache.tamaya.format.ConfigurationData} instances. This class is not thread-safe.
- */
-public final class ConfigurationDataBuilder {
-
- /** The format instance used to read this instance. */
- final ConfigurationFormat format;
- /** The resource read. */
- final String resource;
- /**
- * The properties of the default section (no name).
- */
- Map<String, String> defaultProperties;
- /**
- * A normalized flattened set of this configuration data.
- */
- Map<String, String> combinedProperties;
- /**
- * The sections read.
- */
- Map<String, Map<String, String>> namedSections;
-
- /**
- * Private constructor.
- * @param resource the configuration resource URL, not null.
- * @param format the format that read this data, not null.
- */
- private ConfigurationDataBuilder(String resource, ConfigurationFormat format){
- this.format = Objects.requireNonNull(format);
- this.resource = Objects.requireNonNull(resource);
- }
-
- /**
- * Creates a new instance.
- * @param resource the configuration resource URL, not null.
- * @param format the format that read this data, not null.
- * @return new instance of this class.
- */
- public static ConfigurationDataBuilder of(String resource, ConfigurationFormat format){
- return new ConfigurationDataBuilder(resource, format);
- }
-
- /**
- * Creates a new instance.
- * @param data an existing ConfigurationData instances used to initialize the builder.
- * @return new instance of this class from the given configuration.
- */
- public static ConfigurationDataBuilder of(ConfigurationData data){
- ConfigurationDataBuilder b = new ConfigurationDataBuilder(data.getResource(), data.getFormat());
- if (data.hasDefaultProperties()) {
- b.getDefaultProperties().putAll(data.getDefaultProperties());
- }
- if (data.hasCombinedProperties()) {
- b.getCombinedProperties().putAll(data.getCombinedProperties());
- }
- if (!data.getSections().isEmpty()) {
- b.getSections().putAll(data.getSections());
- }
- return b;
- }
-
- /**
- * Adds (empty) sections,if they are not yet existing. Already existing sections will not be touched.
- * @param sections the new sections to put.
- * @return the builder for chaining.
- */
- public ConfigurationDataBuilder addSections(String... sections){
- for (String section : sections) {
- if (!getSections().containsKey(section)) {
- getSections().put(section, new HashMap<String, String>());
- }
- }
- return this;
- }
-
- /**
- * Adds a single entry to a target section.
- * @param section the target section (will be created if not existing).
- * @param key the entry's key
- * @param value the entry's value
- * @return the builder for chaining.
- */
- public ConfigurationDataBuilder addSectionProperty(String section, String key, String value) {
- Map<String, String> map = getSections().get(section);
- if (map == null) {
- map = new HashMap<>();
- getSections().put(section, map);
- }
- map.put(key, value);
- return this;
- }
-
- /**
- * Adds a single entry to the <i>default</i> section.
- * @param key the entry's key
- * @param value the entry's value
- * @return the builder for chaining.
- */
- public ConfigurationDataBuilder addProperty(String key, String value) {
- getDefaultProperties().put(key, value);
- return this;
- }
-
- /**
- * Adds the given entries to the given section, all existing values will be overridden.
- * @param section the target section (will be created if not existing).
- * @param properties the entry's data
- * @return the builder for chaining.
- */
- public ConfigurationDataBuilder addSectionProperties(String section, Map<String, String> properties) {
- Map<String, String> map = getSections().get(section);
- if (map == null) {
- map = new HashMap<>();
- getSections().put(section, map);
- }
- map.putAll(properties);
- return this;
- }
-
- /**
- * Adds the given entries to the <i>default</i> section, all existing values will be overridden.
- * @param properties the entry's data
- * @return the builder for chaining.
- */
- public ConfigurationDataBuilder addProperties(Map<String, String> properties) {
- getDefaultProperties().putAll(properties);
- return this;
- }
-
- /**
- * Sets the given entries as the <i>combined</i> properties map, all existing properties of the
- * combined map will be overridden.
- *
- * @param properties the entry's data
- * @return the builder for chaining.
- */
- public ConfigurationDataBuilder setCombinedProperties(Map<String, String> properties) {
- this.combinedProperties = new HashMap<>(properties);
- return this;
- }
-
- /**
- * Access the current default section, if not present a new instance is initialized.
- *
- * @return the current default section, never null.
- */
- public Map<String, String> getDefaultProperties() {
- if (defaultProperties == null) {
- defaultProperties = new HashMap<>();
- }
- return defaultProperties;
- }
-
- /**
- * Access the current combined properties, if not present a new instance is initialized.
- *
- * @return the current combined properties, never null.
- */
- public Map<String, String> getCombinedProperties() {
- if (combinedProperties == null) {
- combinedProperties = new HashMap<>();
- }
- return combinedProperties;
- }
-
- /**
- * Access the current named sections, if not present a new instance is initialized.
- *
- * @return the current named sections, never null.
- */
- public Map<String, Map<String, String>> getSections() {
- if (namedSections == null) {
- namedSections = new HashMap<>();
- }
- return namedSections;
- }
-
- /**
- * Builds a new {@link org.apache.tamaya.format.ConfigurationData} instance.
- * @return a new {@link org.apache.tamaya.format.ConfigurationData} instance, not null.
- */
- public ConfigurationData build(){
- return new ConfigurationData(this);
- }
-
- @Override
- public String toString() {
- return "ConfigurationDataBuilder{" +
- "format=" + format +
- ", default properties=" + defaultProperties +
- ", sections=" + namedSections +
- ", combined properties=" + combinedProperties +
- ", resource=" + resource +
- '}';
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java b/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java
deleted file mode 100644
index 997ef3a..0000000
--- a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormat.java
+++ /dev/null
@@ -1,103 +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.format;
-
-import java.io.InputStream;
-import java.net.URL;
-
-/**
- * <p>Implementations current this class encapsulate the mechanism how to read a
- * resource including interpreting the format correctly (e.g. xml vs.
- * properties vs. ini). In most cases file only contains entries of the same priority, which would then
- * result in only one {@link org.apache.tamaya.spi.PropertySource}. Complex file formats, however, may contain entries
- * of different priorities. In this cases, each ordinal type found typically is returned as a separate section so the
- * consuming {@link org.apache.tamaya.spi.PropertySourceProvider} implementation can distribute the different part to
- * individual {@link org.apache.tamaya.spi.PropertySource}s.</p>
- *
- * <h3>Implementation Requirements</h3>
- * Implementations of this type must be
- * <ul>
- * <li>thread-safe</li>
- * </ul>
- */
-public interface ConfigurationFormat {
-
- /**
- * Get a unique name of the format. This name can be used to access the format.
- * @return the (unique) format's name, never null and not empty.
- */
- String getName();
-
- /**
- * Allows the format to examine the given resource, e.g. for a matching file ending. Only, if a format accepts an
- * URL, it will be tried for reading the configuration.
- * @param url the url to read the configuration data from (could be a file, a server location, a classpath
- * resource or something else, not null.
- * @return true, if this format accepts the given URL for reading.
- */
- boolean accepts(URL url);
-
- /**
- * Reads a configuration from an URL, hereby parsing the given {@link java.io.InputStream}. Dependening on
- * the capabilities of the format the returned {@link org.apache.tamaya.format.ConfigurationData} may contain
- * different levels of data:
- * <ul>
- * <li>Only a <i>default</i> section is returned, since the configuration format does not support
- * hierarchies. This is the case for properties and xml properties.</li>
- * <li>Hierarchical formats such as INI, XML and JSON can map each node to a section. Each section
- * can have its own key/value pairs. This allows to map also complex formats in a generic way. A
- * format implementation should then additionally flatten the whole data and store it in a accessible as
- * {@link ConfigurationData#getCombinedProperties()}. This allows to use the properties as inout to a default mapping,
- * which is always appropriate as long as no other semnatics
- * are defined in the concrete target scenario.</li>
- * <li>More complex custom scenarios should map their configuration data read into different
- * sections. Typically the data will be mapped into different {@link org.apache.tamaya.spi.PropertySource}
- * instances with different ordinal levels. As an example imagine a custom format that contains sections
- * 'defaults', 'global-defaults', 'application', 'server-overrides'.</li>
- * <li>Alternate formats</li>
- * </ul>
- *
- * Summarizing implementations common formats should always provide
- * <ul>
- * <li>the data organized in sections as useful for the given format. If data is organized in one section, it
- * should be mapped into the DEFAULT section.</li>
- * <li>Formats that do provide multiple sections, should always provide a FLATTENED section as well, where
- * all the data is organized as a flattened key/value pairs, enabling a generic mapping to a
- * {@link org.apache.tamaya.spi.PropertySource}.</li>
- * </ul>
- *
- * If the configuration format only contains entries of one ordinal type, normally only one single
- * instance of PropertySource is returned (the corresponding key/values should end up in the DEFAULT section).
- * Nevertheless custom formats may contain different sections or parts,
- * where each part maps to a different target ordinal (eg defaults, domain config and app config). In the
- * ladder case multiple PropertySources can be returned, each one with its own ordinal and the corresponding
- * entries.
- * @see org.apache.tamaya.spi.PropertySource
- * @param resource a descriptive name for the resource, since an InputStream does not have any)
- * @param inputStream the inputStream to read the configuration data from (could be a file, a server location, a classpath
- * resource or something else.
- * @return the corresponding {@link ConfigurationData} containing sections/properties read, never {@code null}.
- * @throws org.apache.tamaya.ConfigException if parsing of the input fails.
- */
- ConfigurationData readConfiguration(String resource, InputStream inputStream);
-
- //X TODO Add support to access a default format to see a correct formatting
- //X String getFormatExample();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormats.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormats.java b/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormats.java
deleted file mode 100644
index bc8aabd..0000000
--- a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationFormats.java
+++ /dev/null
@@ -1,187 +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.format;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.apache.tamaya.spi.ServiceContextManager;
-
-/**
- * Small accessor and management class dealing with {@link org.apache.tamaya.format.ConfigurationFormat}
- * instances.
- */
-public final class ConfigurationFormats {
- /**
- * The logger used.
- */
- private static final Logger LOG = Logger.getLogger(ConfigurationFormats.class.getName());
-
- /**
- * Singleton constructor.
- */
- private ConfigurationFormats() {
- }
-
- /**
- * Get all currently available formats, ordered by priority.
- *
- * @return the currently available formats, never null.
- */
- public static List<ConfigurationFormat> getFormats() {
- return ServiceContextManager.getServiceContext().getServices(ConfigurationFormat.class);
- }
-
- /**
- * Get all currently available formats, ordered by priority.
- *
- * @param formatNames available formats to be ordered.
- * @return the currently available formats, never null.
- */
- public static List<ConfigurationFormat> getFormats(String... formatNames) {
- final List<ConfigurationFormat> result = new ArrayList<>();
- final Set<String> names = new HashSet<>(Arrays.asList(formatNames));
- for (final ConfigurationFormat f : getFormats()) {
- if (names.contains(f.getName())) {
- result.add(f);
- }
- }
- return result;
- }
-
- // Activate for JDK 8...
-// /**
-// * Get all currently available formats, ordered by priority.
-// *
-// * @return the currently available formats, never null.
-// */
-// public static List<ConfigurationFormat> getFormats(Predicate<String> namePredicate) {
-// List<ConfigurationFormat> result = new ArrayList<>();
-// for(ConfigurationFormat f:getFormats()){
-// if(namePredicate.test(f.getName()){
-// result.add(f);
-// }
-// }
-// return result;
-// }
-
- /**
- * Get all currently available formats, ordered by priority.
- *
- * @param url source to read configuration from.
- * @return the currently available formats, never null.
- */
- public static List<ConfigurationFormat> getFormats(final URL url) {
- final List<ConfigurationFormat> formats = getFormats();
- final List<ConfigurationFormat> result = new ArrayList<>();
- for (final ConfigurationFormat f : formats) {
- if (f.accepts(url)) {
- result.add(f);
- }
- }
- return result;
- }
-
- /**
- * Tries to read configuration data from a given URL, hereby traversing all known formats in order of precedence.
- * Hereby the formats are first filtered to check if the URL is acceptable, before the input is being parsed.
- *
- * @param url the url from where to read, not null.
- * @return the ConfigurationData read, or null.
- * @throws IOException if the resource cannot be read.
- */
- public static ConfigurationData readConfigurationData(final URL url) throws IOException {
- final List<ConfigurationFormat> formats = getFormats(url);
- return readConfigurationData(url, formats.toArray(new ConfigurationFormat[formats.size()]));
- }
-
- /**
- * Tries to read configuration data from a given URL, hereby explicitly trying all given formats in order.
- *
- * @param url the url from where to read, not null.
- * @param formats the formats to try.
- * @return the ConfigurationData read, or null.
- * @throws IOException if the resource cannot be read.
- */
- public static ConfigurationData readConfigurationData(URL url, ConfigurationFormat... formats) throws IOException {
- return readConfigurationData(url.toString(), url.openStream(), formats);
- }
-
- /**
- * @param urls the urls from where to read, not null.
- * @param formats the formats to try.
- * @return the {@link org.apache.tamaya.format.ConfigurationData} of the files successfully decoded by the
- * given formats.
- */
- public static Collection<ConfigurationData> getPropertySources(Collection<URL> urls, ConfigurationFormat... formats) {
- final List<ConfigurationData> dataRead = new ArrayList<>();
- for (final URL url : urls) {
- try {
- final ConfigurationData data = readConfigurationData(url, formats);
- if (data != null) {
- dataRead.add(data);
- }
- } catch (final Exception e) {
- LOG.log(Level.SEVERE, "Error reading file: " + url.toExternalForm(), e);
- }
- }
- return dataRead;
- }
-
- /**
- * Tries to read configuration data from a given URL, hereby explicitly trying all given formats in order.
- *
- * @param resource a descriptive name for the resource, since an InputStream does not have any
- * @param inputStream the inputStream from where to read, not null.
- * @param formats the formats to try.
- * @return the ConfigurationData read, or null.
- * @throws IOException if the resource cannot be read.
- */
- public static ConfigurationData readConfigurationData(String resource, InputStream inputStream,
- ConfigurationFormat... formats) throws IOException {
- Objects.requireNonNull(inputStream);
- Objects.requireNonNull(resource);
- try(InputStreamFactory isFactory = new InputStreamFactory(inputStream)) {
- for (final ConfigurationFormat format : formats) {
- try (InputStream is = isFactory.createInputStream()) {
- final ConfigurationData data = format.readConfiguration(resource, is);
- if (data != null) {
- return data;
- }
- } catch (final Exception e) {
- LOG.log(Level.INFO,
- "Format " + format.getClass().getName() + " failed to read resource " + resource, e);
- }
- }
- }
- return null;
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/main/java/org/apache/tamaya/format/FlattenedDefaultPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/FlattenedDefaultPropertySource.java b/modules/formats/src/main/java/org/apache/tamaya/format/FlattenedDefaultPropertySource.java
deleted file mode 100644
index 9d2097f..0000000
--- a/modules/formats/src/main/java/org/apache/tamaya/format/FlattenedDefaultPropertySource.java
+++ /dev/null
@@ -1,118 +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.format;
-
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertyValue;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Flattened default PropertySource that uses the flattened config data read from an URL by a
- * ${@link org.apache.tamaya.format.ConfigurationFormat}.
- */
-public class FlattenedDefaultPropertySource implements PropertySource {
- private static final Logger LOG = Logger.getLogger(FlattenedDefaultPropertySource.class.getName());
- private final Map<String, String> properties;
- private final ConfigurationData data;
- private int defaultOrdinal = 0;
-
-
- /*
- * Constructor, uses hereby the flattened config data read from an URL by a
- * ${@link org.apache.tamaya.format.ConfigurationFormat}, and if not present falls back to the default section.
- */
- public FlattenedDefaultPropertySource(ConfigurationData data) {
- this.properties = populateData(data);
- this.data = data;
- }
-
- /*
- * Constructor, uses hereby the flattened config data read from an URL by a
- * ${@link org.apache.tamaya.format.ConfigurationFormat}, and if not present falls back to the default section.
- */
- public FlattenedDefaultPropertySource(int defaultOrdinal, ConfigurationData data) {
- this.properties = populateData(data);
- this.data = data;
- this.defaultOrdinal = defaultOrdinal;
- }
-
- protected Map<String, String> populateData(ConfigurationData data) {
- Map<String, String> result = data.getCombinedProperties();
- if (result.isEmpty()) {
- result = data.getDefaultProperties();
- }
- if (result.isEmpty()) {
- result = new HashMap<>();
- }
- if(result.isEmpty()){
- for (String section : data.getSectionNames()) {
- Map<String,String> sectionMap = data.getSection(section);
- for(Map.Entry<String,String> en: sectionMap.entrySet()){
- result.put(section + '.' + en.getKey(), en.getValue());
- }
- }
- }
- return Collections.unmodifiableMap(result);
- }
-
- @Override
- public String getName() {
- String name = this.properties.get("[meta].name");
- if (name == null) {
- name = this.data.getResource();
- }
- if (name == null) {
- name = getClass().getSimpleName();
- }
- return name;
- }
-
- @Override
- public int getOrdinal() {
- String ordinalValue = this.properties.get(PropertySource.TAMAYA_ORDINAL);
- if (ordinalValue != null) {
- try {
- return Integer.parseInt(ordinalValue.trim());
- } catch (Exception e) {
- LOG.log(Level.WARNING, "Failed to parse Tamaya ordinal from " + data.getResource(), e);
- }
- }
- return defaultOrdinal;
- }
-
- @Override
- public PropertyValue get(String key) {
- return PropertyValue.of(key, properties.get(key), getName());
- }
-
- @Override
- public Map<String, String> getProperties() {
- return properties;
- }
-
- @Override
- public boolean isScannable() {
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/main/java/org/apache/tamaya/format/InputStreamFactory.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/InputStreamFactory.java b/modules/formats/src/main/java/org/apache/tamaya/format/InputStreamFactory.java
deleted file mode 100644
index 912dd08..0000000
--- a/modules/formats/src/main/java/org/apache/tamaya/format/InputStreamFactory.java
+++ /dev/null
@@ -1,89 +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.format;
-
-import java.io.*;
-import java.util.Objects;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Wrapper for a given {@link InputStream} to be able to close
- * it via the try-with-resources construct of Java 7.
- *
- * <h1>Usage example</h1>
- *
- * <pre>
- * public void readIt(InputStream inputStream) {
- * try (InputStream is = new ParallelInputStream(inputStream) {
- * // Consume the stream
- * }
- * }
- * </pre>
- */
-public class InputStreamFactory implements Closeable {
- private static final Logger LOG = Logger.getLogger(InputStreamFactory.class.getName());
-
- private byte[] data;
-
- /**
- * Creates a new InputStreamFactory.
- *
- * @param original the InputStream to be read for extract its data into memory.
- * @throws IOException if thrown by the original during read.
- */
- public InputStreamFactory(InputStream original) throws IOException {
- Objects.requireNonNull(original);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- byte[] bytes = new byte[256];
- try {
- int read = original.read(bytes);
- while (read > 0) {
- bos.write(bytes, 0, read);
- read = original.read(bytes);
- }
- this.data = bos.toByteArray();
- } finally {
- try {
- original.close();
- } catch (IOException e) {
- LOG.log(Level.FINEST, "Error closing stream: " + original, e);
- }
- }
- }
-
- /**
- * Creates a new InputStream with the same data as provided by the InputStream passed on factory creation.
- *
- * @return a new InputStream , never null.
- * @throws IOException if no data is available.
- */
- public InputStream createInputStream() throws IOException {
- byte[] bytes = this.data;
- if (bytes == null) {
- throw new IOException("InputStreamFactory is closed.");
- }
- return new ByteArrayInputStream(bytes);
- }
-
- @Override
- public void close() throws IOException {
- this.data = null;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/main/java/org/apache/tamaya/format/formats/IniConfigurationFormat.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/formats/IniConfigurationFormat.java b/modules/formats/src/main/java/org/apache/tamaya/format/formats/IniConfigurationFormat.java
deleted file mode 100644
index fe27ba7..0000000
--- a/modules/formats/src/main/java/org/apache/tamaya/format/formats/IniConfigurationFormat.java
+++ /dev/null
@@ -1,95 +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.format.formats;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.format.ConfigurationData;
-import org.apache.tamaya.format.ConfigurationDataBuilder;
-import org.apache.tamaya.format.ConfigurationFormat;
-
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Implements a ini file format.
- */
-public class IniConfigurationFormat implements ConfigurationFormat {
-
- /**
- * The logger.
- */
- private final static Logger LOG = Logger.getLogger(IniConfigurationFormat.class.getName());
-
- @Override
- public String getName() {
- return "ini";
- }
-
- @Override
- public boolean accepts(URL url) {
- String fileName = url.getFile();
- return fileName.endsWith(".ini") || fileName.endsWith(".INI");
- }
-
- @Override
- public ConfigurationData readConfiguration(String resource, InputStream inputStream) {
- ConfigurationDataBuilder builder = ConfigurationDataBuilder.of(resource, this);
- try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"))) {
- String line = reader.readLine();
- int lineNum = 0;
- String section = null;
- while (line != null) {
- lineNum++;
- line = line.trim();
- if (line.isEmpty()) {
- line = reader.readLine();
- continue;
- }
- if (line.startsWith("[")) {
- int end = line.indexOf(']');
- if (end < 0) {
- throw new ConfigException(
- "Invalid INI-Format, ']' expected, at " + lineNum + " in " + resource);
- }
- section = line.substring(1, end);
- } else if (line.trim().startsWith("#")) {
- // comment
- } else {
- int sep = line.indexOf('=');
- String key = line.substring(0, sep);
- String value = line.substring(sep + 1);
- if (section != null) {
- builder.addSectionProperty(section, key, value);
- } else {
- builder.addProperty(key, value);
- }
- }
- line = reader.readLine();
- }
- return builder.build();
- } catch (Exception e) {
- LOG.log(Level.SEVERE, "Could not read configuration: " + resource, e);
- }
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesFormat.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesFormat.java b/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesFormat.java
deleted file mode 100644
index 35cef77..0000000
--- a/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesFormat.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.format.formats;
-
-import org.apache.tamaya.format.ConfigurationData;
-import org.apache.tamaya.format.ConfigurationDataBuilder;
-import org.apache.tamaya.format.ConfigurationFormat;
-
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Implementation of a {@link org.apache.tamaya.format.ConfigurationFormat} for -properties files.
- *
- * @see java.util.Properties#load(java.io.InputStream)
- */
-public class PropertiesFormat implements ConfigurationFormat {
- /**
- * The logger.
- */
- private final static Logger LOG = Logger.getLogger(PropertiesFormat.class.getName());
-
-
- @Override
- public String getName() {
- return "properties";
- }
-
- @Override
- public boolean accepts(URL url) {
- String fileName = url.getFile();
- return fileName.endsWith(".properties") || fileName.endsWith(".PROPERTIES") ||
- fileName.endsWith(".conf") || fileName.endsWith(".CONF");
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public ConfigurationData readConfiguration(String resource, InputStream inputStream) {
- Objects.requireNonNull(inputStream);
- Objects.requireNonNull(resource);
- try {
- final Properties p = new Properties();
- p.load(inputStream);
- return ConfigurationDataBuilder.of(resource, this).addProperties(Map.class.cast(p)).build();
- } catch (Exception e) {
- LOG.log(Level.FINEST, "Failed to read config from resource: " + resource, e);
- }
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesXmlFormat.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesXmlFormat.java b/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesXmlFormat.java
deleted file mode 100644
index c47b6f6..0000000
--- a/modules/formats/src/main/java/org/apache/tamaya/format/formats/PropertiesXmlFormat.java
+++ /dev/null
@@ -1,69 +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.format.formats;
-
-import org.apache.tamaya.format.ConfigurationData;
-import org.apache.tamaya.format.ConfigurationDataBuilder;
-import org.apache.tamaya.format.ConfigurationFormat;
-
-import java.io.InputStream;
-import java.net.URL;
-import java.util.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Implementation of a {@link org.apache.tamaya.format.ConfigurationFormat} for xml property
- * files.
- *
- * @see java.util.Properties#loadFromXML(java.io.InputStream)
- */
-public class PropertiesXmlFormat implements ConfigurationFormat {
- /**
- * The logger.
- */
- private final static Logger LOG = Logger.getLogger(PropertiesXmlFormat.class.getName());
-
- @Override
- public String getName() {
- return "xml-properties";
- }
-
- @Override
- public boolean accepts(URL url) {
- String fileName = url.getFile();
- return fileName.endsWith(".xml") || fileName.endsWith(".XML");
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public ConfigurationData readConfiguration(String resource, InputStream inputStream) {
- Objects.requireNonNull(inputStream);
- Objects.requireNonNull(resource);
-
- try {
- final Properties p = new Properties();
- p.loadFromXML(inputStream);
- return ConfigurationDataBuilder.of(resource, this).addProperties(Map.class.cast(p)).build();
- } catch (Exception e) {
- LOG.log(Level.FINEST, "Failed to read config from resource: " + resource, e);
- }
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/main/java/org/apache/tamaya/format/formats/package-info.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/formats/package-info.java b/modules/formats/src/main/java/org/apache/tamaya/format/formats/package-info.java
deleted file mode 100644
index db8987d..0000000
--- a/modules/formats/src/main/java/org/apache/tamaya/format/formats/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-/**
- * This package provides implementtion of {@link org.apache.tamaya.format.ConfigurationFormat}
- * for properties, xml-properties and ini files.
- */
-package org.apache.tamaya.format.formats;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/main/java/org/apache/tamaya/format/package-info.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/package-info.java b/modules/formats/src/main/java/org/apache/tamaya/format/package-info.java
deleted file mode 100644
index 39b5f0b..0000000
--- a/modules/formats/src/main/java/org/apache/tamaya/format/package-info.java
+++ /dev/null
@@ -1,28 +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.
- */
-/**
- * This package provides an abstraction for parsing a configuration
- * from an input strem, called {@link org.apache.tamaya.format.ConfigurationFormat}
- * and corresponding helper artifacts.
- *
- * @see org.apache.tamaya.format.ConfigurationFormat
- * @see org.apache.tamaya.format.ConfigurationData
- * @see org.apache.tamaya.format.ConfigurationFormats
- */
-package org.apache.tamaya.format;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
----------------------------------------------------------------------
diff --git a/modules/formats/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat b/modules/formats/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
deleted file mode 100644
index 96e898f..0000000
--- a/modules/formats/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
+++ /dev/null
@@ -1,21 +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 current 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.
-#
-org.apache.tamaya.format.formats.IniConfigurationFormat
-org.apache.tamaya.format.formats.PropertiesFormat
-org.apache.tamaya.format.formats.PropertiesXmlFormat
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/test/java/org/apache/tamaya/format/ConfigurationFormatsTest.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/test/java/org/apache/tamaya/format/ConfigurationFormatsTest.java b/modules/formats/src/test/java/org/apache/tamaya/format/ConfigurationFormatsTest.java
deleted file mode 100644
index 0839714..0000000
--- a/modules/formats/src/test/java/org/apache/tamaya/format/ConfigurationFormatsTest.java
+++ /dev/null
@@ -1,68 +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.format;
-
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * Tests for {@link org.apache.tamaya.format.ConfigurationFormats}.
- */
-public class ConfigurationFormatsTest {
-
- @org.junit.Test
- public void testGetFormats() throws Exception {
- List<ConfigurationFormat> formats = ConfigurationFormats.getFormats();
- assertNotNull(formats);
- assertEquals(formats.size(), 3);
- }
-
- @org.junit.Test
- public void testReadConfigurationData() throws Exception {
- List<ConfigurationFormat> formats = ConfigurationFormats.getFormats(getClass().getResource("/Test.ini"));
- assertNotNull(formats);
- assertEquals(formats.size(), 1);
- formats = ConfigurationFormats.getFormats(getClass().getResource("/Test.properties"));
- assertNotNull(formats);
- assertEquals(formats.size(), 1);
-// formats = ConfigurationFormats.getFormats(getClass().getResource("/Test.xml"));
-// assertNotNull(formats);
-// assertEquals(formats.size(), 1);
-
- }
-
- @org.junit.Test
- public void testReadConfigurationData_URL() throws Exception {
- ConfigurationData data = ConfigurationFormats.readConfigurationData(getClass().getResource("/Test.ini"));
- assertNotNull(data);
- data = ConfigurationFormats.readConfigurationData(getClass().getResource("/Test.properties"));
- assertNotNull(data);
- }
-
- @org.junit.Test
- public void testReadConfigurationData2() throws Exception {
- List<ConfigurationFormat> formats = ConfigurationFormats.getFormats();
- ConfigurationData data = ConfigurationFormats.readConfigurationData(getClass().getResource("/Test.ini"),
- formats.toArray(new ConfigurationFormat[formats.size()]));
- assertNotNull(data);
- System.out.println(data);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/test/java/org/apache/tamaya/format/FlattenedDefaultPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/test/java/org/apache/tamaya/format/FlattenedDefaultPropertySourceTest.java b/modules/formats/src/test/java/org/apache/tamaya/format/FlattenedDefaultPropertySourceTest.java
deleted file mode 100644
index adc94f6..0000000
--- a/modules/formats/src/test/java/org/apache/tamaya/format/FlattenedDefaultPropertySourceTest.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.format;
-
-import org.apache.tamaya.format.formats.PropertiesFormat;
-import org.apache.tamaya.spi.PropertySource;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-/**
- * Tests for {@link org.apache.tamaya.format.FlattenedDefaultPropertySource}.
- */
-public class FlattenedDefaultPropertySourceTest {
-
- @Test
- public void testGetName() throws Exception {
- FlattenedDefaultPropertySource ps = new FlattenedDefaultPropertySource(createConfigurationData("test1"));
- assertEquals("test1", ps.getName());
- }
-
- private ConfigurationData createConfigurationData(String sourceName) {
- return ConfigurationDataBuilder.of(sourceName, new PropertiesFormat())
- .addProperty("a", "aValue").addSectionProperty("section1", "sectionKey1", "sectionValue11")
- .addSections("section1", "section12")
- .addSectionProperty("section2", "sectionKey1", "sectionValue21").build();
- }
-
- private ConfigurationData createConfigurationData(String sourceName, int ordinal) {
- return ConfigurationDataBuilder.of(sourceName, new PropertiesFormat())
- .addProperty("a", "aValue").addSectionProperty("section1", "sectionKey1", "sectionValue11")
- .addSections("section1", "section12").addProperty(PropertySource.TAMAYA_ORDINAL, String.valueOf(ordinal))
- .addSectionProperty("section2", "sectionKey1", "sectionValue21").build();
- }
-
- private ConfigurationData createConfigurationDataNoDefault(String sourceName) {
- return ConfigurationDataBuilder.of(sourceName, new PropertiesFormat())
- .addSectionProperty("section1", "sectionKey1", "sectionValue11")
- .addSections("section1", "section12")
- .addSectionProperty("section2", "sectionKey1", "sectionValue21").build();
- }
-
- @Test
- public void testGetOrdinal() throws Exception {
- FlattenedDefaultPropertySource ps = new FlattenedDefaultPropertySource(createConfigurationData("test1", 11));
- assertEquals(11, ps.getOrdinal());
- }
-
- @Test
- public void testGet() throws Exception {
- FlattenedDefaultPropertySource ps = new FlattenedDefaultPropertySource(createConfigurationData("test2"));
- assertEquals("aValue", ps.get("a").get("a"));
- assertNotNull(ps.get("section1.sectionKey1").get("section1.sectionKey1"));
- assertNotNull(ps.get("section2.sectionKey1").get("section2.sectionKey1"));
- assertNull(ps.get("sectionKey1"));
- ps = new FlattenedDefaultPropertySource(createConfigurationDataNoDefault("test2"));
- assertEquals("sectionValue11", ps.get("section1.sectionKey1").get("section1.sectionKey1"));
- assertEquals("sectionValue21", ps.get("section2.sectionKey1").get("section2.sectionKey1"));
- assertNull(ps.get("a"));
- assertNull(ps.get("section1"));
- }
-
- @Test
- public void testGetProperties() throws Exception {
- FlattenedDefaultPropertySource ps = new FlattenedDefaultPropertySource(createConfigurationData("test3"));
- assertNotNull(ps.getProperties());
- assertEquals("aValue", ps.getProperties().get("a"));
- assertNotNull(ps.getProperties().get("section1.sectionKey1"));
- assertNotNull(ps.getProperties().get("section2.sectionKey1"));
- assertNull(ps.getProperties().get("section1.sectionKey2"));
- assertNull(ps.getProperties().get("section2.sectionKey2"));
- assertNull(ps.getProperties().get("sectionKey1"));
- assertNull(ps.getProperties().get("sectionKey2"));
- ps = new FlattenedDefaultPropertySource(createConfigurationDataNoDefault("test3"));
- assertNotNull(ps.getProperties());
- assertEquals("sectionValue11", ps.getProperties().get("section1.sectionKey1"));
- assertEquals("sectionValue21", ps.getProperties().get("section2.sectionKey1"));
- assertNull(ps.get("section1"));
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/test/java/org/apache/tamaya/format/InputStreamFactoryTest.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/test/java/org/apache/tamaya/format/InputStreamFactoryTest.java b/modules/formats/src/test/java/org/apache/tamaya/format/InputStreamFactoryTest.java
deleted file mode 100644
index c05da09..0000000
--- a/modules/formats/src/test/java/org/apache/tamaya/format/InputStreamFactoryTest.java
+++ /dev/null
@@ -1,145 +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.format;
-
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-public class InputStreamFactoryTest {
-
- @Test(expected = NullPointerException.class)
- public void ctorEnforcesNonNullOriginal() throws IOException {
- new InputStreamFactory(null);
- }
-
- @Test
- public void givenStreamIsClosedInTryWithResourcesConstruct() throws Exception {
- InputStream stream = mock(InputStream.class);
- doReturn(34).when(stream).read();
-
- InputStreamFactory factory = new InputStreamFactory(stream);
- verify(stream).close();
- for (int i = 0; i < 100; i++) {
- try (InputStream in = factory.createInputStream()) {
- in.read();
- }
- }
- verify(stream).close();
- }
-
- @Test
- public void callToReadIsNotForwardedCallToWrapped() throws IOException {
- InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
- InputStreamFactory closer = new InputStreamFactory(stream);
- byte[] byteArray = new byte[4];
- for (int i = 0; i < 100; i++) {
- InputStream is = closer.createInputStream();
- assertThat(is.read(byteArray), equalTo(4));
- }
- }
-
-
- @Test
- public void callToSkipIsForwardedToWrapped() throws IOException {
- InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
- InputStreamFactory closer = new InputStreamFactory(stream);
- for (int i = 0; i < 100; i++) {
- InputStream is = closer.createInputStream();
- assertThat(is.skip(2L), equalTo(2L));
- }
- }
-
-
- @Test
- public void callToAvailableIsNotForwardedToWrapped() throws IOException {
- InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
- InputStreamFactory closer = new InputStreamFactory(stream);
- for (int i = 0; i < 100; i++) {
- InputStream is = closer.createInputStream();
- assertThat(is.available(), equalTo(4));
- }
- }
-
- @Test
- public void callToCloseIsNotForwardedToWrapped() throws IOException {
- InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
- InputStreamFactory closer = new InputStreamFactory(stream);
- for (int i = 0; i < 100; i++) {
- InputStream is = closer.createInputStream();
- is.close();
- }
- }
-
- @Test
- public void callToMarkIsNotForwardedToWrapped() throws IOException {
-// ArgumentCaptor<Integer> captor = ArgumentCaptor.forClass(Integer.class);
- InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
- InputStreamFactory closer = new InputStreamFactory(stream);
- for (int i = 0; i < 100; i++) {
- InputStream is = closer.createInputStream();
- is.mark(2);
- }
- }
-
-
- @Test
- public void callToResetIsNotForwardedToWrapped() throws IOException {
- InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
- InputStreamFactory closer = new InputStreamFactory(stream);
- for (int i = 0; i < 100; i++) {
- InputStream is = closer.createInputStream();
- is.reset();
- }
- }
-
- @Test
- public void callToMarkSupportedIsNotForwardedToWrapped() throws IOException {
- InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
- InputStreamFactory closer = new InputStreamFactory(stream);
- for (int i = 0; i < 100; i++) {
- InputStream is = closer.createInputStream();
- assertThat(is.markSupported(), is(true));
- }
- }
-
- @Test
- public void callToReadIsForwardedToWrapped() throws IOException {
- InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
- InputStreamFactory closer = new InputStreamFactory(stream);
- for (int i = 0; i < 100; i++) {
- InputStream is = closer.createInputStream();
- assertThat(is.read(), equalTo(1));
- assertThat(is.read(), equalTo(2));
- assertThat(is.read(), equalTo(3));
- assertThat(is.read(), equalTo(4));
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/test/resources/Test.ini
----------------------------------------------------------------------
diff --git a/modules/formats/src/test/resources/Test.ini b/modules/formats/src/test/resources/Test.ini
deleted file mode 100644
index 906a1e6..0000000
--- a/modules/formats/src/test/resources/Test.ini
+++ /dev/null
@@ -1,26 +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 current 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.
-#
-
-aGeneralEntry=blabla
-
-[MySection1]
-sectionEntry1=value1
-
-[MySection2]
-sectionEntry2=value2
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/test/resources/Test.properties
----------------------------------------------------------------------
diff --git a/modules/formats/src/test/resources/Test.properties b/modules/formats/src/test/resources/Test.properties
deleted file mode 100644
index ced544b..0000000
--- a/modules/formats/src/test/resources/Test.properties
+++ /dev/null
@@ -1,21 +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 current 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.
-#
-aGeneralEntry=blabla
-MySection1.sectionEntry1=value1
-MySection2.sectionEntry2=value2
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/yaml/pom.xml
----------------------------------------------------------------------
diff --git a/modules/formats/yaml/pom.xml b/modules/formats/yaml/pom.xml
new file mode 100644
index 0000000..0ec6b38
--- /dev/null
+++ b/modules/formats/yaml/pom.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-formats-all</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>tamaya-yaml</artifactId>
+ <name>Apache Tamaya YAML Support</name>
+ <packaging>bundle</packaging>
+ <inceptionYear>2016</inceptionYear>
+
+ <properties>
+ <jdkVersion>1.7</jdkVersion>
+ <snakeyaml.version>1.17</snakeyaml.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-core</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-formats</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.yaml</groupId>
+ <artifactId>snakeyaml</artifactId>
+ <version>${snakeyaml.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>java-hamcrest</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copyMain</id>
+ <phase>process-test-sources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}</outputDirectory>
+ <overWriteReleases>false</overWriteReleases>
+ <overWriteSnapshots>false</overWriteSnapshots>
+ <overWriteIfNewer>true</overWriteIfNewer>
+ <stripVersion>true</stripVersion>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.jboss.arquillian.daemon</groupId>
+ <artifactId>arquillian-daemon-main</artifactId>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.tamaya.json
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/yaml/src/main/java/org/apache/tamaya/json/YAMLFormat.java
----------------------------------------------------------------------
diff --git a/modules/formats/yaml/src/main/java/org/apache/tamaya/json/YAMLFormat.java b/modules/formats/yaml/src/main/java/org/apache/tamaya/json/YAMLFormat.java
new file mode 100644
index 0000000..06e431e
--- /dev/null
+++ b/modules/formats/yaml/src/main/java/org/apache/tamaya/json/YAMLFormat.java
@@ -0,0 +1,156 @@
+/*
+ * 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.json;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.format.ConfigurationData;
+import org.apache.tamaya.format.ConfigurationDataBuilder;
+import org.apache.tamaya.format.ConfigurationFormat;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static java.lang.String.format;
+
+
+/**
+ * Implementation of the {@link org.apache.tamaya.format.ConfigurationFormat}
+ * able to read configuration properties represented in JSON
+ *
+ * @see <a href="http://www.json.org">JSON format specification</a>
+ */
+public class YAMLFormat implements ConfigurationFormat {
+ /**
+ * THe logger.
+ */
+ private static final Logger LOG = Logger.getLogger(YAMLFormat.class.getName());
+
+ /**
+ * Constructor, itniaitlizing zhe JSON reader factory.
+ */
+ public YAMLFormat(){
+ }
+
+ @Override
+ public String getName() {
+ return "yaml";
+ }
+
+ @Override
+ public boolean accepts(URL url) {
+ return Objects.requireNonNull(url).getPath().endsWith(".yaml");
+ }
+
+ @Override
+ public ConfigurationData readConfiguration(String resource, InputStream inputStream) {
+ try( InputStream in = inputStream;) {
+ Map<String, String> values = readConfig(resource, inputStream);
+ return ConfigurationDataBuilder.of(resource, this).addProperties(values)
+ .build();
+ } catch (Exception e) {
+ throw new ConfigException("Failed to read data from " + resource, e);
+ }
+ }
+
+ /**
+ * Reads the configuration.
+ * @param inputStream the input stream, not null.
+ * @param resource resource URI, not null.
+ * @return the configuration read from the given resource URI.
+ * @throws ConfigException if resource URI cannot be read.
+ */
+ protected Map<String, String> readConfig(String resource, InputStream inputStream) {
+ try{
+ Yaml yaml = new Yaml();
+ HashMap<String, String> values = new HashMap<>();
+ Object config = yaml.load(inputStream);
+ mapYamlIntoProperties(config, values);
+ if(LOG.isLoggable(Level.FINEST)){
+ LOG.finest("Read data from " + resource + " : " + values);
+ }
+ return values;
+ }catch (Throwable t) {
+ throw new ConfigException(format("Failed to read properties from %s", resource), t);
+ }
+ }
+ /**
+ * Reads the configuration.
+ * @param urlResource soure of the configuration.
+ * @return the configuration read from the given resource URL.
+ * @throws ConfigException if resource URL cannot be read.
+ */
+ protected Map<String, String> readConfig(URL urlResource) {
+ try (InputStream is = urlResource.openStream()) {
+ return readConfig(urlResource.toExternalForm(), is);
+ }
+ catch (Throwable t) {
+ throw new ConfigException(format("Failed to read properties from %s", urlResource.toExternalForm()), t);
+ }
+ }
+
+ private void mapYamlIntoProperties(Object config, HashMap<String, String> values) {
+ mapYamlIntoProperties("", config, values);
+ }
+
+ /**
+ * Maps the given config item (could be a String, a collection type or something else returned by the yaml parser
+ * to a key/value pair and adds it to {@code values} (hereby honoring the prefix as a key to be used.).
+ * Collection types are recursively to remapped hereby extending the given prefix as needed and recursively
+ * delegate mapping of values contained.
+ * @param prefix the prefix or key evaluated so far, never null (but can be empty for root entries).
+ * @param config the config value. Could be a single value or a collection type.
+ * @param values the properties where items identified must be written into. These properties are going to be
+ * returned as result of the format reading operation ans integrated into the overall configuration
+ * map.
+ */
+ protected void mapYamlIntoProperties(String prefix, Object config, HashMap<String, String> values) {
+ // add further data types supported by yaml, e.g. date, ...
+ if(config instanceof List){
+ StringBuilder b = new StringBuilder();
+ for(Object val:((List<Object>)config)){
+ b.append(mapValueToString(val));
+ b.append(",");
+ }
+ if(b.length()>0){
+ b.setLength(b.length()-1);
+ }
+ values.put(prefix, b.toString());
+ values.put("_"+prefix+".collection-type", "List");
+ } else if(config instanceof Map){
+ for(Map.Entry<String,Object> en:((Map<String,Object>)config).entrySet()){
+ String newPrefix = prefix.isEmpty()?en.getKey():prefix +"."+en.getKey();
+ mapYamlIntoProperties(newPrefix, en.getValue(), values);
+ }
+ } else{
+ values.put(prefix, mapValueToString(config));
+ }
+ }
+
+ protected String mapValueToString(Object val) {
+ return String.valueOf(val);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/yaml/src/main/java/org/apache/tamaya/json/YAMLPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/formats/yaml/src/main/java/org/apache/tamaya/json/YAMLPropertySource.java b/modules/formats/yaml/src/main/java/org/apache/tamaya/json/YAMLPropertySource.java
new file mode 100644
index 0000000..e29d2e7
--- /dev/null
+++ b/modules/formats/yaml/src/main/java/org/apache/tamaya/json/YAMLPropertySource.java
@@ -0,0 +1,100 @@
+/*
+ * 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.json;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.net.URL;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+
+/**
+ * Property source based on a JSON file.
+ */
+public class YAMLPropertySource implements PropertySource {
+ /** The underlying resource. */
+ private final URL urlResource;
+ /** The values read. */
+ private final Map<String, String> values;
+ /** The evaluated ordinal. */
+ private int ordinal;
+ /** The format implementation used for parsing. */
+ private YAMLFormat format = new YAMLFormat();
+
+ /**
+ * Constructor, hereby using 0 as the default ordinal.
+ * @param resource the resource modelled as URL, not null.
+ */
+ public YAMLPropertySource(URL resource) {
+ this(resource, 0);
+ }
+
+ /**
+ * Constructor.
+ * @param resource the resource modelled as URL, not null.
+ * @param defaultOrdinal the defaultOrdinal to be used.
+ */
+ public YAMLPropertySource(URL resource, int defaultOrdinal) {
+ urlResource = Objects.requireNonNull(resource);
+ this.ordinal = defaultOrdinal; // may be overriden by read...
+ this.values = format.readConfig(urlResource);
+ if (this.values.containsKey(TAMAYA_ORDINAL)) {
+ this.ordinal = Integer.parseInt(this.values.get(TAMAYA_ORDINAL));
+ }
+ }
+
+ @Override
+ public int getOrdinal() {
+ PropertyValue configuredOrdinal = get(TAMAYA_ORDINAL);
+ if(configuredOrdinal!=null){
+ try{
+ return Integer.parseInt(configuredOrdinal.getValue());
+ } catch(Exception e){
+ Logger.getLogger(getClass().getName()).log(Level.WARNING,
+ "Configured Ordinal is not an int number: " + configuredOrdinal, e);
+ }
+ }
+ return ordinal;
+ }
+
+ @Override
+ public String getName() {
+ return urlResource.toExternalForm();
+ }
+
+ @Override
+ public PropertyValue get(String key) {
+ return PropertyValue.of(key, getProperties().get(key), getName());
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return Collections.unmodifiableMap(values);
+ }
+
+
+ @Override
+ public boolean isScannable() {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/yaml/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
----------------------------------------------------------------------
diff --git a/modules/formats/yaml/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat b/modules/formats/yaml/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
new file mode 100644
index 0000000..1b5d57d
--- /dev/null
+++ b/modules/formats/yaml/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.json.YAMLFormat
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/yaml/src/test/java/org/apache/tamaya/json/YAMLFormatTest.java
----------------------------------------------------------------------
diff --git a/modules/formats/yaml/src/test/java/org/apache/tamaya/json/YAMLFormatTest.java b/modules/formats/yaml/src/test/java/org/apache/tamaya/json/YAMLFormatTest.java
new file mode 100644
index 0000000..0f0e589
--- /dev/null
+++ b/modules/formats/yaml/src/test/java/org/apache/tamaya/json/YAMLFormatTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.json;
+
+
+import org.apache.tamaya.format.ConfigurationData;
+import org.apache.tamaya.format.FlattenedDefaultPropertySource;
+import org.apache.tamaya.spi.PropertySource;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class YAMLFormatTest {
+ private final YAMLFormat format = new YAMLFormat();
+
+ @Test
+ public void testAcceptURL() throws MalformedURLException {
+ assertTrue(format.accepts(new URL("http://127.0.0.1/anyfile.yaml")));
+ }
+
+ @Test
+ public void testAcceptURL_BC1() throws MalformedURLException {
+ assertFalse(format.accepts(new URL("http://127.0.0.1/anyfile.YAML")));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testAcceptURL_BC2() throws MalformedURLException {
+ assertFalse(format.accepts(null));
+ }
+
+ @Test
+ public void testAcceptURL_BC3() throws MalformedURLException {
+ assertFalse(format.accepts(new URL("http://127.0.0.1/anyfile.docx")));
+ }
+
+ @Test
+ public void testRead() throws IOException {
+ URL configURL = YAMLPropertySourceTest.class.getResource("/configs/valid/contact.yaml");
+ assertTrue(format.accepts(configURL));
+ ConfigurationData data = format.readConfiguration(configURL.toString(), configURL.openStream());
+ assertNotNull(data);
+ for(Map.Entry<String,String> en:data.getDefaultProperties().entrySet()) {
+ System.out.println(en.getKey() + " -> " + en.getValue());
+ }
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/yaml/src/test/java/org/apache/tamaya/json/YAMLPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/modules/formats/yaml/src/test/java/org/apache/tamaya/json/YAMLPropertySourceTest.java b/modules/formats/yaml/src/test/java/org/apache/tamaya/json/YAMLPropertySourceTest.java
new file mode 100644
index 0000000..7f1c7a3
--- /dev/null
+++ b/modules/formats/yaml/src/test/java/org/apache/tamaya/json/YAMLPropertySourceTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.json;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertySource;
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+
+import java.net.URL;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+public class YAMLPropertySourceTest {
+
+ @Test
+ public void testYamlWithOrdinal() throws Exception {
+ URL configURL = YAMLPropertySourceTest.class.getResource("/configs/valid/test-with-prio.yaml");
+
+ assertThat(configURL, CoreMatchers.notNullValue());
+
+ YAMLPropertySource source = new YAMLPropertySource(configURL, 4);
+ assertEquals(source.getOrdinal(), 16784);
+ }
+
+ @Test
+ public void testYamlDefaultOrdinal() throws Exception {
+ URL configURL = YAMLPropertySourceTest.class.getResource("/configs/valid/test.yaml");
+
+ assertThat(configURL, CoreMatchers.notNullValue());
+
+ YAMLPropertySource source = new YAMLPropertySource(configURL, 4);
+ assertEquals(source.getOrdinal(), 4);
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/yaml/src/test/resources/configs/valid/contact.yaml
----------------------------------------------------------------------
diff --git a/modules/formats/yaml/src/test/resources/configs/valid/contact.yaml b/modules/formats/yaml/src/test/resources/configs/valid/contact.yaml
new file mode 100644
index 0000000..95d5a03
--- /dev/null
+++ b/modules/formats/yaml/src/test/resources/configs/valid/contact.yaml
@@ -0,0 +1,46 @@
+#
+# 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 current 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.
+#
+invoice: 34843
+date : 2001-01-23
+bill-to: &id001
+ given : Chris
+ family : Dumars
+ address:
+ lines: |
+ 458 Walkman Dr.
+ Suite #292
+ city : Royal Oak
+ state : MI
+ postal : 48046
+ship-to: *id001
+product:
+ - sku : BL394D
+ quantity : 4
+ description : Basketball
+ price : 450.00
+ - sku : BL4438H
+ quantity : 1
+ description : Super Hoop
+ price : 2392.00
+tax : 251.42
+total: 4443.52
+comments: >
+ Late afternoon is best.
+ Backup contact is Nancy
+ Billsmer @ 338-4338.
\ No newline at end of file
[11/15] incubator-tamaya-extensions git commit: TAMAYA-189: Moved
format and injection modules into separate subtrees.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/test/java/org/apache/tamaya/format/InputStreamFactoryTest.java
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/test/java/org/apache/tamaya/format/InputStreamFactoryTest.java b/modules/formats/common/src/test/java/org/apache/tamaya/format/InputStreamFactoryTest.java
new file mode 100644
index 0000000..c05da09
--- /dev/null
+++ b/modules/formats/common/src/test/java/org/apache/tamaya/format/InputStreamFactoryTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.format;
+
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class InputStreamFactoryTest {
+
+ @Test(expected = NullPointerException.class)
+ public void ctorEnforcesNonNullOriginal() throws IOException {
+ new InputStreamFactory(null);
+ }
+
+ @Test
+ public void givenStreamIsClosedInTryWithResourcesConstruct() throws Exception {
+ InputStream stream = mock(InputStream.class);
+ doReturn(34).when(stream).read();
+
+ InputStreamFactory factory = new InputStreamFactory(stream);
+ verify(stream).close();
+ for (int i = 0; i < 100; i++) {
+ try (InputStream in = factory.createInputStream()) {
+ in.read();
+ }
+ }
+ verify(stream).close();
+ }
+
+ @Test
+ public void callToReadIsNotForwardedCallToWrapped() throws IOException {
+ InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
+ InputStreamFactory closer = new InputStreamFactory(stream);
+ byte[] byteArray = new byte[4];
+ for (int i = 0; i < 100; i++) {
+ InputStream is = closer.createInputStream();
+ assertThat(is.read(byteArray), equalTo(4));
+ }
+ }
+
+
+ @Test
+ public void callToSkipIsForwardedToWrapped() throws IOException {
+ InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
+ InputStreamFactory closer = new InputStreamFactory(stream);
+ for (int i = 0; i < 100; i++) {
+ InputStream is = closer.createInputStream();
+ assertThat(is.skip(2L), equalTo(2L));
+ }
+ }
+
+
+ @Test
+ public void callToAvailableIsNotForwardedToWrapped() throws IOException {
+ InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
+ InputStreamFactory closer = new InputStreamFactory(stream);
+ for (int i = 0; i < 100; i++) {
+ InputStream is = closer.createInputStream();
+ assertThat(is.available(), equalTo(4));
+ }
+ }
+
+ @Test
+ public void callToCloseIsNotForwardedToWrapped() throws IOException {
+ InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
+ InputStreamFactory closer = new InputStreamFactory(stream);
+ for (int i = 0; i < 100; i++) {
+ InputStream is = closer.createInputStream();
+ is.close();
+ }
+ }
+
+ @Test
+ public void callToMarkIsNotForwardedToWrapped() throws IOException {
+// ArgumentCaptor<Integer> captor = ArgumentCaptor.forClass(Integer.class);
+ InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
+ InputStreamFactory closer = new InputStreamFactory(stream);
+ for (int i = 0; i < 100; i++) {
+ InputStream is = closer.createInputStream();
+ is.mark(2);
+ }
+ }
+
+
+ @Test
+ public void callToResetIsNotForwardedToWrapped() throws IOException {
+ InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
+ InputStreamFactory closer = new InputStreamFactory(stream);
+ for (int i = 0; i < 100; i++) {
+ InputStream is = closer.createInputStream();
+ is.reset();
+ }
+ }
+
+ @Test
+ public void callToMarkSupportedIsNotForwardedToWrapped() throws IOException {
+ InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
+ InputStreamFactory closer = new InputStreamFactory(stream);
+ for (int i = 0; i < 100; i++) {
+ InputStream is = closer.createInputStream();
+ assertThat(is.markSupported(), is(true));
+ }
+ }
+
+ @Test
+ public void callToReadIsForwardedToWrapped() throws IOException {
+ InputStream stream = new ByteArrayInputStream(new byte[]{1, 2, 3, 4});
+ InputStreamFactory closer = new InputStreamFactory(stream);
+ for (int i = 0; i < 100; i++) {
+ InputStream is = closer.createInputStream();
+ assertThat(is.read(), equalTo(1));
+ assertThat(is.read(), equalTo(2));
+ assertThat(is.read(), equalTo(3));
+ assertThat(is.read(), equalTo(4));
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/test/resources/Test.ini
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/test/resources/Test.ini b/modules/formats/common/src/test/resources/Test.ini
new file mode 100644
index 0000000..906a1e6
--- /dev/null
+++ b/modules/formats/common/src/test/resources/Test.ini
@@ -0,0 +1,26 @@
+#
+# 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 current 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.
+#
+
+aGeneralEntry=blabla
+
+[MySection1]
+sectionEntry1=value1
+
+[MySection2]
+sectionEntry2=value2
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/common/src/test/resources/Test.properties
----------------------------------------------------------------------
diff --git a/modules/formats/common/src/test/resources/Test.properties b/modules/formats/common/src/test/resources/Test.properties
new file mode 100644
index 0000000..ced544b
--- /dev/null
+++ b/modules/formats/common/src/test/resources/Test.properties
@@ -0,0 +1,21 @@
+#
+# 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 current 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.
+#
+aGeneralEntry=blabla
+MySection1.sectionEntry1=value1
+MySection2.sectionEntry2=value2
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/pom.xml
----------------------------------------------------------------------
diff --git a/modules/formats/json/pom.xml b/modules/formats/json/pom.xml
new file mode 100644
index 0000000..8346231
--- /dev/null
+++ b/modules/formats/json/pom.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-formats-all</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>tamaya-json</artifactId>
+ <name>Apache Tamaya JSON Support</name>
+ <packaging>bundle</packaging>
+ <inceptionYear>2015</inceptionYear>
+
+ <properties>
+ <jdkVersion>1.7</jdkVersion>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-core</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-formats</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-json_1.0_spec</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.johnzon</groupId>
+ <artifactId>johnzon-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.daemon</groupId>
+ <artifactId>arquillian-daemon-container-managed</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.daemon</groupId>
+ <artifactId>arquillian-daemon-container-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.daemon</groupId>
+ <artifactId>arquillian-daemon-main</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.daemon</groupId>
+ <artifactId>arquillian-daemon-protocol-arquillian</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.daemon</groupId>
+ <artifactId>arquillian-daemon-protocol-wire</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.daemon</groupId>
+ <artifactId>arquillian-daemon-server</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.junit</groupId>
+ <artifactId>arquillian-junit-container</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>java-hamcrest</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copyMain</id>
+ <phase>process-test-sources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}</outputDirectory>
+ <overWriteReleases>false</overWriteReleases>
+ <overWriteSnapshots>false</overWriteSnapshots>
+ <overWriteIfNewer>true</overWriteIfNewer>
+ <stripVersion>true</stripVersion>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.jboss.arquillian.daemon</groupId>
+ <artifactId>arquillian-daemon-main</artifactId>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.tamaya.json
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/main/java/org/apache/tamaya/json/JSONFormat.java
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/main/java/org/apache/tamaya/json/JSONFormat.java b/modules/formats/json/src/main/java/org/apache/tamaya/json/JSONFormat.java
new file mode 100644
index 0000000..8bdd414
--- /dev/null
+++ b/modules/formats/json/src/main/java/org/apache/tamaya/json/JSONFormat.java
@@ -0,0 +1,85 @@
+/*
+ * 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.json;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.format.ConfigurationData;
+import org.apache.tamaya.format.ConfigurationDataBuilder;
+import org.apache.tamaya.format.ConfigurationFormat;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import javax.json.Json;
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import javax.json.JsonReaderFactory;
+
+/**
+ * Implementation of the {@link org.apache.tamaya.format.ConfigurationFormat}
+ * able to read configuration properties represented in JSON
+ *
+ * @see <a href="http://www.json.org">JSON format specification</a>
+ */
+public class JSONFormat implements ConfigurationFormat {
+ /** Property that make Johnzon accept commentc. */
+ public static final String JOHNZON_SUPPORTS_COMMENTS_PROP = "org.apache.johnzon.supports-comments";
+ /** The reader factory used. */
+ private final JsonReaderFactory readerFactory;
+
+ /**
+ * Constructor, itniaitlizing zhe JSON reader factory.
+ */
+ public JSONFormat(){
+ Map<String, Object> config = new HashMap<>();
+ config.put(JOHNZON_SUPPORTS_COMMENTS_PROP, true);
+ this.readerFactory = Json.createReaderFactory(config);
+ }
+
+ @Override
+ public String getName() {
+ return "json";
+ }
+
+ @Override
+ public boolean accepts(URL url) {
+ return Objects.requireNonNull(url).getPath().endsWith(".json");
+ }
+
+ @Override
+ public ConfigurationData readConfiguration(String resource, InputStream inputStream) {
+
+ try {
+ final JsonReader reader = this.readerFactory.createReader(inputStream, Charset.forName("UTF-8"));
+ JsonObject root = reader.readObject();
+ HashMap<String, String> values = new HashMap<>();
+ JSONVisitor visitor = new JSONVisitor(root, values);
+ visitor.run();
+ return ConfigurationDataBuilder.of(resource, this).addProperties(values)
+ .build();
+ } catch (JsonException e) {
+ throw new ConfigException("Failed to read data from " + resource, e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/main/java/org/apache/tamaya/json/JSONPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/main/java/org/apache/tamaya/json/JSONPropertySource.java b/modules/formats/json/src/main/java/org/apache/tamaya/json/JSONPropertySource.java
new file mode 100644
index 0000000..43cfa73
--- /dev/null
+++ b/modules/formats/json/src/main/java/org/apache/tamaya/json/JSONPropertySource.java
@@ -0,0 +1,149 @@
+/*
+ * 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.json;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonReaderFactory;
+import javax.json.JsonStructure;
+
+import static java.lang.String.format;
+
+/**
+ * Property source based on a JSON file.
+ */
+public class JSONPropertySource implements PropertySource {
+ /** Constant for enabling comments in Johnzon. */
+ public static final String JOHNZON_SUPPORTS_COMMENTS_PROP = "org.apache.johnzon.supports-comments";
+
+ /** The underlying resource. */
+ private final URL urlResource;
+ /** The values read. */
+ private final Map<String, String> values;
+ /** The evaluated ordinal. */
+ private int ordinal;
+ /** The JSON reader factory used. */
+ private JsonReaderFactory readerFactory = initReaderFactory();
+
+ /** Initializes the factory to be used for creating readers. */
+ private JsonReaderFactory initReaderFactory() {
+ Map<String, Object> config = new HashMap<>();
+ config.put(JOHNZON_SUPPORTS_COMMENTS_PROP, true);
+ return Json.createReaderFactory(config);
+ }
+
+ /**
+ * Constructor, hereby using 0 as the default ordinal.
+ * @param resource the resource modelled as URL, not null.
+ */
+ public JSONPropertySource(URL resource) {
+ this(resource, 0);
+ }
+
+ /**
+ * Constructor.
+ * @param resource the resource modelled as URL, not null.
+ * @param defaultOrdinal the defaultOrdinal to be used.
+ */
+ public JSONPropertySource(URL resource, int defaultOrdinal) {
+ urlResource = Objects.requireNonNull(resource);
+ this.ordinal = defaultOrdinal; // may be overriden by read...
+ this.values = readConfig(urlResource);
+ if (this.values.containsKey(TAMAYA_ORDINAL)) {
+ this.ordinal = Integer.parseInt(this.values.get(TAMAYA_ORDINAL));
+ }
+ Map<String, Object> config = new HashMap<>();
+ config.put(JOHNZON_SUPPORTS_COMMENTS_PROP, true);
+ this.readerFactory = Json.createReaderFactory(config);
+ }
+
+
+ @Override
+ public int getOrdinal() {
+ PropertyValue configuredOrdinal = get(TAMAYA_ORDINAL);
+ if(configuredOrdinal!=null){
+ try{
+ return Integer.parseInt(configuredOrdinal.getValue());
+ } catch(Exception e){
+ Logger.getLogger(getClass().getName()).log(Level.WARNING,
+ "Configured Ordinal is not an int number: " + configuredOrdinal, e);
+ }
+ }
+ return ordinal;
+ }
+
+ @Override
+ public String getName() {
+ return urlResource.toExternalForm();
+ }
+
+ @Override
+ public PropertyValue get(String key) {
+ return PropertyValue.of(key, getProperties().get(key), getName());
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return Collections.unmodifiableMap(values);
+ }
+
+ /**
+ * Reads the configuration.
+ * @param urlResource soure of the configuration.
+ * @return the configuration read from the given resource URL.
+ * @throws ConfigException if resource URL cannot be read.
+ */
+ protected Map<String, String> readConfig(URL urlResource) {
+ try (InputStream is = urlResource.openStream()) {
+ JsonStructure root = this.readerFactory.createReader(is, Charset.forName("UTF-8")).read();
+
+ // Test added. H. Saly, 15. Aug. 2015
+ if (!(root instanceof JsonObject)) {
+ throw new ConfigException("Currently only JSON objects are supported");
+ }
+
+ Map<String, String> values = new HashMap<>();
+ JSONVisitor visitor = new JSONVisitor((JsonObject)root, values);
+ visitor.run();
+ return values;
+ }
+ catch (Throwable t) {
+ throw new ConfigException(format("Failed to read properties from %s", urlResource.toExternalForm()), t);
+ }
+ }
+
+ @Override
+ public boolean isScannable() {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/main/java/org/apache/tamaya/json/JSONVisitor.java
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/main/java/org/apache/tamaya/json/JSONVisitor.java b/modules/formats/json/src/main/java/org/apache/tamaya/json/JSONVisitor.java
new file mode 100644
index 0000000..2135ec5
--- /dev/null
+++ b/modules/formats/json/src/main/java/org/apache/tamaya/json/JSONVisitor.java
@@ -0,0 +1,119 @@
+/*
+ * 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.json;
+
+import org.apache.tamaya.ConfigException;
+
+import java.util.*;
+
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.JsonString;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+
+/**
+ * Visitor implementation to read a JSON formatted input source.
+ */
+class JSONVisitor {
+ private final JsonObject rootNode;
+ private final Map<String, String> targetStore;
+
+ JSONVisitor(JsonObject startNode, Map<String, String> target) {
+ rootNode = startNode;
+ targetStore = target;
+ }
+
+ public void run() {
+ Deque<VisitingContext> stack = new ArrayDeque<>();
+
+ stack.add(new VisitingContext(rootNode));
+ boolean goOn = stack.peek().hasNext();
+
+ if (goOn) {
+ do {
+ Map.Entry<String, JsonValue> current = stack.peek().nextElement();
+
+ if (!(current.getValue() instanceof JsonStructure)) {
+ String key = stack.peek().getNSPrefix() + current.getKey();
+ String value;
+ JsonValue jsonValue = current.getValue();
+ switch(jsonValue.getValueType()) {
+ case NULL: value = null; break;
+ case FALSE: value = Boolean.FALSE.toString(); break;
+ case TRUE: value = Boolean.TRUE.toString(); break;
+ case NUMBER: value = jsonValue.toString(); break;
+ case STRING: value = ((JsonString) jsonValue).getString(); break;
+ default:
+ throw new ConfigException("Internal failure while processing JSON document.");
+ }
+
+ targetStore.put(key, value);
+ } else if (current.getValue() instanceof JsonObject) {
+ String key = stack.peek().getNSPrefix() + current.getKey();
+ JsonObject node = (JsonObject) current.getValue();
+ stack.push(new VisitingContext(node, key));
+ } else if (current.getValue() instanceof JsonArray) {
+ throw new ConfigException("Arrays are not supported at the moment.");
+ } else {
+ throw new ConfigException("Internal failure while processing JSON document.");
+ }
+
+ goOn = stack.peek().hasNext();
+
+ while (!goOn && stack.size() > 0) {
+ stack.remove();
+ goOn = (stack.size() > 0) && stack.peek().hasNext();
+ }
+ } while (goOn);
+ }
+ }
+
+ /**
+ * Context for a sub context visited.
+ */
+ private static class VisitingContext {
+ private final String namespace;
+ private final JsonObject node;
+ private final Iterator<Map.Entry<String, JsonValue>> elements;
+
+ public VisitingContext(JsonObject node) {
+ this(node, "");
+ }
+
+ public VisitingContext(JsonObject rootNode, String currentNamespace) {
+ namespace = currentNamespace;
+ node = rootNode;
+ elements = node.entrySet().iterator();
+ }
+
+ public Map.Entry<String, JsonValue> nextElement() {
+ return elements.next();
+ }
+
+
+ public boolean hasNext() {
+ return elements.hasNext();
+ }
+
+ public String getNSPrefix() {
+ return namespace.isEmpty() ? namespace : namespace + ".";
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat b/modules/formats/json/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
new file mode 100644
index 0000000..a843cbe
--- /dev/null
+++ b/modules/formats/json/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.json.JSONFormat
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/java/org/apache/tamaya/json/CommonJSONTestCaseCollection.java
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/java/org/apache/tamaya/json/CommonJSONTestCaseCollection.java b/modules/formats/json/src/test/java/org/apache/tamaya/json/CommonJSONTestCaseCollection.java
new file mode 100644
index 0000000..946878c
--- /dev/null
+++ b/modules/formats/json/src/test/java/org/apache/tamaya/json/CommonJSONTestCaseCollection.java
@@ -0,0 +1,190 @@
+/*
+ * 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.json;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import java.net.URL;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+
+/**
+ * Class with a collection of common test cases each JSON processing
+ * class must be able to pass.
+ */
+public abstract class CommonJSONTestCaseCollection {
+
+ abstract PropertySource getPropertiesFrom(URL source) throws Exception;
+
+ @Test
+ public void canReadNonLatinCharacters() throws Exception {
+ URL configURL = JSONPropertySourceTest.class
+ .getResource("/configs/valid/cyrillic.json");
+
+ assertThat(configURL, Matchers.notNullValue());
+
+ PropertySource propertySource = getPropertiesFrom(configURL);
+
+ assertThat(propertySource.get("name"), Matchers.notNullValue());
+ assertThat(propertySource.get("name").getValue(), equalTo("\u041e\u043b\u0438\u0432\u0435\u0440"));
+ assertThat(propertySource.get("\u0444\u0430\u043c\u0438\u043b\u0438\u044f"), Matchers.notNullValue());
+ assertThat(propertySource.get("\u0444\u0430\u043c\u0438\u043b\u0438\u044f").getValue(), Matchers.equalTo("Fischer"));
+ }
+
+ @Test
+ public void canReadNestedStringOnlyJSONConfigFile() throws Exception {
+ URL configURL = JSONPropertySourceTest.class
+ .getResource("/configs/valid/simple-nested-string-only-config-1.json");
+
+ assertThat(configURL, CoreMatchers.notNullValue());
+
+ PropertySource properties = getPropertiesFrom(configURL);
+
+ assertThat(properties.getProperties().keySet(), hasSize(5));
+
+ PropertyValue keyB = properties.get("b");
+ PropertyValue keyDO = properties.get("d.o");
+ PropertyValue keyDP = properties.get("d.p");
+
+ assertThat(keyB, notNullValue());
+ assertThat(keyB.getValue(), equalTo("B"));
+ assertThat(keyDO, notNullValue());
+ assertThat(keyDO.getValue(), equalTo("O"));
+ assertThat(keyDP, Matchers.notNullValue());
+ assertThat(keyDP.getValue(), is("P"));
+ }
+
+ @Test
+ public void canReadNestedStringOnlyJSONConfigFileWithObjectInTheMiddle()
+ throws Exception {
+ URL configURL = JSONPropertySourceTest.class
+ .getResource("/configs/valid/simple-nested-string-only-config-2.json");
+
+ assertThat(configURL, CoreMatchers.notNullValue());
+
+ PropertySource properties = getPropertiesFrom(configURL);
+
+ assertThat(properties.getProperties().keySet(), hasSize(4));
+
+ PropertyValue keyA = properties.get("a");
+ PropertyValue keyDO = properties.get("b.o");
+ PropertyValue keyDP = properties.get("b.p");
+ PropertyValue keyC = properties.get("c");
+
+ assertThat(keyA, notNullValue());
+ assertThat(keyA.getValue(), is("A"));
+ assertThat(keyC, notNullValue());
+ assertThat(keyC.getValue(), equalTo("C"));
+ assertThat(keyDO, notNullValue());
+ assertThat(keyDO.getValue(), equalTo("O"));
+ assertThat(keyDP, notNullValue());
+ assertThat(keyDP.getValue(), is("P"));
+ }
+
+ @Test(expected = ConfigException.class)
+ public void canHandleIllegalJSONFileWhichContainsAnArray() throws Exception {
+ URL configURL = JSONPropertySourceTest.class.getResource("/configs/invalid/with-array.json");
+
+ assertThat(configURL, CoreMatchers.notNullValue());
+
+ getPropertiesFrom(configURL).getProperties();
+ }
+
+ @Test(expected = ConfigException.class)
+ public void canHandleIllegalJSONFileConsistingOfOneOpeningBracket() throws Exception {
+ URL configURL = JSONPropertySourceTest.class.getResource("/configs/invalid/only-opening-bracket.json");
+
+ assertThat(configURL, CoreMatchers.notNullValue());
+
+ getPropertiesFrom(configURL).getProperties();
+ }
+
+ @Test(expected = ConfigException.class)
+ public void canHandleIllegalJSONFileWhichIsEmpty() throws Exception {
+ URL configURL = JSONPropertySourceTest.class.getResource("/configs/invalid/empty-file.json");
+
+ assertThat(configURL, CoreMatchers.notNullValue());
+
+ getPropertiesFrom(configURL).getProperties();
+ }
+
+ @Test
+ public void priorityInConfigFileOverwriteExplicitlyGivenPriority() throws Exception {
+ URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/with-explicit-priority.json");
+
+ assertThat(configURL, CoreMatchers.notNullValue());
+
+ PropertySource properties = getPropertiesFrom(configURL);
+
+ assertThat(properties.getOrdinal(), is(16784));
+ }
+
+ @Test
+ public void canReadFlatStringOnlyJSONConfigFile() throws Exception {
+ URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/simple-flat-string-only-config.json");
+
+ assertThat(configURL, CoreMatchers.notNullValue());
+
+ PropertySource properties = getPropertiesFrom(configURL);
+
+ assertThat(properties.getProperties().keySet(), hasSize(3));
+
+ PropertyValue keyA = properties.get("a");
+ PropertyValue keyB = properties.get("b");
+ PropertyValue keyC = properties.get("c");
+
+ assertThat(keyA, notNullValue());
+ assertThat(keyA.getValue(), equalTo("A"));
+ assertThat(keyB, notNullValue());
+ assertThat(keyB.getValue(), is("B"));
+ assertThat(keyC, notNullValue());
+ assertThat(keyC.getValue(), is("C"));
+ }
+
+ @Test(expected = ConfigException.class)
+ public void emptyJSONFileResultsInConfigException() throws Exception {
+ URL configURL = JSONPropertySourceTest.class.getResource("/configs/invalid/empty-file.json");
+
+ assertThat(configURL, CoreMatchers.notNullValue());
+
+ PropertySource properties = getPropertiesFrom(configURL);
+
+ properties.getProperties();
+ }
+
+ @Test
+ public void canHandleEmptyJSONObject() throws Exception {
+ URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/empty-object-config.json");
+
+ assertThat(configURL, CoreMatchers.notNullValue());
+
+ PropertySource properties = getPropertiesFrom(configURL);
+
+ assertThat(properties.getProperties().keySet(), hasSize(0));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/java/org/apache/tamaya/json/JSONFormatIT.java
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/java/org/apache/tamaya/json/JSONFormatIT.java b/modules/formats/json/src/test/java/org/apache/tamaya/json/JSONFormatIT.java
new file mode 100644
index 0000000..851655e
--- /dev/null
+++ b/modules/formats/json/src/test/java/org/apache/tamaya/json/JSONFormatIT.java
@@ -0,0 +1,48 @@
+/*
+ * 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.json;
+
+import org.apache.tamaya.format.ConfigurationFormat;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.notNullValue;
+
+/**
+ * Integration tests for {@link JSONFormat}.
+ */
+public class JSONFormatIT {
+ @Test
+ public void jsonFormatCanBeFoundViaServiceLoader() throws Exception {
+ List<ConfigurationFormat> formats = ServiceContextManager.getServiceContext()
+ .getServices(ConfigurationFormat.class);
+
+ ConfigurationFormat format = null;
+ for (ConfigurationFormat f : formats) {
+ if (f instanceof JSONFormat) {
+ format = f;
+ break;
+ }
+ }
+ assertThat(format, notNullValue());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/java/org/apache/tamaya/json/JSONFormatTest.java
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/java/org/apache/tamaya/json/JSONFormatTest.java b/modules/formats/json/src/test/java/org/apache/tamaya/json/JSONFormatTest.java
new file mode 100644
index 0000000..9218046
--- /dev/null
+++ b/modules/formats/json/src/test/java/org/apache/tamaya/json/JSONFormatTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.json;
+
+
+import org.apache.tamaya.format.ConfigurationData;
+import org.apache.tamaya.format.FlattenedDefaultPropertySource;
+import org.apache.tamaya.spi.PropertySource;
+import org.junit.Test;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+public class JSONFormatTest extends CommonJSONTestCaseCollection {
+ private final JSONFormat format = new JSONFormat();
+
+ @Test(expected = NullPointerException.class)
+ public void acceptsNeedsNonNullParameter() throws Exception {
+ format.accepts(null);
+ }
+
+ @Test
+ public void aNonJSONFileBasedURLIsNotAccepted() throws Exception {
+ URL url = new URL("file:///etc/service/conf.conf");
+
+ assertThat(format.accepts(url), is(false));
+ }
+
+ @Test
+ public void aJSONFileBasedURLIsAccepted() throws Exception {
+ URL url = new URL("file:///etc/service/conf.json");
+
+ assertThat(format.accepts(url), is(true));
+ }
+
+ @Test
+ public void aHTTPBasedURLIsNotAccepted() throws Exception {
+ URL url = new URL("http://nowhere.somewhere/conf.json");
+ assertThat(format.accepts(url), is(true));
+ }
+
+ @Test
+ public void aFTPBasedURLIsNotAccepted() throws Exception {
+ URL url = new URL("ftp://nowhere.somewhere/a/b/c/d/conf.json");
+
+ assertThat(format.accepts(url), is(true));
+ }
+
+ @Override
+ PropertySource getPropertiesFrom(URL source) throws Exception {
+ try (InputStream is = source.openStream()) {
+ ConfigurationData data = format.readConfiguration(source.toString(), is);
+ return new FlattenedDefaultPropertySource(data);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/java/org/apache/tamaya/json/JSONPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/java/org/apache/tamaya/json/JSONPropertySourceTest.java b/modules/formats/json/src/test/java/org/apache/tamaya/json/JSONPropertySourceTest.java
new file mode 100644
index 0000000..9892446
--- /dev/null
+++ b/modules/formats/json/src/test/java/org/apache/tamaya/json/JSONPropertySourceTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.json;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertySource;
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+
+import java.net.URL;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+public class JSONPropertySourceTest extends CommonJSONTestCaseCollection {
+
+ @Test
+ public void tamayaOrdinalKeywordIsNotPropagatedAsNormalProperty() throws Exception {
+ URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/with-explicit-priority.json");
+
+ assertThat(configURL, CoreMatchers.notNullValue());
+
+ JSONPropertySource source = new JSONPropertySource(configURL, 4);
+ assertEquals(source.get(PropertySource.TAMAYA_ORDINAL).getValue(), "16784");
+ }
+
+ @Test(expected=ConfigException.class)
+ public void testDoNotAcceptJsonArrays() throws Exception {
+ URL configURL = JSONPropertySourceTest.class.getResource("/configs/invalid/array.json");
+
+ assertThat(configURL, CoreMatchers.notNullValue());
+
+ new JSONPropertySource(configURL);
+ }
+
+ @Override
+ PropertySource getPropertiesFrom(URL source) throws Exception {
+ return new JSONPropertySource(source);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/resources/arquillian.xml
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/resources/arquillian.xml b/modules/formats/json/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..1eeb58b
--- /dev/null
+++ b/modules/formats/json/src/test/resources/arquillian.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<arquillian xmlns="http://jboss.org/schema/arquillian"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
+ <container qualifier="daemon" default="true">
+ <configuration>
+ <property name="host">localhost</property>
+ <property name="port">12346</property>
+ <property name="serverJarFile">target/arquillian-daemon-main.jar</property>
+ </configuration>
+ </container>
+</arquillian>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/resources/configs/invalid/array.json
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/resources/configs/invalid/array.json b/modules/formats/json/src/test/resources/configs/invalid/array.json
new file mode 100644
index 0000000..0c2058a
--- /dev/null
+++ b/modules/formats/json/src/test/resources/configs/invalid/array.json
@@ -0,0 +1,21 @@
+/*
+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.
+*/
+[
+
+]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/resources/configs/invalid/empty-file.json
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/resources/configs/invalid/empty-file.json b/modules/formats/json/src/test/resources/configs/invalid/empty-file.json
new file mode 100644
index 0000000..f396085
--- /dev/null
+++ b/modules/formats/json/src/test/resources/configs/invalid/empty-file.json
@@ -0,0 +1,18 @@
+/*
+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.
+*/
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/resources/configs/invalid/only-opening-bracket.json
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/resources/configs/invalid/only-opening-bracket.json b/modules/formats/json/src/test/resources/configs/invalid/only-opening-bracket.json
new file mode 100644
index 0000000..b936f69
--- /dev/null
+++ b/modules/formats/json/src/test/resources/configs/invalid/only-opening-bracket.json
@@ -0,0 +1,19 @@
+/*
+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.
+*/
+{
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/resources/configs/invalid/with-array.json
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/resources/configs/invalid/with-array.json b/modules/formats/json/src/test/resources/configs/invalid/with-array.json
new file mode 100644
index 0000000..e623e49
--- /dev/null
+++ b/modules/formats/json/src/test/resources/configs/invalid/with-array.json
@@ -0,0 +1,27 @@
+/*
+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.
+*/
+{
+ "a" : "A",
+ "b" : {
+ "c" : "C",
+ "d" : [
+ "1", "2"
+ ]
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/resources/configs/valid/cyrillic.json
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/resources/configs/valid/cyrillic.json b/modules/formats/json/src/test/resources/configs/valid/cyrillic.json
new file mode 100644
index 0000000..b9f07b8
--- /dev/null
+++ b/modules/formats/json/src/test/resources/configs/valid/cyrillic.json
@@ -0,0 +1,22 @@
+/*
+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.
+*/
+{
+ "name" : "\u041e\u043b\u0438\u0432\u0435\u0440",
+ "\u0444\u0430\u043c\u0438\u043b\u0438\u044f" : "Fischer"
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/resources/configs/valid/empty-object-config.json
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/resources/configs/valid/empty-object-config.json b/modules/formats/json/src/test/resources/configs/valid/empty-object-config.json
new file mode 100644
index 0000000..103c28d
--- /dev/null
+++ b/modules/formats/json/src/test/resources/configs/valid/empty-object-config.json
@@ -0,0 +1,20 @@
+/*
+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.
+*/
+{
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/resources/configs/valid/simple-flat-string-only-config.json
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/resources/configs/valid/simple-flat-string-only-config.json b/modules/formats/json/src/test/resources/configs/valid/simple-flat-string-only-config.json
new file mode 100644
index 0000000..02e2cd8
--- /dev/null
+++ b/modules/formats/json/src/test/resources/configs/valid/simple-flat-string-only-config.json
@@ -0,0 +1,23 @@
+/*
+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.
+*/
+{
+ "a" : "A",
+ "b" : "B",
+ "c" : "C"
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json b/modules/formats/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json
new file mode 100644
index 0000000..fb2c4fe
--- /dev/null
+++ b/modules/formats/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json
@@ -0,0 +1,27 @@
+/*
+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.
+*/
+{
+ "a": "A",
+ "b": "B",
+ "c": "C",
+ "d": {
+ "o": "O",
+ "p": "P"
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json b/modules/formats/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json
new file mode 100644
index 0000000..b037174
--- /dev/null
+++ b/modules/formats/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json
@@ -0,0 +1,26 @@
+/*
+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.
+*/
+{
+ "a" : "A",
+ "b" : {
+ "o" : "O",
+ "p" : "P"
+ },
+ "c" : "C"
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/json/src/test/resources/configs/valid/with-explicit-priority.json
----------------------------------------------------------------------
diff --git a/modules/formats/json/src/test/resources/configs/valid/with-explicit-priority.json b/modules/formats/json/src/test/resources/configs/valid/with-explicit-priority.json
new file mode 100644
index 0000000..ed7acc2
--- /dev/null
+++ b/modules/formats/json/src/test/resources/configs/valid/with-explicit-priority.json
@@ -0,0 +1,25 @@
+/*
+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.
+*/
+{
+ /*
+ some useful comment here
+ */
+ "tamaya.ordinal" : 16784,
+ "a" : "A" // another comment
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/pom.xml
----------------------------------------------------------------------
diff --git a/modules/formats/pom.xml b/modules/formats/pom.xml
index 990acfc..387d455 100644
--- a/modules/formats/pom.xml
+++ b/modules/formats/pom.xml
@@ -1,24 +1,22 @@
-<!--
-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 current 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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<!--
+ ~ 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
@@ -27,62 +25,14 @@ under the License.
<version>0.3-incubating-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
- <artifactId>tamaya-formats</artifactId>
- <name>Apache Tamaya Modules Formats</name>
- <packaging>bundle</packaging>
-
- <properties>
- <jdkVersion>1.7</jdkVersion>
- </properties>
+ <artifactId>tamaya-formats-all</artifactId>
+ <name>Apache Tamaya Modules - Formats Parent</name>
+ <packaging>pom</packaging>
- <dependencies>
- <dependency>
- <groupId>org.apache.tamaya</groupId>
- <artifactId>tamaya-api</artifactId>
- <version>${project.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.tamaya.ext</groupId>
- <artifactId>tamaya-resources</artifactId>
- <version>${project.version}</version>
- </dependency>
- <!-- Test scope only, do not create a code dependency! -->
- <dependency>
- <groupId>org.apache.tamaya</groupId>
- <artifactId>tamaya-core</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>java-hamcrest</artifactId>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- </dependency>
- </dependencies>
+ <modules>
+ <module>common</module>
+ <module>json</module>
+ <module>yaml</module>
+ </modules>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>
- org.apache.tamaya.format,
- org.apache.tamaya.format.formats
- </Export-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/main/java/org/apache/tamaya/format/BaseFormatPropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/BaseFormatPropertySourceProvider.java b/modules/formats/src/main/java/org/apache/tamaya/format/BaseFormatPropertySourceProvider.java
deleted file mode 100644
index 84d6cfa..0000000
--- a/modules/formats/src/main/java/org/apache/tamaya/format/BaseFormatPropertySourceProvider.java
+++ /dev/null
@@ -1,154 +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.format;
-
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertySourceProvider;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Objects;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Implementation of a {@link PropertySourceProvider} that reads configuration from some given resource paths
- * and using the given formats. The resource path are resolved as classpath resources. This can be changed by
- * overriding {@link #getPropertySources()}.
- * For each resource found the configuration formats passed get a chance to read the resource, if they succeed the
- * result is taken as the providers PropertySources to be exposed.
- */
-public abstract class BaseFormatPropertySourceProvider implements PropertySourceProvider {
- /**
- * The logger used.
- */
- private static final Logger LOG = Logger.getLogger(BaseFormatPropertySourceProvider.class.getName());
- /**
- * The config formats supported for the given location/resource paths.
- */
- private final List<ConfigurationFormat> configFormats = new ArrayList<>();
- /**
- * The paths to be evaluated.
- */
- private final Collection<URL> paths = new ArrayList<>();
-
- /**
- * Creates a new instance.
- *
- * @param formats the formats to be used, not null, not empty.
- * @param paths the paths to be resolved, not null, not empty.
- */
- public BaseFormatPropertySourceProvider(
- List<ConfigurationFormat> formats,
- URL... paths) {
- this.configFormats.addAll(Objects.requireNonNull(formats));
- this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
- }
-
- /**
- * Creates a new instance, hereby using the current thread context classloader, or if not available the classloader
- * that loaded this class.
- * @param formats the formats to be used, not null, not empty.
- * @param paths the paths to be resolved, not null, not empty.
- */
- public BaseFormatPropertySourceProvider(
- List<ConfigurationFormat> formats, String... paths) {
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- if(cl==null){
- cl = getClass().getClassLoader();
- }
- this.configFormats.addAll(Objects.requireNonNull(formats));
- for(String path:paths) {
- Enumeration<URL> urls;
- try {
- urls = cl.getResources(path);
- } catch (IOException e) {
- LOG.log(Level.WARNING, "Failed to read resource: " + path, e);
- continue;
- }
- while(urls.hasMoreElements()) {
- this.paths.add(urls.nextElement());
- }
- }
- }
-
- /**
- * Creates a new instance.
- *
- * @param classLoader the ClassLoader to be used, not null, not empty.
- * @param formats the formats to be used, not null, not empty.
- * @param paths the paths to be resolved, not null, not empty.
- */
- public BaseFormatPropertySourceProvider(
- List<ConfigurationFormat> formats,
- ClassLoader classLoader, String... paths) {
- this.configFormats.addAll(Objects.requireNonNull(formats));
- for(String path:paths) {
- Enumeration<URL> urls;
- try {
- urls = classLoader.getResources(path);
- } catch (IOException e) {
- LOG.log(Level.WARNING, "Failed to read resource: " + path, e);
- continue;
- }
- while(urls.hasMoreElements()) {
- this.paths.add(urls.nextElement());
- }
- }
- }
-
-
- /**
- * Method to create a {@link org.apache.tamaya.spi.PropertySource} based on the given entries read.
- *
- * @param data the configuration data, not null.
- * @return the {@link org.apache.tamaya.spi.PropertySource} instance ready to be registered.
- */
- protected abstract Collection<PropertySource> getPropertySources(ConfigurationData data);
-
- /**
- * This method does dynamically resolve the paths using the current ClassLoader set. If no ClassLoader was
- * explcitly set during creation the current Thread context ClassLoader is used. If none of the supported
- * formats is able to parse a resource a WARNING log is written.
- *
- * @return the PropertySources successfully read
- */
- @Override
- public Collection<PropertySource> getPropertySources() {
- List<PropertySource> propertySources = new ArrayList<>();
- for (URL res : this.paths) {
- try(InputStream is = res.openStream()) {
- for (ConfigurationFormat format : configFormats) {
- ConfigurationData data = format.readConfiguration(res.toString(), is);
- propertySources.addAll(getPropertySources(data));
- }
- } catch (Exception e) {
- LOG.log(Level.WARNING, "Failed to put resource based config: " + res, e);
- }
- }
- return propertySources;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationData.java
----------------------------------------------------------------------
diff --git a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationData.java b/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationData.java
deleted file mode 100644
index b58d2ab..0000000
--- a/modules/formats/src/main/java/org/apache/tamaya/format/ConfigurationData.java
+++ /dev/null
@@ -1,206 +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.format;
-
-import java.util.*;
-
-/**
- * <p>Data that abstracts the data read from a configuration resources using a certain format. The data can be divided
- * into different sections, similar to ini-files. Herebey different sections the best map to entries with different
- * priorities to be applied, when integrated into PropertySource instances.</p>
- * New instances of this class can be created using a {@link org.apache.tamaya.format.ConfigurationDataBuilder}.
- * <h3>Implementation Specification</h3>
- * This class is
- * <ul>
- * <li>immutable</li>
- * <li>thread-safe</li>
- * </ul>
- */
-public final class ConfigurationData {
- /**
- * The properties of the default section (no name).
- */
- private Map<String, String> defaultProperties;
- /**
- * A normalized flattened set of this configuration data.
- */
- private Map<String, String> combinedProperties;
- /**
- * The sections read.
- */
- private Map<String, Map<String, String>> namedSections;
- /** The format instance used to read this instance. */
- private final ConfigurationFormat format;
- /** The resource read. */
- private final String resource;
-
-
- /**
- * COnstructor used by builder.
- * @param builder the builder instance passing the read configuration data.
- */
- ConfigurationData(ConfigurationDataBuilder builder){
- this.format = builder.format;
- this.resource = builder.resource;
- if (builder.defaultProperties != null) {
- this.defaultProperties = new HashMap<>();
- this.defaultProperties.putAll(builder.defaultProperties);
- }
- if (builder.combinedProperties != null) {
- this.combinedProperties = new HashMap<>();
- this.combinedProperties.putAll(builder.combinedProperties);
- }
- if (builder.namedSections != null) {
- this.namedSections = new HashMap<>();
- this.namedSections.putAll(builder.namedSections);
- }
- if (this.combinedProperties == null || this.combinedProperties.isEmpty()) {
- this.combinedProperties = new HashMap<>();
- this.combinedProperties.putAll(getDefaultProperties());
- // popuilate it with sections...
- for (String sectionName : getSectionNames()) {
- Map<String, String> section = getSection(sectionName);
- for (Map.Entry<String, String> en : section.entrySet()) {
- String key = sectionName + '.' + en.getKey();
- combinedProperties.put(key, en.getValue());
- }
- }
- }
- }
-
- /**
- * Get the {@link org.apache.tamaya.format.ConfigurationFormat} that read this data.
- * @return the {@link org.apache.tamaya.format.ConfigurationFormat} that read this data, never null.
- */
- public ConfigurationFormat getFormat(){
- return format;
- }
-
- /**
- * Get the resource from which this data was read.
- * @return the resource from which this data was read, never null.
- */
- public String getResource(){
- return resource;
- }
-
- /**
- * Access an immutable Set of all present section names, including the default section (if any).
- * @return the set of present section names, never null.
- */
- public Set<String> getSectionNames() {
- if (namedSections == null) {
- return Collections.emptySet();
- }
- return namedSections.keySet();
- }
-
- /**
- * Get a section's data.
- * @param name the section name, not null.
- * @return the data of this section, or null, if no such section exists.
- */
- public Map<String, String> getSection(String name) {
- return this.namedSections.get(name);
- }
-
- /**
- * Convenience accessor for accessing the default section.
- * @return the default section's data, or null, if no such section exists.
- */
- public Map<String, String> getDefaultProperties() {
- if (defaultProperties == null) {
- return Collections.emptyMap();
- }
- return defaultProperties;
- }
-
- /**
- * Get combined properties for this config data instance. If
- *
- * @return the normalized properties.
- */
- public Map<String, String> getCombinedProperties() {
- if (combinedProperties == null) {
- return Collections.emptyMap();
- }
- return combinedProperties;
- }
-
- /**
- * Accessor used for easily creating a new builder based on a given data instance.
- *
- * @return the data contained, never null.
- */
- public Map<String, Map<String, String>> getSections() {
- if (namedSections == null) {
- return Collections.emptyMap();
- }
- return namedSections;
- }
-
- /**
- * Immutable accessor to ckeck, if there are default properties present.
- *
- * @return true, if default properties are present.
- */
- public boolean hasDefaultProperties() {
- return this.defaultProperties != null && !this.defaultProperties.isEmpty();
- }
-
- /**
- * Immutable accessor to ckeck, if there are combined properties set.
- *
- * @return true, if combined properties are set.
- */
- public boolean hasCombinedProperties() {
- return this.combinedProperties != null && !this.combinedProperties.isEmpty();
- }
-
- /**
- * Immutable accessor to ckeck, if there are named sections present.
- *
- * @return true, if at least one named section is present.
- */
- private boolean hasSections() {
- return this.namedSections != null && !this.namedSections.isEmpty();
- }
-
- /**
- * Checks if no properties are contained in this data item.
- *
- * @return true, if no properties are contained in this data item.
- */
- public boolean isEmpty() {
- return !hasCombinedProperties() && !hasDefaultProperties() && !hasSections();
- }
-
- @Override
- public String toString() {
- return "ConfigurationData{" +
- "format=" + format +
- ", default properties=" + defaultProperties +
- ", combined properties=" + combinedProperties +
- ", sections=" + namedSections +
- ", resource=" + resource +
- '}';
- }
-
-
-}
[07/15] incubator-tamaya-extensions git commit: TAMAYA-189: Moved
format and injection modules into separate subtrees.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/pom.xml
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/pom.xml b/modules/injection/cdi-se/pom.xml
new file mode 100644
index 0000000..848b95e
--- /dev/null
+++ b/modules/injection/cdi-se/pom.xml
@@ -0,0 +1,212 @@
+<!--
+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 current 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-injection-all</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <artifactId>tamaya-cdi-se</artifactId>
+ <groupId>tamaya-integration</groupId>
+ <name>Apache Tamaya Modules - Injection CDI (Direct)</name>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <owb.version>1.6.2</owb.version>
+ <weld.version>2.2.7.Final</weld.version>
+ <geronimo-jcdi-1.1-spec.version>1.0</geronimo-jcdi-1.1-spec.version>
+ <geronimo-interceptor-1.2-spec.version>1.0</geronimo-interceptor-1.2-spec.version>
+ <geronimo-atinject-1.0-spec.version>1.0</geronimo-atinject-1.0-spec.version>
+ <bval.version>0.5</bval.version>
+ <ds.version>1.1.0</ds.version>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>prepare-agent</id>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.tamaya.integration.cdi.config
+ </Export-Package>
+ <Private-Package>
+ org.apache.tamaya.integration.cdi.internal
+ </Private-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>java-hamcrest</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-classloader-support</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-spisupport</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-core</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-injection</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jcdi_1.1_spec</artifactId>
+ <version>${geronimo-jcdi-1.1-spec.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.deltaspike.modules</groupId>
+ <artifactId>deltaspike-test-control-module-api</artifactId>
+ <version>${ds.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.deltaspike.modules</groupId>
+ <artifactId>deltaspike-test-control-module-impl</artifactId>
+ <version>${ds.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>OWB</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <dependencies>
+ <!-- OWB specific dependencies-->
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-atinject_1.0_spec</artifactId>
+ <version>${geronimo-atinject-1.0-spec.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-interceptor_1.2_spec</artifactId>
+ <version>${geronimo-interceptor-1.2-spec.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-annotation_1.2_spec</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-el_2.2_spec</artifactId>
+ <version>1.0.2</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.openwebbeans</groupId>
+ <artifactId>openwebbeans-impl</artifactId>
+ <version>${owb.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openwebbeans</groupId>
+ <artifactId>openwebbeans-spi</artifactId>
+ <version>${owb.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.openwebbeans</groupId>
+ <artifactId>openwebbeans-resource</artifactId>
+ <version>${owb.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.bval</groupId>
+ <artifactId>bval-jsr303</artifactId>
+ <version>${bval.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.deltaspike.cdictrl</groupId>
+ <artifactId>deltaspike-cdictrl-owb</artifactId>
+ <version>${ds.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </profile>
+ <profile>
+ <id>Weld</id>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.weld.se</groupId>
+ <artifactId>weld-se</artifactId>
+ <version>${weld.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.deltaspike.cdictrl</groupId>
+ <artifactId>deltaspike-cdictrl-weld</artifactId>
+ <version>${ds.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java
new file mode 100644
index 0000000..566d00e
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java
@@ -0,0 +1,169 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.ServiceContext;
+
+import javax.annotation.Priority;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import java.text.MessageFormat;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+/**
+ * <p>This class implements a {@link ServiceContext}, which basically provides a similar loading mechanism as used
+ * by the {@link java.util.ServiceLoader}. Whereas the {@link java.util.ServiceLoader} only loads configurations
+ * and instances from one classloader, this loader manages configs found and the related instances for each
+ * classloader along the classloader hierarchies individually. It ensures instances are loaded on the classloader
+ * level, where they first are visible. Additionally it ensures the same configuration resource (and its
+ * declared services) are loaded multiple times, when going up the classloader hierarchy.</p>
+ *
+ * <p>Finally classloaders are not stored by reference by this class, to ensure they still can be garbage collected.
+ * Refer also the inherited parent class for further details.</p>
+ *
+ * <p>This class uses an ordinal of {@code 10}, so it overrides any default {@link ServiceContext} implementations
+ * provided with the Tamaya core modules.</p>
+ */
+public class CDIAwareServiceContext implements ServiceContext {
+
+ /**
+ * Singletons.
+ */
+ private final Map<Class<?>, Object> singletons = new ConcurrentHashMap<>();
+
+ private ServiceContext defaultServiceContext = new ServiceLoaderServiceContext();
+
+
+ @Override
+ public <T> T getService(Class<T> serviceType) {
+ Object cached = singletons.get(serviceType);
+ if (cached == null) {
+ Collection<T> services = getServices(serviceType);
+ if (services.isEmpty()) {
+ cached = null;
+ } else {
+ cached = getServiceWithHighestPriority(services, serviceType);
+ }
+ if(cached!=null) {
+ singletons.put(serviceType, cached);
+ }
+ }
+ return serviceType.cast(cached);
+ }
+
+ /**
+ * Loads and registers services.
+ *
+ * @param <T> the concrete type.
+ * @param serviceType The service type.
+ * @return the items found, never {@code null}.
+ */
+ @Override
+ public <T> List<T> getServices(final Class<T> serviceType) {
+ List<T> found = defaultServiceContext.getServices(serviceType);
+ BeanManager beanManager = TamayaCDIIntegration.getBeanManager();
+ Instance<T> cdiInstances = null;
+ if(beanManager!=null){
+ Set<Bean<?>> instanceBeans = beanManager.getBeans(Instance.class);
+ Bean<?> bean = instanceBeans.iterator().next();
+ cdiInstances = (Instance<T>)beanManager.getReference(bean, Instance.class,
+ beanManager.createCreationalContext(bean));
+ }
+ if(cdiInstances!=null){
+ for(T t:cdiInstances.select(serviceType)){
+ found.add(t);
+ }
+ }
+ return found;
+ }
+
+ /**
+ * Checks the given instance for a @Priority annotation. If present the annotation's value s evaluated. If no such
+ * annotation is present, a default priority is returned (1);
+ * @param o the instance, not null.
+ * @return a priority, by default 1.
+ */
+ public static int getPriority(Object o){
+ int prio = 1; //X TODO discuss default priority
+ Priority priority = o.getClass().getAnnotation(Priority.class);
+ if (priority != null) {
+ prio = priority.value();
+ }
+ return prio;
+ }
+
+ /**
+ * @param services to scan
+ * @param <T> type of the service
+ *
+ * @return the service with the highest {@link javax.annotation.Priority#value()}
+ *
+ * @throws ConfigException if there are multiple service implementations with the maximum priority
+ */
+ private <T> T getServiceWithHighestPriority(Collection<T> services, Class<T> serviceType) {
+
+ // we do not need the priority stuff if the list contains only one element
+ if (services.size() == 1) {
+ return services.iterator().next();
+ }
+
+ Integer highestPriority = null;
+ int highestPriorityServiceCount = 0;
+ T highestService = null;
+
+ for (T service : services) {
+ int prio = getPriority(service);
+ if (highestPriority == null || highestPriority < prio) {
+ highestService = service;
+ highestPriorityServiceCount = 1;
+ highestPriority = prio;
+ } else if (highestPriority == prio) {
+ highestPriorityServiceCount++;
+ }
+ }
+
+ if (highestPriorityServiceCount > 1) {
+ throw new ConfigException(MessageFormat.format("Found {0} implementations for Service {1} with Priority {2}: {3}",
+ highestPriorityServiceCount,
+ serviceType.getName(),
+ highestPriority,
+ services));
+ }
+
+ return highestService;
+ }
+
+ /**
+ * Returns ordinal of 20, overriding defaults as well as the inherited (internally used) CLAwareServiceContext
+ * instance.
+ * @return ordinal of 20.
+ */
+ @Override
+ public int ordinal() {
+ return 20;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContext.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContext.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContext.java
new file mode 100644
index 0000000..ae1f0bf
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContext.java
@@ -0,0 +1,296 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertySourceProvider;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import javax.annotation.Priority;
+import javax.enterprise.inject.Vetoed;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Logger;
+
+/**
+ * Default Implementation of a simple ConfigurationContext.
+ */
+@SuppressWarnings("FieldCanBeLocal")
+@Vetoed
+public class DefaultConfigurationContext implements ConfigurationContext {
+ /** The logger used. */
+ private final static Logger LOG = Logger.getLogger(DefaultConfigurationContext.class.getName());
+ /**
+ * Cubcomponent handling {@link PropertyConverter} instances.
+ */
+ private final PropertyConverterManager propertyConverterManager = new PropertyConverterManager();
+
+ /**
+ * The current unmodifiable list of loaded {@link PropertySource} instances.
+ */
+ private List<PropertySource> immutablePropertySources;
+
+ /**
+ * The current unmodifiable list of loaded {@link PropertyFilter} instances.
+ */
+ private List<PropertyFilter> immutablePropertyFilters;
+
+ /**
+ * The overriding policy used when combining PropertySources registered to evalute the final configuration
+ * values.
+ */
+ private PropertyValueCombinationPolicy propertyValueCombinationPolicy;
+
+ /**
+ * Lock for internal synchronization.
+ */
+ private final ReentrantReadWriteLock propertySourceLock = new ReentrantReadWriteLock();
+
+ /** Comparator used for ordering property sources. */
+ private final PropertySourceComparator propertySourceComparator = new PropertySourceComparator();
+
+ /** Comparator used for ordering property filters. */
+ private final PropertyFilterComparator propertyFilterComparator = new PropertyFilterComparator();
+
+
+ /**
+ * The first time the Configuration system gets invoked we do initialize
+ * all our {@link PropertySource}s and
+ * {@link PropertyFilter}s which are known at startup.
+ */
+ public DefaultConfigurationContext() {
+ List<PropertySource> propertySources = new ArrayList<>();
+
+ // first we load all PropertySources which got registered via java.util.ServiceLoader
+ propertySources.addAll(ServiceContextManager.getServiceContext().getServices(PropertySource.class));
+
+ // after that we add all PropertySources which get dynamically registered via their PropertySourceProviders
+ propertySources.addAll(evaluatePropertySourcesFromProviders());
+
+ // now sort them according to their ordinal values
+ Collections.sort(propertySources, new PropertySourceComparator());
+
+ immutablePropertySources = Collections.unmodifiableList(propertySources);
+ LOG.info("Registered " + immutablePropertySources.size() + " property sources: " +
+ immutablePropertySources);
+
+ // as next step we pick up the PropertyFilters pretty much the same way
+ List<PropertyFilter> propertyFilters = new ArrayList<>();
+ propertyFilters.addAll(ServiceContextManager.getServiceContext().getServices(PropertyFilter.class));
+ Collections.sort(propertyFilters, new PropertyFilterComparator());
+ immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+ LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
+ immutablePropertyFilters);
+
+ immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+ LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
+ immutablePropertyFilters);
+ propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().getService(PropertyValueCombinationPolicy.class);
+ if(propertyValueCombinationPolicy==null) {
+ propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+ }
+ LOG.info("Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
+ }
+
+ DefaultConfigurationContext(ConfigurationContextBuilder builder) {
+ List<PropertySource> propertySources = new ArrayList<>();
+ // first we load all PropertySources which got registered via java.util.ServiceLoader
+ propertySources.addAll(builder.getPropertySources());
+ // now sort them according to their ordinal values
+ Collections.sort(propertySources, propertySourceComparator);
+ immutablePropertySources = Collections.unmodifiableList(propertySources);
+ LOG.info("Registered " + immutablePropertySources.size() + " property sources: " +
+ immutablePropertySources);
+
+ // as next step we pick up the PropertyFilters pretty much the same way
+ List<PropertyFilter> propertyFilters = new ArrayList<>();
+ propertyFilters.addAll(ServiceContextManager.getServiceContext().getServices(PropertyFilter.class));
+ Collections.sort(propertyFilters, propertyFilterComparator);
+ immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+ LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
+ immutablePropertyFilters);
+
+ propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().getService(PropertyValueCombinationPolicy.class);
+ if(propertyValueCombinationPolicy==null){
+ propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+ }
+ LOG.info("Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
+ }
+
+
+
+ /**
+ * Pick up all {@link PropertySourceProvider}s and return all the
+ * {@link PropertySource}s they like to register.
+ */
+ private Collection<? extends PropertySource> evaluatePropertySourcesFromProviders() {
+ List<PropertySource> propertySources = new ArrayList<>();
+ Collection<PropertySourceProvider> propertySourceProviders = ServiceContextManager.getServiceContext().getServices(PropertySourceProvider.class);
+ for (PropertySourceProvider propertySourceProvider : propertySourceProviders) {
+ Collection<PropertySource> sources = propertySourceProvider.getPropertySources();
+ LOG.finer("PropertySourceProvider " + propertySourceProvider.getClass().getName() +
+ " provided the following property sources: " + sources);
+ propertySources.addAll(sources);
+ }
+
+ return propertySources;
+ }
+
+ @Override
+ public void addPropertySources(PropertySource... propertySourcesToAdd) {
+ Lock writeLock = propertySourceLock.writeLock();
+ try {
+ writeLock.lock();
+ List<PropertySource> newPropertySources = new ArrayList<>(this.immutablePropertySources);
+ newPropertySources.addAll(Arrays.asList(propertySourcesToAdd));
+ Collections.sort(newPropertySources, new PropertySourceComparator());
+
+ this.immutablePropertySources = Collections.unmodifiableList(newPropertySources);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Comparator used for ordering PropertySources.
+ */
+ private static class PropertySourceComparator implements Comparator<PropertySource>, Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Order property source reversely, the most important come first.
+ *
+ * @param source1 the first PropertySource
+ * @param source2 the second PropertySource
+ * @return the comparison result.
+ */
+ private int comparePropertySources(PropertySource source1, PropertySource source2) {
+ if (source1.getOrdinal() < source2.getOrdinal()) {
+ return -1;
+ } else if (source1.getOrdinal() > source2.getOrdinal()) {
+ return 1;
+ } else {
+ return source1.getClass().getName().compareTo(source2.getClass().getName());
+ }
+ }
+
+ @Override
+ public int compare(PropertySource source1, PropertySource source2) {
+ return comparePropertySources(source1, source2);
+ }
+ }
+
+ /**
+ * Comparator used for ordering PropertyFilters.
+ */
+ private static class PropertyFilterComparator implements Comparator<PropertyFilter>, Serializable{
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Compare 2 filters for ordering the filter chain.
+ *
+ * @param filter1 the first filter
+ * @param filter2 the second filter
+ * @return the comparison result
+ */
+ private int comparePropertyFilters(PropertyFilter filter1, PropertyFilter filter2) {
+ Priority prio1 = filter1.getClass().getAnnotation(Priority.class);
+ Priority prio2 = filter2.getClass().getAnnotation(Priority.class);
+ int ord1 = prio1 != null ? prio1.value() : 0;
+ int ord2 = prio2 != null ? prio2.value() : 0;
+
+ if (ord1 < ord2) {
+ return -1;
+ } else if (ord1 > ord2) {
+ return 1;
+ } else {
+ return filter1.getClass().getName().compareTo(filter2.getClass().getName());
+ }
+ }
+
+ @Override
+ public int compare(PropertyFilter filter1, PropertyFilter filter2) {
+ return comparePropertyFilters(filter1, filter2);
+ }
+ }
+
+ @Override
+ public List<PropertySource> getPropertySources() {
+ return immutablePropertySources;
+ }
+
+ @Override
+ public PropertySource getPropertySource(String name) {
+ for(PropertySource ps:getPropertySources()){
+ if(ps.getName().equals(name)){
+ return ps;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+ propertyConverterManager.register(typeToConvert, propertyConverter);
+ LOG.info("Added PropertyConverter: " + propertyConverter.getClass().getName());
+ }
+
+ @Override
+ public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+ return propertyConverterManager.getPropertyConverters();
+ }
+
+ @Override
+ public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+ return propertyConverterManager.getPropertyConverters(targetType);
+ }
+
+ @Override
+ public List<PropertyFilter> getPropertyFilters() {
+ return immutablePropertyFilters;
+ }
+
+ @Override
+ public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(){
+ return propertyValueCombinationPolicy;
+ }
+
+ @Override
+ public ConfigurationContextBuilder toBuilder() {
+ return ConfigurationProvider.getConfigurationContextBuilder().setContext(this);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContextBuilder.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContextBuilder.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContextBuilder.java
new file mode 100644
index 0000000..c2dc83e
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContextBuilder.java
@@ -0,0 +1,152 @@
+///*
+// * 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.integration.cdi;
+//
+//import org.apache.tamaya.ConfigException;
+//import org.apache.tamaya.TypeLiteral;
+//import org.apache.tamaya.spi.ConfigurationContext;
+//import org.apache.tamaya.spi.ConfigurationContextBuilder;
+//import org.apache.tamaya.spi.PropertyConverter;
+//import org.apache.tamaya.spi.PropertyFilter;
+//import org.apache.tamaya.spi.PropertySource;
+//import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+//
+//import javax.enterprise.inject.Vetoed;
+//import java.util.ArrayList;
+//import java.util.Arrays;
+//import java.util.Collection;
+//import java.util.HashMap;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.Objects;
+//
+///**
+// * Default implementation of {@link ConfigurationContextBuilder}.
+// */
+//@Vetoed
+//public class DefaultConfigurationContextBuilder implements ConfigurationContextBuilder {
+//
+// final Map<String, PropertySource> propertySources = new HashMap<>();
+// final List<PropertyFilter> propertyFilters = new ArrayList<>();
+// final Map<TypeLiteral<?>, List<PropertyConverter<?>>> propertyConverters = new HashMap<>();
+// PropertyValueCombinationPolicy combinationPolicy;
+//
+// @Override
+// public ConfigurationContextBuilder setContext(ConfigurationContext context) {
+// this.propertySources.clear();
+// for(PropertySource ps:context.getPropertySources()) {
+// this.propertySources.put(ps.getName(), ps);
+// }
+// this.propertyFilters.clear();
+// this.propertyFilters.addAll(context.getPropertyFilters());
+// this.propertyConverters.clear();
+// this.propertyConverters.putAll(context.getPropertyConverters());
+// this.combinationPolicy = context.getPropertyValueCombinationPolicy();
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContextBuilder addPropertySources(Collection<PropertySource> propertySourcesToAdd) {
+// for(PropertySource ps:propertySourcesToAdd){
+// if(this.propertySources.containsKey(ps.getName())){
+// throw new ConfigException("Duplicate PropertySource: " + ps.getName());
+// }
+// }
+// for(PropertySource ps:propertySourcesToAdd) {
+// this.propertySources.put(ps.getName(), ps);
+// }
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContextBuilder addPropertySources(PropertySource... propertySourcesToAdd) {
+// return addPropertySources(Arrays.asList(propertySourcesToAdd));
+// }
+//
+// @Override
+// public ConfigurationContextBuilder removePropertySources(Collection<String> propertySourcesToRemove) {
+// for(String key: propertySourcesToRemove){
+// this.propertySources.remove(key);
+// }
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContextBuilder removePropertySources(String... propertySourcesToRemove) {
+// return removePropertySources(Arrays.asList(propertySourcesToRemove));
+// }
+//
+// @Override
+// public ConfigurationContextBuilder addPropertyFilters(Collection<PropertyFilter> filters) {
+// this.propertyFilters.addAll(filters);
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContextBuilder addPropertyFilters(PropertyFilter... filters) {
+// return addPropertyFilters(Arrays.asList(filters));
+// }
+//
+// @Override
+// public ConfigurationContextBuilder removePropertyFilters(Collection<PropertyFilter> filters) {
+// this.propertyFilters.removeAll(filters);
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContextBuilder removePropertyFilters(PropertyFilter... filters) {
+// return removePropertyFilters(Arrays.asList(filters));
+// }
+//
+// @Override
+// public <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+// List<PropertyConverter<?>> converters = this.propertyConverters.get(typeToConvert);
+// if(converters==null){
+// converters = new ArrayList<>();
+// this.propertyConverters.put(typeToConvert, converters);
+// }
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert, PropertyConverter<?>... converters) {
+// return removePropertyConverters(typeToConvert, Arrays.asList(converters));
+// }
+//
+// @Override
+// public ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert, Collection<PropertyConverter<?>> converters) {
+// List<PropertyConverter<?>> existing = this.propertyConverters.get(typeToConvert);
+// if(existing!=null) {
+// existing.removeAll(converters);
+// }
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContextBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy) {
+// this.combinationPolicy = Objects.requireNonNull(policy);
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContext build() {
+// return new DefaultConfigurationContext(this);
+// }
+//
+//}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/EnumConverter.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/EnumConverter.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/EnumConverter.java
new file mode 100644
index 0000000..d6ad1ba
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/EnumConverter.java
@@ -0,0 +1,71 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+
+import javax.enterprise.inject.Vetoed;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to tge given enum type.
+ * @param <T> the enum type.
+ */
+@Vetoed
+public class EnumConverter<T> implements PropertyConverter<T> {
+ private final Logger LOG = Logger.getLogger(EnumConverter.class.getName());
+ private Class<T> enumType;
+ private Method factory;
+
+ public EnumConverter(Class<T> enumType) {
+ if (!Enum.class.isAssignableFrom(enumType)) {
+ throw new IllegalArgumentException("Not an Enum: " + enumType.getName());
+ }
+ this.enumType = Objects.requireNonNull(enumType);
+ try {
+ this.factory = enumType.getMethod("valueOf", String.class);
+ } catch (NoSuchMethodException e) {
+ throw new ConfigException("Uncovertible enum type without valueOf method found, please provide a custom " +
+ "PropertyConverter for: " + enumType.getName());
+ }
+ }
+
+ @Override
+ public T convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(), "<enumValue>");
+ try {
+ return (T) factory.invoke(null, value);
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + enumType.getName(), e);
+ }
+ try {
+ return (T) factory.invoke(null, value.toUpperCase(Locale.ENGLISH));
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + enumType.getName(), e);
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/PropertyConverterManager.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/PropertyConverterManager.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/PropertyConverterManager.java
new file mode 100644
index 0000000..e0e35f7
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/PropertyConverterManager.java
@@ -0,0 +1,427 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import javax.enterprise.inject.Vetoed;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Logger;
+
+/**
+ * Manager that deals with {@link PropertyConverter} instances.
+ * This class is thread-safe.
+ */
+@Vetoed
+public class PropertyConverterManager {
+ /**
+ * The logger used.
+ */
+ private static final Logger LOG = Logger.getLogger(PropertyConverterManager.class.getName());
+ /**
+ * The registered converters.
+ */
+ private final Map<TypeLiteral<?>, List<PropertyConverter<?>>> converters = new ConcurrentHashMap<>();
+ /**
+ * The transitive converters.
+ */
+ private final Map<TypeLiteral<?>, List<PropertyConverter<?>>> transitiveConverters = new ConcurrentHashMap<>();
+ /**
+ * The lock used.
+ */
+ private final ReadWriteLock lock = new ReentrantReadWriteLock();
+
+ private static final Comparator<Object> PRIORITY_COMPARATOR = new Comparator<Object>() {
+
+ @Override
+ public int compare(Object o1, Object o2) {
+ int prio = CDIAwareServiceContext.getPriority(o1) - CDIAwareServiceContext.getPriority(o2);
+ if (prio < 0) {
+ return 1;
+ } else if (prio > 0) {
+ return -1;
+ } else {
+ return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
+ }
+ }
+ };
+
+ /**
+ * Constructor.
+ */
+ public PropertyConverterManager() {
+ initConverters();
+ }
+
+ /**
+ * Registers the default converters provided out of the box.
+ */
+ protected void initConverters() {
+ for (PropertyConverter conv : ServiceContextManager.getServiceContext().getServices(PropertyConverter.class)) {
+ Type type = TypeLiteral.getGenericInterfaceTypeParameters(conv.getClass(), PropertyConverter.class)[0];
+ register(TypeLiteral.of(type), conv);
+ }
+ }
+
+ /**
+ * Registers a ew converter instance.
+ *
+ * @param targetType the target type, not null.
+ * @param converter the converter, not null.
+ * @param <T> the type.
+ */
+ public <T> void register(TypeLiteral<T> targetType, PropertyConverter<T> converter) {
+ Objects.requireNonNull(converter);
+ Lock writeLock = lock.writeLock();
+ try {
+ writeLock.lock();
+ List converters = List.class.cast(this.converters.get(targetType));
+ List<PropertyConverter<?>> newConverters = new ArrayList<>();
+ if (converters != null) {
+ newConverters.addAll(converters);
+ }
+ newConverters.add(converter);
+ Collections.sort(newConverters, PRIORITY_COMPARATOR);
+ this.converters.put(targetType, Collections.unmodifiableList(newConverters));
+ // evaluate transitive closure for all inherited supertypes and implemented interfaces
+ // direct implemented interfaces
+ for (Class<?> ifaceType : targetType.getRawType().getInterfaces()) {
+ converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(ifaceType)));
+ newConverters = new ArrayList<>();
+ if (converters != null) {
+ newConverters.addAll(converters);
+ }
+ newConverters.add(converter);
+ Collections.sort(newConverters, PRIORITY_COMPARATOR);
+ this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters));
+ }
+ Class<?> superClass = targetType.getRawType().getSuperclass();
+ while (superClass != null && !superClass.equals(Object.class)) {
+ converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(superClass)));
+ newConverters = new ArrayList<>();
+ if (converters != null) {
+ newConverters.addAll(converters);
+ }
+ newConverters.add(converter);
+ Collections.sort(newConverters, PRIORITY_COMPARATOR);
+ this.transitiveConverters.put(TypeLiteral.of(superClass), Collections.unmodifiableList(newConverters));
+ for (Class<?> ifaceType : superClass.getInterfaces()) {
+ converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(ifaceType)));
+ newConverters = new ArrayList<>();
+ if (converters != null) {
+ newConverters.addAll(converters);
+ }
+ newConverters.add(converter);
+ Collections.sort(newConverters, PRIORITY_COMPARATOR);
+ this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters));
+ }
+ superClass = superClass.getSuperclass();
+ }
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Allows to evaluate if a given target type is supported.
+ *
+ * @param targetType the target type, not null.
+ * @return true, if a converter for the given type is registered, or a default one can be created.
+ */
+ public boolean isTargetTypeSupported(TypeLiteral<?> targetType) {
+ if (converters.containsKey(targetType) || transitiveConverters.containsKey(targetType)) {
+ return true;
+ }
+ return createDefaultPropertyConverter(targetType) != null;
+ }
+
+ /**
+ * Get a map of all property converters currently registered. This will not contain the converters that
+ * may be created, when an instance is adapted, which provides a String constructor or compatible
+ * factory methods taking a single String instance.
+ *
+ * @return the current map of instantiated and registered converters.
+ * @see #createDefaultPropertyConverter(TypeLiteral)
+ */
+ public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+ Lock readLock = lock.readLock();
+ try {
+ readLock.lock();
+ return new HashMap<>(this.converters);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * <p>Get the list of all current registered converters for the given target type.
+ * If not converters are registered, they component tries to create and register a dynamic
+ * converter based on String costructor or static factory methods available.</p>
+ *
+ * <p>The converters provided are of the following type and returned in the following order:</p>
+ * <ul>
+ * <li>Converters mapped explicitly to the required target type are returned first, ordered
+ * by decreasing priority. This means, if explicit converters are registered these are used
+ * primarly for converting a value.</li>
+ * <li>The target type of each explicitly registered converter also can be transitively mapped to
+ * 1) all directly implemented interfaces, 2) all its superclasses (except Object), 3) all the interfaces
+ * implemented by its superclasses. These groups of transitive converters is returned similarly in the
+ * order as mentioned, whereas also here a priority based decreasing ordering is applied.</li>
+ * <li>java.lang wrapper classes and native types are automatically mapped.</li>
+ * <li>If no explicit converters are registered, for Enum types a default implementation is provided that
+ * compares the configuration values with the different enum members defined (cases sensitive mapping).</li>
+ * </ul>
+ *
+ * <p>So given that list above directly registered mappings always are tried first, before any transitive mapping
+ * should be used. Also in all cases @Priority annotations are honored for ordering of the converters in place.
+ * Transitive conversion is supported for all directly implemented interfaces (including inherited ones) and
+ * the inheritance hierarchy (exception Object). Super interfaces of implemented interfaces are ignored.</p>
+ *
+ *
+ * @param targetType the target type, not null.
+ * @param <T> the type class
+ * @return the ordered list of converters (may be empty for not convertible types).
+ * @see #createDefaultPropertyConverter(TypeLiteral)
+ */
+ public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+ Lock readLock = lock.readLock();
+ List<PropertyConverter<T>> converterList = new ArrayList<>();
+ List<PropertyConverter<T>> converters;
+ // direct mapped converters
+ try {
+ readLock.lock();
+ converters = List.class.cast(this.converters.get(targetType));
+ } finally {
+ readLock.unlock();
+ }
+ if (converters != null) {
+ converterList.addAll(converters);
+ }
+ // transitive converter
+ try {
+ readLock.lock();
+ converters = List.class.cast(this.transitiveConverters.get(targetType));
+ } finally {
+ readLock.unlock();
+ }
+ if (converters != null) {
+ converterList.addAll(converters);
+ }
+ // handling of java.lang wrapper classes
+ TypeLiteral<T> boxedType = mapBoxedType(targetType);
+ if (boxedType != null) {
+ try {
+ readLock.lock();
+ converters = List.class.cast(this.converters.get(boxedType));
+ } finally {
+ readLock.unlock();
+ }
+ if (converters != null) {
+ converterList.addAll(converters);
+ }
+ }
+ if (converterList.isEmpty()) {
+ // adding any converters created on the fly, e.g. for enum types.
+ PropertyConverter<T> defaultConverter = createDefaultPropertyConverter(targetType);
+ if (defaultConverter != null) {
+ register(targetType, defaultConverter);
+ try {
+ readLock.lock();
+ converters = List.class.cast(this.converters.get(targetType));
+ } finally {
+ readLock.unlock();
+ }
+ }
+ if (converters != null) {
+ converterList.addAll(converters);
+ }
+ }
+ return converterList;
+ }
+
+ /**
+ * Maps native types to the corresponding boxed types.
+ *
+ * @param targetType the native type.
+ * @param <T> the type
+ * @return the boxed type, or null.
+ */
+ private <T> TypeLiteral<T> mapBoxedType(TypeLiteral<T> targetType) {
+ Type parameterType = targetType.getType();
+ if (parameterType == int.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Integer.class));
+ }
+ if (parameterType == short.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Short.class));
+ }
+ if (parameterType == byte.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Byte.class));
+ }
+ if (parameterType == long.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Long.class));
+ }
+ if (parameterType == boolean.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Boolean.class));
+ }
+ if (parameterType == char.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Character.class));
+ }
+ if (parameterType == float.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Float.class));
+ }
+ if (parameterType == double.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Double.class));
+ }
+ if (parameterType == int[].class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Integer[].class));
+ }
+ if (parameterType == short[].class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Short[].class));
+ }
+ if (parameterType == byte[].class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Byte[].class));
+ }
+ if (parameterType == long[].class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Long[].class));
+ }
+ if (parameterType == boolean.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Boolean.class));
+ }
+ if (parameterType == char[].class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Character[].class));
+ }
+ if (parameterType == float[].class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Float[].class));
+ }
+ if (parameterType == double[].class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Double[].class));
+ }
+ return null;
+ }
+
+ /**
+ * Creates a dynamic PropertyConverter for the given target type.
+ *
+ * @param targetType the target type
+ * @param <T> the type class
+ * @return a new converter, or null.
+ */
+ protected <T> PropertyConverter<T> createDefaultPropertyConverter(final TypeLiteral<T> targetType) {
+ if (Enum.class.isAssignableFrom(targetType.getRawType())) {
+ return new EnumConverter<>(targetType.getRawType());
+ }
+ PropertyConverter<T> converter = null;
+ final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "valueOf", "instanceOf", "getInstance", "from", "fromString", "parse");
+ if (factoryMethod != null) {
+ converter = new PropertyConverter<T>() {
+ @Override
+ public T convert(String value, ConversionContext context) {
+ context.addSupportedFormats(PropertyConverter.class, "static T of(String)", "static T valueOf(String)",
+ "static T getInstance(String)", "static T from(String)",
+ "static T fromString(String)", "static T parse(String)");
+ try {
+ if (!Modifier.isStatic(factoryMethod.getModifiers())) {
+ throw new ConfigException(factoryMethod.toGenericString() +
+ " is not a static method. Only static " +
+ "methods can be used as factory methods.");
+ }
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ factoryMethod.setAccessible(true);
+ return null;
+ }
+ });
+ Object invoke = factoryMethod.invoke(null, value);
+ return targetType.getRawType().cast(invoke);
+ } catch (Exception e) {
+ throw new ConfigException("Failed to decode '" + value + "'", e);
+ }
+ }
+ };
+ }
+ if (converter == null) {
+ try {
+ final Constructor<T> constr = targetType.getRawType().getDeclaredConstructor(String.class);
+ converter = new PropertyConverter<T>() {
+ @Override
+ public T convert(String value, ConversionContext context) {
+ context.addSupportedFormats(PropertyConverter.class, "new T(String)");
+ try {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ constr.setAccessible(true);
+ return null;
+ }
+ });
+ return constr.newInstance(value);
+ } catch (Exception e) {
+ throw new ConfigException("Failed to decode '" + value + "'", e);
+ }
+ }
+ };
+ } catch (Exception e) {
+ LOG.finest("Failed to construct instance of type: " + targetType.getRawType().getName() + ": " + e);
+ }
+ }
+ return converter;
+ }
+
+ /**
+ * Tries to evaluate a factory method that can be used to create an instance based on a String.
+ *
+ * @param type the target type
+ * @param methodNames the possible static method names
+ * @return the first method found, or null.
+ */
+ private Method getFactoryMethod(Class<?> type, String... methodNames) {
+ Method m;
+ for (String name : methodNames) {
+ try {
+ m = type.getDeclaredMethod(name, String.class);
+ return m;
+ } catch (NoSuchMethodException | RuntimeException e) {
+ LOG.finest("No such factory method found on type: " + type.getName() + ", methodName: " + name);
+ }
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/SEInjectorCDIExtension.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/SEInjectorCDIExtension.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/SEInjectorCDIExtension.java
new file mode 100644
index 0000000..86e95b0
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/SEInjectorCDIExtension.java
@@ -0,0 +1,112 @@
+/*
+ * 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.integration.cdi;
+
+
+import org.apache.tamaya.inject.ConfigurationInjection;
+import org.apache.tamaya.inject.api.Config;
+import org.apache.tamaya.inject.api.ConfigDefaultSections;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Vetoed;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.InjectionTarget;
+import javax.enterprise.inject.spi.ProcessInjectionTarget;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+/**
+ * CDI portable extension that integrates {@link org.apache.tamaya.inject.ConfigurationInjector}
+ * with CDI by adding configuration features to CDI (config enable CDI beans).
+ */
+@Vetoed
+public final class SEInjectorCDIExtension implements Extension {
+
+ /**
+ * Method that injects the values into any configured fields, by wrapping the given
+ * InjectionTarget.
+ * @param pit the injection target
+ * @param <T> the target type
+ */
+ public <T> void initializeConfiguredFields(final @Observes ProcessInjectionTarget<T> pit) {
+ final AnnotatedType<T> at = pit.getAnnotatedType();
+ if (!isConfigured(at.getJavaClass())) {
+ return;
+ }
+ final InjectionTarget<T> it = pit.getInjectionTarget();
+ InjectionTarget<T> wrapped = new InjectionTarget<T>() {
+ @Override
+ public void inject(T instance, CreationalContext<T> ctx) {
+ it.inject(instance, ctx);
+ ConfigurationInjection.getConfigurationInjector().configure(instance);
+ }
+
+ @Override
+ public void postConstruct(T instance) {
+ it.postConstruct(instance);
+ }
+
+ @Override
+ public void preDestroy(T instance) {
+ it.dispose(instance);
+ }
+
+ @Override
+ public void dispose(T instance) {
+ it.dispose(instance);
+ }
+
+ @Override
+ public Set<InjectionPoint> getInjectionPoints() {
+ return it.getInjectionPoints();
+ }
+
+ @Override
+ public T produce(CreationalContext<T> ctx) {
+ return it.produce(ctx);
+ }
+ };
+ pit.setInjectionTarget(wrapped);
+ }
+
+ private boolean isConfigured(Class type) {
+ if (type.getAnnotation(ConfigDefaultSections.class) != null) {
+ return true;
+ }
+ // if no class level annotation is there we might have field level annotations only
+ for (Field field : type.getDeclaredFields()) {
+ if (field.isAnnotationPresent(Config.class)) {
+ return true;
+ }
+ }
+ // if no class level annotation is there we might have method level annotations only
+ for (Method method : type.getDeclaredMethods()) {
+ if(method.isAnnotationPresent(Config.class)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java
new file mode 100644
index 0000000..5171d91
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java
@@ -0,0 +1,151 @@
+/*
+ * 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.integration.cdi;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.ServiceContext;
+
+import javax.annotation.Priority;
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class implements the (default) {@link ServiceContext} interface and hereby uses the JDK
+ * {@link ServiceLoader} to load the services required.
+ */
+final class ServiceLoaderServiceContext implements ServiceContext {
+ /**
+ * List current services loaded, per class.
+ */
+ private final ConcurrentHashMap<Class<?>, List<Object>> servicesLoaded = new ConcurrentHashMap<>();
+ /**
+ * Singletons.
+ */
+ private final Map<Class<?>, Object> singletons = new ConcurrentHashMap<>();
+
+ @Override
+ public <T> T getService(Class<T> serviceType) {
+ Object cached = singletons.get(serviceType);
+ if (cached == null) {
+ Collection<T> services = getServices(serviceType);
+ if (services.isEmpty()) {
+ cached = null;
+ } else {
+ cached = getServiceWithHighestPriority(services, serviceType);
+ }
+ if(cached!=null) {
+ singletons.put(serviceType, cached);
+ }
+ }
+ return serviceType.cast(cached);
+ }
+
+ /**
+ * Loads and registers services.
+ *
+ * @param <T> the concrete type.
+ * @param serviceType The service type.
+ * @return the items found, never {@code null}.
+ */
+ @Override
+ public <T> List<T> getServices(final Class<T> serviceType) {
+ List<T> found = (List<T>) servicesLoaded.get(serviceType);
+ if (found != null) {
+ return found;
+ }
+ List<T> services = new ArrayList<>();
+ try {
+ for (T t : ServiceLoader.load(serviceType)) {
+ services.add(t);
+ }
+ services = Collections.unmodifiableList(services);
+ } catch (Exception e) {
+ Logger.getLogger(ServiceLoaderServiceContext.class.getName()).log(Level.WARNING,
+ "Error loading services current type " + serviceType, e);
+ }
+ final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>) services));
+ return previousServices != null ? previousServices : services;
+ }
+
+ /**
+ * Checks the given instance for a @Priority annotation. If present the annotation's value s evaluated. If no such
+ * annotation is present, a default priority is returned (1);
+ * @param o the instance, not null.
+ * @return a priority, by default 1.
+ */
+ public static int getPriority(Object o){
+ int prio = 1; //X TODO discuss default priority
+ Priority priority = o.getClass().getAnnotation(Priority.class);
+ if (priority != null) {
+ prio = priority.value();
+ }
+ return prio;
+ }
+
+ /**
+ * @param services to scan
+ * @param <T> type of the service
+ *
+ * @return the service with the highest {@link Priority#value()}
+ *
+ * @throws ConfigException if there are multiple service implementations with the maximum priority
+ */
+ private <T> T getServiceWithHighestPriority(Collection<T> services, Class<T> serviceType) {
+
+ // we do not need the priority stuff if the list contains only one element
+ if (services.size() == 1) {
+ return services.iterator().next();
+ }
+
+ Integer highestPriority = null;
+ int highestPriorityServiceCount = 0;
+ T highestService = null;
+
+ for (T service : services) {
+ int prio = getPriority(service);
+ if (highestPriority == null || highestPriority < prio) {
+ highestService = service;
+ highestPriorityServiceCount = 1;
+ highestPriority = prio;
+ } else if (highestPriority == prio) {
+ highestPriorityServiceCount++;
+ }
+ }
+
+ if (highestPriorityServiceCount > 1) {
+ throw new ConfigException(MessageFormat.format("Found {0} implementations for Service {1} with Priority {2}: {3}",
+ highestPriorityServiceCount,
+ serviceType.getName(),
+ highestPriority,
+ services));
+ }
+
+ return highestService;
+ }
+
+ @Override
+ public int ordinal() {
+ return 1;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaCDIIntegration.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaCDIIntegration.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaCDIIntegration.java
new file mode 100644
index 0000000..3f62039
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaCDIIntegration.java
@@ -0,0 +1,52 @@
+/*
+ * 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.integration.cdi;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+
+/**
+ * Tamaya main integration with CDI, storing the BeanManager reference for implementation, where no
+ * JNDI is available or {@code java:comp/env/BeanManager} is not set correctly.
+ */
+public class TamayaCDIIntegration implements Extension {
+ /** The BeanManager references stored. */
+ private static BeanManager beanManager;
+
+ /**
+ * Initializes the current BeanManager with the instance passed.
+ * @param validation the event
+ * @param beanManager the BeanManager instance
+ */
+ @SuppressWarnings("all")
+ public void initBeanManager(@Observes AfterDeploymentValidation validation, BeanManager beanManager){
+ TamayaCDIIntegration.beanManager = beanManager;
+ }
+
+ /**
+ * Get the current {@link BeanManager} instance.
+ * @return the currently used bean manager.
+ */
+ public static BeanManager getBeanManager(){
+ return beanManager;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaConfigProvider.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaConfigProvider.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaConfigProvider.java
new file mode 100644
index 0000000..a81e545
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaConfigProvider.java
@@ -0,0 +1,55 @@
+/*
+ * 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.integration.cdi;
+
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spisupport.DefaultConfiguration;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Singleton;
+
+/**
+ * Tamaya main integreation with CDI (singleton) serving producers for Configuration, ConfigurationContext and
+ * ConfigurationContextBuilder.
+ */
+@Singleton
+public class TamayaConfigProvider{
+
+ @Produces
+ @ApplicationScoped
+ public Configuration getConfiguration(ConfigurationContext context){
+ return new DefaultConfiguration(context);
+ }
+
+ @Produces @ApplicationScoped
+ public ConfigurationContext getConfigurationContext(){
+ return new DefaultConfigurationContext();
+ }
+
+ @Produces
+ public ConfigurationContextBuilder getConfigurationContextBuilder(){
+ return ConfigurationProvider.getConfigurationContextBuilder();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/config/ConfiguredVetoExtension.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/config/ConfiguredVetoExtension.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/config/ConfiguredVetoExtension.java
new file mode 100644
index 0000000..f90998d
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/config/ConfiguredVetoExtension.java
@@ -0,0 +1,42 @@
+/*
+ * 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.integration.cdi.config;
+
+import org.apache.tamaya.ConfigurationProvider;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+
+/**
+ * CDI Extension that can be used to veto on beans by configuring the fully qualified class names (as regex expression)
+ * under {@code javax.enterprise.inject.vetoed}. Multiple expression can be added as comma separated values.
+ */
+public class ConfiguredVetoExtension {
+
+ public void observesBean(@Observes ProcessAnnotatedType<?> type){
+ String vetoedTypesVal = ConfigurationProvider.getConfiguration().get("javax.enterprise.inject.vetoed");
+ String[] vetoedTypes = vetoedTypesVal.split(",");
+ for(String typeExpr:vetoedTypes){
+ if(type.getAnnotatedType().getJavaClass().getName().matches(typeExpr)){
+ type.veto();
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/resources/META-INF/beans.xml b/modules/injection/cdi-se/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..adee378
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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 current 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.
+-->
+<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd">
+
+</beans>
+
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/modules/injection/cdi-se/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000..8580a42
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1,20 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.integration.cdi.TamayaCDIIntegration
+org.apache.tamaya.integration.cdi.SEInjectorCDIExtension
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext b/modules/injection/cdi-se/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
new file mode 100644
index 0000000..4fe7e01
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.integration.cdi.CDIAwareServiceContext
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/ConfiguredClass.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/ConfiguredClass.java b/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/ConfiguredClass.java
new file mode 100644
index 0000000..9d920bc
--- /dev/null
+++ b/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/ConfiguredClass.java
@@ -0,0 +1,112 @@
+/*
+ *
+ * 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 current 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.integration.cdi;
+
+import org.apache.tamaya.inject.api.Config;
+
+import java.math.BigDecimal;
+
+import javax.inject.Singleton;
+
+/**
+ * Class to be loaded from CDI to ensure fields are correctly configured using CDI injection mechanisms.
+ */
+@Singleton
+public class ConfiguredClass{
+
+ @Config
+ private String testProperty;
+
+ @Config(value = {"a.b.c.key1","a.b.c.key2","a.b.c.key3"}, defaultValue = "The current \\${JAVA_HOME} env property is ${env:JAVA_HOME}.")
+ String value1;
+
+ @Config({"foo","a.b.c.key2"})
+ private String value2;
+
+ @Config(defaultValue = "N/A")
+ private String runtimeVersion;
+
+ @Config(defaultValue = "${sys:java.version}")
+ private String javaVersion2;
+
+ @Config(defaultValue = "5")
+ private Integer int1;
+
+ @Config
+ private int int2;
+
+ @Config
+ private boolean booleanT;
+
+ @Config("BD")
+ private BigDecimal bigNumber;
+
+ @Config("double1")
+ private double doubleValue;
+
+ public String getTestProperty() {
+ return testProperty;
+ }
+
+ public String getValue1() {
+ return value1;
+ }
+
+ public String getValue2() {
+ return value2;
+ }
+
+ public String getRuntimeVersion() {
+ return runtimeVersion;
+ }
+
+ public String getJavaVersion2() {
+ return javaVersion2;
+ }
+
+ public Integer getInt1() {
+ return int1;
+ }
+
+ public int getInt2() {
+ return int2;
+ }
+
+ public boolean isBooleanT() {
+ return booleanT;
+ }
+
+ public BigDecimal getBigNumber() {
+ return bigNumber;
+ }
+
+ public double getDoubleValue() {
+ return doubleValue;
+ }
+
+ @Override
+ public String toString(){
+ return super.toString() + ": testProperty="+testProperty+", value1="+value1+", value2="+value2
+ +", int1="+int1+", int2="+int2+", booleanT="+booleanT+", bigNumber="+bigNumber
+ +", runtimeVersion="+runtimeVersion+", javaVersion2="+javaVersion2;
+ }
+
+}