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/07/20 00:59:11 UTC
[1/7] incubator-tamaya git commit: - Minimalized API. - Propagated
change to rest of modules.
Repository: incubator-tamaya
Updated Branches:
refs/heads/tamaya-next a72893099 -> 7144e3f98
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/ConverterTestsPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/ConverterTestsPropertySource.java b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/ConverterTestsPropertySource.java
new file mode 100644
index 0000000..3f34384
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/ConverterTestsPropertySource.java
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.converters;
+
+import org.apache.tamaya.builder.spi.PropertySource;
+import org.apache.tamaya.builder.spi.PropertyValue;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Test Property Source used by converter tests.
+ */
+public class ConverterTestsPropertySource implements PropertySource{
+ @Override
+ public int getOrdinal() {
+ return 0;
+ }
+
+ @Override
+ public String getName(){
+ return "ConverterTestsPropertySource";
+ }
+
+ @Override
+ public PropertyValue get(String key) {
+ switch(key){
+ // Bytes
+ case "tests.converter.byte.decimal":
+ return PropertyValue.of(key, "101", getName());
+ case "tests.converter.byte.octal":
+ return PropertyValue.of(key, "02", getName());
+ case "tests.converter.byte.hex.lowerX":
+ return PropertyValue.of(key, "0x2F", getName());
+ case "tests.converter.byte.hex.upperX":
+ return PropertyValue.of(key, "0X3F", getName());
+ case "tests.converter.byte.min":
+ return PropertyValue.of(key, "min", getName());
+ case "tests.converter.byte.max":
+ return PropertyValue.of(key, "MAX_Value", getName());
+ // Boolean
+ case "tests.converter.boolean.y1":
+ return PropertyValue.of(key, "y", getName());
+ case "tests.converter.boolean.y2":
+ return PropertyValue.of(key, "Y", getName());
+ case "tests.converter.boolean.yes1":
+ return PropertyValue.of(key, "yes", getName());
+ case "tests.converter.boolean.yes2":
+ return PropertyValue.of(key, "Yes", getName());
+ case "tests.converter.boolean.yes3":
+ return PropertyValue.of(key, "yeS", getName());
+ case "tests.converter.boolean.true1":
+ return PropertyValue.of(key, "true", getName());
+ case "tests.converter.boolean.true2":
+ return PropertyValue.of(key, "True", getName());
+ case "tests.converter.boolean.true3":
+ return PropertyValue.of(key, "trUe", getName());
+ case "tests.converter.boolean.t1":
+ return PropertyValue.of(key, "t", getName());
+ case "tests.converter.boolean.t2":
+ return PropertyValue.of(key, "T", getName());
+ case "tests.converter.boolean.n1":
+ return PropertyValue.of(key, "n", getName());
+ case "tests.converter.boolean.n2":
+ return PropertyValue.of(key, "N", getName());
+ case "tests.converter.boolean.no1":
+ return PropertyValue.of(key, "no", getName());
+ case "tests.converter.boolean.no2":
+ return PropertyValue.of(key, "No", getName());
+ case "tests.converter.boolean.no3":
+ return PropertyValue.of(key, "nO", getName());
+ case "tests.converter.boolean.false1":
+ return PropertyValue.of(key, "false", getName());
+ case "tests.converter.boolean.false2":
+ return PropertyValue.of(key, "False", getName());
+ case "tests.converter.boolean.false3":
+ return PropertyValue.of(key, "falSe", getName());
+ case "tests.converter.boolean.f1":
+ return PropertyValue.of(key, "f", getName());
+ case "tests.converter.boolean.f2":
+ return PropertyValue.of(key, "F", getName());
+ // Character
+ case "tests.converter.char.f":
+ return PropertyValue.of(key, "f", getName());
+ case "tests.converter.char.d":
+ return PropertyValue.of(key, "'d'", getName());
+ case "tests.converter.char.f-before":
+ return PropertyValue.of(key, " f", getName());
+ case "tests.converter.char.f-after":
+ return PropertyValue.of(key, "f ", getName());
+ case "tests.converter.char.f-around":
+ return PropertyValue.of(key, " f ", getName());
+ case "tests.converter.char.f-numeric":
+ return PropertyValue.of(key, "101", getName());
+ // currency
+ case "tests.converter.currency.code1":
+ return PropertyValue.of(key, "CHF", getName());
+ case "tests.converter.currency.code2":
+ return PropertyValue.of(key, "cHf", getName());
+ case "tests.converter.currency.code3":
+ return PropertyValue.of(key, " CHF", getName());
+ case "tests.converter.currency.code4":
+ return PropertyValue.of(key, "CHF ", getName());
+ case "tests.converter.currency.code5":
+ return PropertyValue.of(key, " CHF ", getName());
+ case "tests.converter.currency.code-numeric1":
+ return PropertyValue.of(key, "100", getName());
+ case "tests.converter.currency.code-numeric2":
+ return PropertyValue.of(key, " 100", getName());
+ case "tests.converter.currency.code-numeric3":
+ return PropertyValue.of(key, "100 ", getName());
+ case "tests.converter.currency.code-numeric4":
+ return PropertyValue.of(key, " 100 ", getName());
+ case "tests.converter.currency.code-locale1":
+ return PropertyValue.of(key, "DE", getName());
+ case "tests.converter.currency.code-locale2":
+ return PropertyValue.of(key, " DE", getName());
+ case "tests.converter.currency.code-locale3":
+ return PropertyValue.of(key, "DE ", getName());
+ case "tests.converter.currency.code-locale4":
+ return PropertyValue.of(key, " DE ", getName());
+ //double
+ case "tests.converter.double.decimal":
+ return PropertyValue.of(key, "1.23456789", getName());
+ case "tests.converter.double.decimalNegative":
+ return PropertyValue.of(key, "-1.23456789", getName());
+ case "tests.converter.double.integer":
+ return PropertyValue.of(key, " 100", getName());
+ case "tests.converter.double.hex1":
+ return PropertyValue.of(key, " 0XFF", getName());
+ case "tests.converter.double.hex2":
+ return PropertyValue.of(key, "-0xFF ", getName());
+ case "tests.converter.double.hex3":
+ return PropertyValue.of(key, "#FF", getName());
+ case "tests.converter.double.octal":
+ return PropertyValue.of(key, "0013", getName());
+ case "tests.converter.double.min":
+ return PropertyValue.of(key, "MIN_Value", getName());
+ case "tests.converter.double.max":
+ return PropertyValue.of(key, "max", getName());
+ case "tests.converter.double.nan":
+ return PropertyValue.of(key, "NAN", getName());
+ case "tests.converter.double.pi":
+ return PropertyValue.of(key, "positive_infinity", getName());
+ case "tests.converter.double.ni":
+ return PropertyValue.of(key, "Negative_Infinity", getName());
+ //float
+ case "tests.converter.float.decimal":
+ return PropertyValue.of(key, "1.23456789", getName());
+ case "tests.converter.float.decimalNegative":
+ return PropertyValue.of(key, "-1.23456789", getName());
+ case "tests.converter.float.integer":
+ return PropertyValue.of(key, " 100", getName());
+ case "tests.converter.float.hex1":
+ return PropertyValue.of(key, " 0XFF", getName());
+ case "tests.converter.float.hex2":
+ return PropertyValue.of(key, "-0xFF ", getName());
+ case "tests.converter.float.hex3":
+ return PropertyValue.of(key, "#FF", getName());
+ case "tests.converter.float.octal":
+ return PropertyValue.of(key, "0013", getName());
+ case "tests.converter.float.min":
+ return PropertyValue.of(key, "MIN_Value", getName());
+ case "tests.converter.float.max":
+ return PropertyValue.of(key, "max", getName());
+ case "tests.converter.float.nan":
+ return PropertyValue.of(key, "NAN", getName());
+ case "tests.converter.float.pi":
+ return PropertyValue.of(key, "positive_infinity", getName());
+ case "tests.converter.float.ni":
+ return PropertyValue.of(key, "Negative_Infinity", getName());
+ // Integer
+ case "tests.converter.integer.decimal":
+ return PropertyValue.of(key, "101", getName());
+ case "tests.converter.integer.octal":
+ return PropertyValue.of(key, "02", getName());
+ case "tests.converter.integer.hex.lowerX":
+ return PropertyValue.of(key, "0x2F", getName());
+ case "tests.converter.integer.hex.upperX":
+ return PropertyValue.of(key, "0X3F", getName());
+ case "tests.converter.integer.min":
+ return PropertyValue.of(key, "min", getName());
+ case "tests.converter.integer.max":
+ return PropertyValue.of(key, "MAX_Value", getName());
+ // Long
+ case "tests.converter.long.decimal":
+ return PropertyValue.of(key, "101", getName());
+ case "tests.converter.long.octal":
+ return PropertyValue.of(key, "02", getName());
+ case "tests.converter.long.hex.lowerX":
+ return PropertyValue.of(key, "0x2F", getName());
+ case "tests.converter.long.hex.upperX":
+ return PropertyValue.of(key, "0X3F", getName());
+ case "tests.converter.long.min":
+ return PropertyValue.of(key, "min", getName());
+ case "tests.converter.long.max":
+ return PropertyValue.of(key, "MAX_Value", getName());
+ // Short
+ case "tests.converter.short.decimal":
+ return PropertyValue.of(key, "101", getName());
+ case "tests.converter.short.octal":
+ return PropertyValue.of(key, "02", getName());
+ case "tests.converter.short.hex.lowerX":
+ return PropertyValue.of(key, "0x2F", getName());
+ case "tests.converter.short.hex.upperX":
+ return PropertyValue.of(key, "0X3F", getName());
+ case "tests.converter.short.min":
+ return PropertyValue.of(key, "min", getName());
+ case "tests.converter.short.max":
+ return PropertyValue.of(key, "MAX_Value", getName());
+ // BigDecimal
+ case "tests.converter.bd.decimal":
+ return PropertyValue.of(key, "101", getName());
+ case "tests.converter.bd.float":
+ return PropertyValue.of(key, "101.36438746", getName());
+ case "tests.converter.bd.big":
+ return PropertyValue.of(key, "101666666666666662333337263723628763821638923628193612983618293628763", getName());
+ case "tests.converter.bd.bigFloat":
+ return PropertyValue.of(key, "1016666666666666623333372637236287638216389293628763.101666666666666662333337263723628763821638923628193612983618293628763", getName());
+ case "tests.converter.bd.hex.lowerX":
+ return PropertyValue.of(key, "0x2F", getName());
+ case "tests.converter.bd.hex.upperX":
+ return PropertyValue.of(key, "0X3F", getName());
+ }
+ return null;
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public boolean isScannable() {
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/CurrencyConverterTest.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/CurrencyConverterTest.java b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/CurrencyConverterTest.java
new file mode 100644
index 0000000..9113ca2
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/CurrencyConverterTest.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.core.internal.converters;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.junit.Test;
+
+import java.util.Currency;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests the default converter for bytes.
+ */
+public class CurrencyConverterTest {
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Currency_Code_CHF() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Currency valueRead = config.get("tests.converter.currency.code1", Currency.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead, Currency.getInstance("CHF"));
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Currency_Code_cHf() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Currency valueRead = config.get("tests.converter.currency.code2", Currency.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead, Currency.getInstance("CHF"));
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Currency_Code_CHF_Whitespace_Before() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Currency valueRead = config.get("tests.converter.currency.code3", Currency.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead, Currency.getInstance("CHF"));
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Currency_Code_CHF_Whitespace_After() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Currency valueRead = config.get("tests.converter.currency.code4", Currency.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead, Currency.getInstance("CHF"));
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Currency_Code_CHF_Whitespace_Around() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Currency valueRead = config.get("tests.converter.currency.code5", Currency.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead, Currency.getInstance("CHF"));
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Currency_Code_Numeric() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Currency valueRead = config.get("tests.converter.currency.code-numeric1", Currency.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.getNumericCode(), Currency.getInstance("BGL").getNumericCode());
+ valueRead = config.get("tests.converter.currency.code-numeric2", Currency.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.getNumericCode(), Currency.getInstance("BGL").getNumericCode());
+ valueRead = config.get("tests.converter.currency.code-numeric3", Currency.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.getNumericCode(), Currency.getInstance("BGL").getNumericCode());
+ valueRead = config.get("tests.converter.currency.code-numeric4", Currency.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.getNumericCode(), Currency.getInstance("BGL").getNumericCode());
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Currency_Code_Locale() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Currency valueRead = config.get("tests.converter.currency.code-locale1", Currency.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.getCurrencyCode(), "EUR");
+ valueRead = config.get("tests.converter.currency.code-locale2", Currency.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.getCurrencyCode(), "EUR");
+ valueRead = config.get("tests.converter.currency.code-locale3", Currency.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.getCurrencyCode(), "EUR");
+ valueRead = config.get("tests.converter.currency.code-locale4", Currency.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.getCurrencyCode(), "EUR");
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_NotPresent() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Byte valueRead = config.get("tests.converter.byte.foo", Byte.class);
+ assertFalse(valueRead!=null);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/DoubleConverterTest.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/DoubleConverterTest.java b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/DoubleConverterTest.java
new file mode 100644
index 0000000..ee2f33a
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/DoubleConverterTest.java
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.converters;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests the default converter for bytes.
+ */
+public class DoubleConverterTest {
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Double_Decimal() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Double valueRead = config.get("tests.converter.double.decimal", Double.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.doubleValue(), 1.23456789, 0.0d);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Double_DecimalNegative() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Double valueRead = config.get("tests.converter.double.decimalNegative", Double.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.doubleValue(), -1.23456789, 0.0d);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Double_Integer() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Double valueRead = config.get("tests.converter.double.integer", Double.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.doubleValue(),100d, 0.0d);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Double_Hex1() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Double valueRead = config.get("tests.converter.double.hex1", Double.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.doubleValue(),255d, 0.0d);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Double_Hex2() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Double valueRead = config.get("tests.converter.double.hex2", Double.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.doubleValue(),-255d, 0.0d);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Double_Hex3() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Double valueRead = config.get("tests.converter.double.hex3", Double.class);
+ assertTrue(valueRead!=null);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Double_MinValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Double valueRead = config.get("tests.converter.double.min", Double.class);
+ assertTrue(valueRead!=null);
+ assertEquals(Double.MIN_VALUE, valueRead.doubleValue(),0.0d);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Double_MaxValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Double valueRead = config.get("tests.converter.double.max", Double.class);
+ assertTrue(valueRead!=null);
+ assertEquals(Double.MAX_VALUE, valueRead.doubleValue(),0.0d);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Double_NaNValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Double valueRead = config.get("tests.converter.double.nan", Double.class);
+ assertTrue(valueRead!=null);
+ assertEquals(Double.NaN, valueRead.doubleValue(),0.0d);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Double_PositiveInfinityValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Double valueRead = config.get("tests.converter.double.pi", Double.class);
+ assertTrue(valueRead!=null);
+ assertEquals(Double.POSITIVE_INFINITY, valueRead.doubleValue(),0.0d);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Double_NegativeInfinityValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Double valueRead = config.get("tests.converter.double.ni", Double.class);
+ assertTrue(valueRead!=null);
+ assertEquals(Double.NEGATIVE_INFINITY, valueRead.doubleValue(),0.0d);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/EnumConverterTest.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/EnumConverterTest.java b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/EnumConverterTest.java
new file mode 100644
index 0000000..52d643e
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/EnumConverterTest.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.core.internal.converters;
+
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.builder.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/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/FloatConverterTest.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/FloatConverterTest.java b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/FloatConverterTest.java
new file mode 100644
index 0000000..98ea720
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/FloatConverterTest.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.core.internal.converters;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests the default converter for bytes.
+ */
+public class FloatConverterTest {
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Float_Decimal() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Float valueRead = config.get("tests.converter.float.decimal", Float.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.floatValue(), 1.23456789f, 0.0f);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Float_DecimalNegative() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Float valueRead = config.get("tests.converter.float.decimalNegative", Float.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.floatValue(), -1.23456789f, 0.0f);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Float_Integer() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Float valueRead = config.get("tests.converter.float.integer", Float.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.floatValue(),100f, 0.0f);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Float_Hex1() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Float valueRead = config.get("tests.converter.float.hex1", Float.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.floatValue(),255f, 0.0f);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Float_Hex2() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Float valueRead = config.get("tests.converter.float.hex2", Float.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.floatValue(),-255f, 0.0f);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Float_Hex3() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Float valueRead = config.get("tests.converter.float.hex3", Float.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.floatValue(),255f, 0.0f);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Float_MinValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Float valueRead = config.get("tests.converter.float.min", Float.class);
+ assertTrue(valueRead!=null);
+ assertEquals(Float.MIN_VALUE, valueRead.floatValue(),0.0f);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Float_MaxValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Float valueRead = config.get("tests.converter.float.max", Float.class);
+ assertTrue(valueRead!=null);
+ assertEquals(Float.MAX_VALUE, valueRead.floatValue(),0.0f);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Float_NaNValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Float valueRead = config.get("tests.converter.float.nan", Float.class);
+ assertTrue(valueRead!=null);
+ assertEquals(Float.NaN, valueRead.floatValue(),0.0f);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Float_PositiveInfinityValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Float valueRead = config.get("tests.converter.float.pi", Float.class);
+ assertTrue(valueRead!=null);
+ assertEquals(Float.POSITIVE_INFINITY, valueRead.floatValue(),0.0f);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Float_NegativeInfinityValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Float valueRead = config.get("tests.converter.float.ni", Float.class);
+ assertTrue(valueRead!=null);
+ assertEquals(Float.NEGATIVE_INFINITY, valueRead.floatValue(),0.0f);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/IntegerConverterTest.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/IntegerConverterTest.java b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/IntegerConverterTest.java
new file mode 100644
index 0000000..03b0f12
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/IntegerConverterTest.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.converters;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests the default converter for Integers.
+ */
+public class IntegerConverterTest {
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Integer_Decimal() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Integer valueRead = config.get("tests.converter.integer.decimal", Integer.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.intValue(), 101);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Integer_Octal() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Integer valueRead = config.get("tests.converter.integer.octal", Integer.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.intValue(), Integer.decode("02").intValue());
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Integer_Hex() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Integer valueRead = config.get("tests.converter.integer.hex.lowerX", Integer.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.intValue(), Integer.decode("0x2F").intValue());
+ valueRead = config.get("tests.converter.integer.hex.upperX", Integer.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.intValue(), Integer.decode("0X3F").intValue());
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_NotPresent() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Integer valueRead = config.get("tests.converter.integer.foo", Integer.class);
+ assertFalse(valueRead != null);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Integer_MinValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Integer valueRead = config.get("tests.converter.integer.min", Integer.class);
+ assertTrue(valueRead != null);
+ assertEquals(Integer.MIN_VALUE, valueRead.intValue());
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Integer_MaxValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Integer valueRead = config.get("tests.converter.integer.max", Integer.class);
+ assertTrue(valueRead != null);
+ assertEquals(Integer.MAX_VALUE, valueRead.intValue());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/LongConverterTest.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/LongConverterTest.java b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/LongConverterTest.java
new file mode 100644
index 0000000..0df6b09
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/LongConverterTest.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.converters;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests the default converter for Longs.
+ */
+public class LongConverterTest {
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Long_Decimal() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Long valueRead = config.get("tests.converter.long.decimal", Long.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.intValue(), 101);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Long_Octal() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Long valueRead = config.get("tests.converter.long.octal", Long.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.intValue(), Long.decode("02").intValue());
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Long_Hex() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Long valueRead = config.get("tests.converter.long.hex.lowerX", Long.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.intValue(), Long.decode("0x2F").intValue());
+ valueRead = config.get("tests.converter.long.hex.upperX", Long.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.intValue(), Long.decode("0X3F").intValue());
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_NotPresent() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Long valueRead = config.get("tests.converter.long.foo", Long.class);
+ assertFalse(valueRead != null);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Long_MinValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Long valueRead = config.get("tests.converter.long.min", Long.class);
+ assertTrue(valueRead != null);
+ assertEquals(Long.MIN_VALUE, valueRead.longValue());
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Long_MaxValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Long valueRead = config.get("tests.converter.long.max", Long.class);
+ assertTrue(valueRead != null);
+ assertEquals(Long.MAX_VALUE, valueRead.longValue());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/NumberConverterTest.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/NumberConverterTest.java b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/NumberConverterTest.java
new file mode 100644
index 0000000..3fa2e58
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/NumberConverterTest.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.core.internal.converters;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.junit.Test;
+
+import java.math.BigDecimal;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests the default converter for Number.
+ */
+public class NumberConverterTest {
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Decimal() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Number valueRead = config.get("tests.converter.bd.decimal", Number.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead, 101L);
+ }
+
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Hex() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Number valueRead = config.get("tests.converter.bd.hex.lowerX", Number.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead, Long.valueOf("47"));
+ valueRead = config.get("tests.converter.bd.hex.upperX", Number.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead, Long.valueOf("63"));
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_NotPresent() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Number valueRead = config.get("tests.converter.bd.foo", Number.class);
+ assertFalse(valueRead!=null);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_BigValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Number valueRead = config.get("tests.converter.bd.big", Number.class);
+ assertTrue(valueRead!=null);
+ assertEquals(new BigDecimal("101666666666666662333337263723628763821638923628193612983618293628763"),
+ valueRead);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_BigFloatValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Number valueRead = config.get("tests.converter.bd.bigFloat", Number.class);
+ assertTrue(valueRead!=null);
+ assertEquals(new BigDecimal("1016666666666666623333372637236287638216389293628763.1016666666666666623333372" +
+ "63723628763821638923628193612983618293628763"), valueRead);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/ShortConverterTest.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/ShortConverterTest.java b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/ShortConverterTest.java
new file mode 100644
index 0000000..193a92e
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/ShortConverterTest.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.converters;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests the default converter for Shorts.
+ */
+public class ShortConverterTest {
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Short_Decimal() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Short valueRead = config.get("tests.converter.short.decimal", Short.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.intValue(), 101);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Short_Octal() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Short valueRead = config.get("tests.converter.short.octal", Short.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.intValue(), Short.decode("02").intValue());
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Short_Hex() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Short valueRead = config.get("tests.converter.short.hex.lowerX", Short.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.intValue(), Short.decode("0x2F").intValue());
+ valueRead = config.get("tests.converter.short.hex.upperX", Short.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead.intValue(), Short.decode("0X3F").intValue());
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_NotPresent() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Short valueRead = config.get("tests.converter.short.foo", Short.class);
+ assertFalse(valueRead != null);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Short_MinValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Short valueRead = config.get("tests.converter.short.min", Short.class);
+ assertTrue(valueRead != null);
+ assertEquals(Short.MIN_VALUE, valueRead.intValue());
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Short_MaxValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Short valueRead = config.get("tests.converter.short.max", Short.class);
+ assertTrue(valueRead != null);
+ assertEquals(Short.MAX_VALUE, valueRead.intValue());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/util/mockito/NotMockedAnswer.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/util/mockito/NotMockedAnswer.java b/modules/types/src/test/java/org/apache/tamaya/types/util/mockito/NotMockedAnswer.java
new file mode 100644
index 0000000..3188d85
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/util/mockito/NotMockedAnswer.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.builder.util.mockito;
+
+import org.mockito.exceptions.base.MockitoException;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.io.Serializable;
+
+// @todo This is a duplicated class
+public class NotMockedAnswer implements Answer<Object>, Serializable {
+ public final static NotMockedAnswer NOT_MOCKED_ANSWER = new NotMockedAnswer();
+
+ private NotMockedAnswer() {
+ }
+
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ if("toString".equals(invocation.getMethod().getName())){
+ return "Some "+invocation.getMethod().getDeclaringClass().getName();
+ }
+ StringBuilder msgBuilder = new StringBuilder();
+
+ msgBuilder.append("Invocation of method not mocked: ")
+ .append(invocation.getMethod().toGenericString());
+
+ if (invocation.getArguments().length > 0) {
+ msgBuilder.append(" Supplied arguments: ");
+
+ for (int i = 0; i < invocation.getArguments().length; i++) {
+ msgBuilder.append(invocation.getArguments()[i]);
+
+ if (i - 1 < invocation.getArguments().length) {
+ msgBuilder.append(", ");
+ }
+ }
+ }
+ throw new MockitoException(msgBuilder.toString());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeA.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeA.java b/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeA.java
new file mode 100644
index 0000000..89b2f5b
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeA.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.builder.util.types;
+
+/**
+ * Custom type with two argument constructor.
+ */
+public class CustomTypeA {
+ private String name;
+
+ public CustomTypeA(String name, String other) {
+ this.name = name + other;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeB.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeB.java b/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeB.java
new file mode 100644
index 0000000..f7f4d99
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeB.java
@@ -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 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.builder.util.types;
+
+/**
+ * Custom type with factory method
+ * {@link org.apache.tamaya.builder.util.types.CustomTypeB#of(String)}
+ */
+public class CustomTypeB {
+ private String name;
+
+ private CustomTypeB(String value) {
+ this.name = value;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public static CustomTypeB of(String source) {
+ return new CustomTypeB(source);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeC.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeC.java b/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeC.java
new file mode 100644
index 0000000..da9ce56
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeC.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.builder.util.types;
+
+public class CustomTypeC {
+ private String value;
+
+
+ public CustomTypeC(String in, @SuppressWarnings("unused") int iHideThisConstructorForTamaya) {
+ value = in;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public static CustomTypeC produceFrom(String in) {
+ return new CustomTypeC(in, -1);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeCPropertyConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeCPropertyConverter.java b/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeCPropertyConverter.java
new file mode 100644
index 0000000..084b38b
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/util/types/CustomTypeCPropertyConverter.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.builder.util.types;
+
+import org.apache.tamaya.builder.spi.ConversionContext;
+import org.apache.tamaya.builder.spi.PropertyConverter;
+
+public class CustomTypeCPropertyConverter implements PropertyConverter<org.apache.tamaya.builder.util.types.CustomTypeC> {
+ @Override
+ public org.apache.tamaya.builder.util.types.CustomTypeC convert(String value, ConversionContext context) {
+ return org.apache.tamaya.builder.util.types.CustomTypeC.produceFrom(value);
+ }
+}
[6/7] incubator-tamaya git commit: - Minimalized API. - Propagated
change to rest of modules.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/ProgrammaticConfigurationContext.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/ProgrammaticConfigurationContext.java b/modules/builder/src/main/java/org/apache/tamaya/builder/ProgrammaticConfigurationContext.java
deleted file mode 100644
index 05acdc3..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/ProgrammaticConfigurationContext.java
+++ /dev/null
@@ -1,388 +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.builder;
-
-
-import org.apache.tamaya.builder.spi.PropertyConverter;
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.builder.spi.ConfigurationContext;
-import org.apache.tamaya.builder.spi.ConfigurationContextBuilder;
-import org.apache.tamaya.builder.spi.PropertyFilter;
-import org.apache.tamaya.builder.spi.PropertySource;
-import org.apache.tamaya.builder.spi.PropertySourceProvider;
-import org.apache.tamaya.builder.spi.PropertyValueCombinationPolicy;
-import org.apache.tamaya.builder.spi.ServiceContextManager;
-import org.apache.tamaya.spisupport.PriorityServiceComparator;
-import org.apache.tamaya.spisupport.PropertyConverterManager;
-import org.apache.tamaya.spisupport.PropertySourceComparator;
-
-import javax.annotation.Priority;
-import java.util.*;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.logging.Logger;
-
-/**
- * Implementation of the {@link ConfigurationContext}
- * used by the {@link org.apache.tamaya.builder.ConfigurationBuilder}
- * internally.
- */
-class ProgrammaticConfigurationContext implements ConfigurationContext {
-
- private static final Comparator<PropertySource> PS_COMPARATOR = new PropertySourceComparator();
- private static final Comparator<Object> COMP_COMPARATOR = new PriorityServiceComparator();
- /**
- * The logger used.
- */
- private final static Logger LOG = Logger.getLogger(ProgrammaticConfigurationContext.class.getName());
- /**
- * Cubcomponent handling {@link PropertyConverter} instances.
- */
- private PropertyConverterManager propertyConverterManager = new PropertyConverterManager();
-
- /**
- * The current unmodifiable list of loaded {@link PropertySource} instances.
- */
- private List<PropertySource> immutablePropertySources = new ArrayList<>();
-
- /**
- * The current unmodifiable list of loaded {@link PropertyFilter} instances.
- */
- private List<PropertyFilter> immutablePropertyFilters = new ArrayList<>();
-
- /**
- * The overriding policy used when combining PropertySources registered to evalute the final configuration
- * values.
- */
- private PropertyValueCombinationPolicy propertyValueCombinationPolicy;
-
- /**
- * Lock for internal synchronization.
- */
- private final ReadWriteLock propertySourceLock = 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.
- */
- @SuppressWarnings("unchecked")
- public ProgrammaticConfigurationContext(Builder builder) {
- propertyConverterManager = new PropertyConverterManager(builder.loadProvidedPropertyConverters);
-
- List<PropertySource> sources = getAllPropertySources(builder);
- Collections.sort(sources, PS_COMPARATOR);
- immutablePropertySources = Collections.unmodifiableList(sources);
-
-
- List<PropertyFilter> filters = getPropertyFilters(builder);
- Collections.sort(filters, COMP_COMPARATOR);
- immutablePropertyFilters = Collections.unmodifiableList(filters);
-
-
- propertyValueCombinationPolicy = builder.propertyValueCombinationPolicy;
- for(Map.Entry<TypeLiteral<?>, List<PropertyConverter<?>>> en: builder.propertyConverters.entrySet()){
- if(en!=null){
- for(PropertyConverter pv:en.getValue()) {
- propertyConverterManager.register(en.getKey(), pv);
- }
- }
- }
-
- LOG.info("Using " + immutablePropertySources.size() + " property sources: " + immutablePropertySources);
- LOG.info("Using " + immutablePropertyFilters.size() + " property filters: " + immutablePropertyFilters);
- LOG.info("Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
- }
-
- private List<PropertyFilter> getPropertyFilters(Builder builder) {
- List<PropertyFilter> provided = new ArrayList<>();
- if(builder.loadProvidedPropertyFilters) {
- provided.addAll(ServiceContextManager.getServiceContext().getServices(PropertyFilter.class));
- }
- for(PropertyFilter pf:builder.propertyFilters) {
- if (pf != null) {
- provided.add(pf);
- }
- }
- return provided;
- }
-
- private List<PropertySource> getAllPropertySources(Builder builder) {
- List<PropertySource> provided = new ArrayList<>();
- if(builder.loadProvidedPropertySources) {
- provided.addAll(ServiceContextManager.getServiceContext().getServices(PropertySource.class));
- }
- for(PropertySource ps:builder.propertySources){
- if(ps!=null){
- provided.add(ps);
- }
- }
- if (builder.loadProvidedPropertySourceProviders) {
- List<PropertySourceProvider> providers = ServiceContextManager.getServiceContext()
- .getServices(PropertySourceProvider.class);
- for (PropertySourceProvider provider : providers) {
- for(PropertySource ps:provider.getPropertySources()) {
- if(ps!=null) {
- provided.addAll(provider.getPropertySources());
- }
- }
- }
- }
- return provided;
- }
-
- public void addPropertySources(PropertySource... propertySourcesToAdd) {
- Lock writeLock = propertySourceLock.writeLock();
- try {
- writeLock.lock();
- List<PropertySource> provided = new ArrayList<>();
- for(PropertySource ps:propertySourcesToAdd){
- if(ps!=null){
- provided.add(ps);
- }
- }
- this.immutablePropertySources = Collections.unmodifiableList(provided);
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * 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) {
-
- //X TODO this method duplicates DefaultConfigurationContext.PropertySourceComparator.comparePropertySources()
- //X maybe we should extract the Comperator in an own class for real code-reuse (copy paste == bad code reuse)
-
- if (source1.getOrdinal() < source2.getOrdinal()) {
- return -1;
- } else if (source1.getOrdinal() > source2.getOrdinal()) {
- return 1;
- } else {
- return source1.getClass().getName().compareTo(source2.getClass().getName());
- }
- }
-
- /**
- * 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) {
-
- //X TODO this method duplicates DefaultConfigurationContext.PropertySourceComparator.comparePropertyFilters()
- //X maybe we should extract the Comperator in an own class for real code-reuse (copy paste == bad code reuse)
-
- 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 List<PropertySource> getPropertySources() {
- return immutablePropertySources;
- }
-
- 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() {
- // @todo Check if it could be useful to support this method, Oliver B. Fischer
- throw new RuntimeException("This method is currently not supported.");
- }
-
- /**
- * The Builder for {@link ProgrammaticConfigurationContext}
- */
- public final static class Builder {
- /**
- * The current unmodifiable list of loaded {@link PropertySource} instances.
- */
- private final List<PropertySource> propertySources = new ArrayList<>();
-
- /**
- * The current unmodifiable list of loaded {@link PropertyFilter} instances.
- */
- private final List<PropertyFilter> propertyFilters = new ArrayList<>();
-
- private final Map<TypeLiteral<?>, List<PropertyConverter<?>>> propertyConverters = new HashMap<>();
-
- /**
- * The overriding policy used when combining PropertySources registered to evalute the final configuration
- * values.
- */
- private PropertyValueCombinationPolicy propertyValueCombinationPolicy =
- PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
-
- private boolean loadProvidedPropertyConverters;
- private boolean loadProvidedPropertySources;
- private boolean loadProvidedPropertySourceProviders;
- private boolean loadProvidedPropertyFilters;
-
- public Builder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy) {
- this.propertyValueCombinationPolicy = Objects.requireNonNull(policy);
- return this;
- }
-
- public Builder addPropertySources(PropertySource... propertySources) {
- for (PropertySource ps : propertySources) {
- if (ps != null) {
- this.propertySources.add(ps);
- }
- }
- return this;
- }
-
- public Builder addPropertySources(Collection<PropertySource> propertySources) {
- for (PropertySource ps : propertySources) {
- if (ps != null) {
- this.propertySources.add(ps);
- }
- }
- return this;
- }
-
- public Builder addPropertySourceProviders(PropertySourceProvider... propertySourceProviders) {
- for (PropertySourceProvider ps : propertySourceProviders) {
- if (ps != null) {
- this.propertySources.addAll(ps.getPropertySources());
- }
- }
- return this;
- }
-
- public Builder addPropertySourceProviders(Collection<PropertySourceProvider> propertySourceProviders) {
- for (PropertySourceProvider ps : propertySourceProviders) {
- if (ps != null) {
- this.propertySources.addAll(ps.getPropertySources());
- }
- }
- return this;
- }
-
- public Builder addPropertyFilters(PropertyFilter... propertyFIlter) {
- for (PropertyFilter pf : propertyFIlter) {
- if (pf != null) {
- this.propertyFilters.add(pf);
- }
- }
- return this;
- }
-
- public Builder addPropertyFilters(Collection<PropertyFilter> propertyFIlter) {
- for (PropertyFilter pf : propertyFIlter) {
- if (pf != null) {
- this.propertyFilters.add(pf);
- }
- }
- return this;
- }
-
- /**
- * Should be never used.
- */
- @Deprecated
- public Builder setConfigurationContext(ConfigurationContext configurationContext) {
- this.addPropertySources(configurationContext.getPropertySources());
- this.addPropertyFilters(configurationContext.getPropertyFilters());
- this.propertyValueCombinationPolicy = Objects.requireNonNull(
- configurationContext.getPropertyValueCombinationPolicy());
- return this;
- }
-
- //X TODO think on a functonality/API for using the default PropertyConverters and use the configured ones here
- //X TODO as overrides used first.
-
- public <T> Builder addPropertyConverter(TypeLiteral<T> type, PropertyConverter<T> propertyConverter) {
- if(!propertyConverters.containsKey(type)){
- List<PropertyConverter<?>> convList = new ArrayList<>();
- convList.add(propertyConverter);
- propertyConverters.put(type, convList);
- }
- return this;
- }
-
- public ConfigurationContext build() {
- return new ProgrammaticConfigurationContext(this);
- }
-
-
- public void loadProvidedPropertyConverters(boolean state) {
- loadProvidedPropertyConverters = state;
- }
-
- public void loadProvidedPropertySources(boolean state) {
- loadProvidedPropertySources = state;
- }
-
- public void loadProvidedPropertySourceProviders(boolean state) {
- loadProvidedPropertySourceProviders = state;
- }
-
- public void loadProvidedPropertyFilters(boolean state) {
- loadProvidedPropertyFilters = state;
- }
-
- }
-
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/PropertySourceBasedConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/PropertySourceBasedConfiguration.java b/modules/builder/src/main/java/org/apache/tamaya/builder/PropertySourceBasedConfiguration.java
new file mode 100644
index 0000000..376966c
--- /dev/null
+++ b/modules/builder/src/main/java/org/apache/tamaya/builder/PropertySourceBasedConfiguration.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.builder;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.builder.spi.PropertyFilter;
+import org.apache.tamaya.builder.spi.PropertySource;
+import org.apache.tamaya.builder.spi.PropertyValueCombinationPolicy;
+
+import java.util.List;
+
+/**
+ * Central SPI for programmatically dealing with the setup of the configuration system.
+ * This includes adding and enlisting {@link PropertySource}s,
+ * ConfigFilters, etc.
+ */
+public interface PropertySourceBasedConfiguration extends Configuration {
+
+ /**
+ * This method can be used for programmatically adding {@link PropertySource}s.
+ * It is not needed for normal 'usage' by end users, but only for Extension Developers!
+ *
+ * @param propertySourcesToAdd the PropertySources to add
+ */
+ void addPropertySources(PropertySource... propertySourcesToAdd);
+
+ /**
+ * This method returns the current list of registered PropertySources ordered via their ordinal.
+ * PropertySources with a lower ordinal come last. The PropertySource with the
+ * highest ordinal comes first.
+ * If two PropertySources have the same ordinal number they will get sorted
+ * using their class name just to ensure the user at least gets the same ordering
+ * after a JVM restart, hereby names before are added last.
+ * PropertySources are loaded when this method is called the first time, which basically is
+ * when the first time configuration is accessed.
+ *
+ * @return a sorted list of registered PropertySources. The returned list need not be modifiable
+ */
+ List<PropertySource> getPropertySources();
+
+ /**
+ * Access the current PropertyFilter instances.
+ * @return the list of registered PropertyFilters, never null.
+ */
+ List<PropertyFilter> getPropertyFilters();
+
+ /**
+ * Access the {@link PropertyValueCombinationPolicy} used to evaluate the final
+ * property values.
+ * @return the {@link PropertyValueCombinationPolicy} used, never null.
+ */
+ PropertyValueCombinationPolicy getPropertyValueCombinationPolicy();
+
+ /**
+ * Creates a {@link PropertySourceBasedConfigurationBuilder} preinitialized with the data from this instance.
+ * @return a new builder instance, never null.
+ */
+ PropertySourceBasedConfigurationBuilder toBuilder();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/PropertySourceBasedConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/PropertySourceBasedConfigurationBuilder.java b/modules/builder/src/main/java/org/apache/tamaya/builder/PropertySourceBasedConfigurationBuilder.java
new file mode 100644
index 0000000..c7dd922
--- /dev/null
+++ b/modules/builder/src/main/java/org/apache/tamaya/builder/PropertySourceBasedConfigurationBuilder.java
@@ -0,0 +1,483 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.builder;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.builder.propertysource.SimplePropertySource;
+import org.apache.tamaya.builder.spi.*;
+import org.apache.tamaya.format.ConfigurationData;
+import org.apache.tamaya.format.ConfigurationFormats;
+import org.apache.tamaya.format.FlattenedDefaultPropertySource;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static java.lang.String.format;
+
+/**
+ * <p>Builder class used for building a configuration manually without relying
+ * only on the Service Provider Interface API.</p>
+ *
+ * <p><strong>Features of the builder</strong></p>
+ *
+ * <ol>
+ * <li>Adding of property converters manually</li>
+ * <li>Adding of property sources directly</li>
+ * <li>Adding of property sources via URL</li>
+ * <li>Adding of property source providers directly</li>
+ * <li>Enabling and disabling of via SPI mechanism provided resources as converters,
+ * property sources, etc.</li>
+ * </ol>
+ *
+ * <p><strong>Example</strong></p>
+ *
+ * <pre>{@code ConfigurationBuilder builder = new ConfigurationBuilder();
+ * builder.disableProvidedPropertySources() // Do not load provided property
+ * .disableProvidedPropertySourceProviders() // sources and providers automatically
+ * .addPropertySource("file:/etc/conf.properties"); // Load properties from conf.properties
+ *
+ * Configuration config = builder.build();
+ * }</pre>
+ *
+ * <p><strong>Support for configuration formats</strong></p>
+ *
+ * The configuration builder allows you to put property resources
+ * via a URL, as shown in the code example above, without implementing
+ * a {@link PropertySource PropertySource} or providing an
+ * instance of a {@link PropertySource PropertySource}.
+ * If a property resource in
+ * a specific format can be added to configuration builder or not depends
+ * on the available implementations of
+ * {@link org.apache.tamaya.format.ConfigurationFormat} in the classpath.
+ * Which formats are available can be checked via
+ * {@link org.apache.tamaya.format.ConfigurationFormats#getFormats()}.
+ */
+public class PropertySourceBasedConfigurationBuilder {
+ private static final Logger LOG = Logger.getLogger(PropertySourceBasedConfigurationBuilder.class.getName());
+ /**
+ * The current unmodifiable list of loaded {@link PropertySource} instances.
+ */
+ private final List<PropertySource> propertySources = new ArrayList<>();
+
+ /**
+ * The current unmodifiable list of loaded {@link PropertyFilter} instances.
+ */
+ private final List<PropertyFilter> propertyFilters = new ArrayList<>();
+
+ /**
+ * The overriding policy used when combining PropertySources registered to evalute the final configuration
+ * values.
+ */
+ private PropertyValueCombinationPolicy propertyValueCombinationPolicy =
+ PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+
+ private boolean loadProvidedPropertySources;
+ private boolean loadProvidedPropertySourceProviders;
+ private boolean loadProvidedPropertyFilters;
+
+ /**
+ * Flag if the config has already been built.
+ * Configuration can be built only once
+ */
+ private boolean built;
+
+ public PropertySourceBasedConfigurationBuilder(){
+ }
+
+ public PropertySourceBasedConfigurationBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy) {
+ this.propertyValueCombinationPolicy = Objects.requireNonNull(policy);
+ return this;
+ }
+
+ public PropertySourceBasedConfigurationBuilder addPropertySources(PropertySource... propertySources) {
+ for (PropertySource ps : propertySources) {
+ if (ps != null) {
+ this.propertySources.add(ps);
+ }
+ }
+ return this;
+ }
+
+ public PropertySourceBasedConfigurationBuilder addPropertySources(Collection<PropertySource> propertySources) {
+ for (PropertySource ps : propertySources) {
+ if (ps != null) {
+ this.propertySources.add(ps);
+ }
+ }
+ return this;
+ }
+
+ public PropertySourceBasedConfigurationBuilder addPropertySourceProviders(PropertySourceProvider... propertySourceProviders) {
+ for (PropertySourceProvider ps : propertySourceProviders) {
+ if (ps != null) {
+ this.propertySources.addAll(ps.getPropertySources());
+ }
+ }
+ return this;
+ }
+
+ public PropertySourceBasedConfigurationBuilder addPropertySourceProviders(Collection<PropertySourceProvider> propertySourceProviders) {
+ for (PropertySourceProvider ps : propertySourceProviders) {
+ if (ps != null) {
+ this.propertySources.addAll(ps.getPropertySources());
+ }
+ }
+ return this;
+ }
+
+ public PropertySourceBasedConfigurationBuilder addPropertyFilters(PropertyFilter... propertyFIlter) {
+ for (PropertyFilter pf : propertyFIlter) {
+ if (pf != null) {
+ this.propertyFilters.add(pf);
+ }
+ }
+ return this;
+ }
+
+ public PropertySourceBasedConfigurationBuilder addPropertyFilters(Collection<PropertyFilter> propertyFIlter) {
+ for (PropertyFilter pf : propertyFIlter) {
+ if (pf != null) {
+ this.propertyFilters.add(pf);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Should be never used.
+ */
+ @Deprecated
+ public PropertySourceBasedConfigurationBuilder usePropertySourceBasedConfiguration(PropertySourceBasedConfiguration configurationContext) {
+ addPropertySources(configurationContext.getPropertySources());
+ addPropertyFilters(configurationContext.getPropertyFilters());
+ this.propertyValueCombinationPolicy = Objects.requireNonNull(
+ configurationContext.getPropertyValueCombinationPolicy());
+ return this;
+ }
+
+ public void loadProvidedPropertySources(boolean state) {
+ loadProvidedPropertySources = state;
+ }
+
+ public void loadProvidedPropertySourceProviders(boolean state) {
+ loadProvidedPropertySourceProviders = state;
+ }
+
+ public void loadProvidedPropertyFilters(boolean state) {
+ loadProvidedPropertyFilters = state;
+ }
+
+ public PropertySourceBasedConfigurationBuilder setConfiguration(PropertySourceBasedConfiguration context) {
+ this.propertySources.clear();
+ for(PropertySource ps:context.getPropertySources()) {
+ addPropertySources(ps);
+ }
+ this.propertyFilters.clear();
+ this.propertyFilters.addAll(context.getPropertyFilters());
+ this.propertyValueCombinationPolicy = context.getPropertyValueCombinationPolicy();
+ return this;
+ }
+
+ public PropertySourceBasedConfigurationBuilder addPropertySourceURLs(Collection<URL> propertySourceURLsToAdd) {
+ for(URL url:propertySourceURLsToAdd){
+ try {
+ ConfigurationData data = ConfigurationFormats.readConfigurationData(url);
+ addPropertySources(new SimplePropertySource(url.toString(),data.getCombinedProperties()));
+ }catch(Exception e){
+ LOG.log(Level.SEVERE, "Failed to load config from: " + url, e);
+ }
+ }
+ for(URL url:propertySourceURLsToAdd) {
+ try {
+ this.propertySources.add(new SimplePropertySource(url.toString(), getConfigurationDataFromURL(url).getCombinedProperties()));
+ } catch (IOException e) {
+ LOG.log(Level.SEVERE, "Error loading config from: " + url, e);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Adds one resources with properties in an arbitrary format
+ * to the configuration to be build.
+ *
+ * <p>If a specific format is supported depends on the available
+ * {@link org.apache.tamaya.format.ConfigurationFormat} implementations.</p>
+ *
+ * <pre>{@code URL resource = new URL("file:/etc/service/config.json");
+ *
+ * builder.addPropertySources(resource);}
+ * </pre>
+ *
+ * @param url resource with properties for the the configuration to be build.
+ *
+ * @return the builder instance currently used
+ *
+ * @see org.apache.tamaya.format.ConfigurationFormat
+ * @see org.apache.tamaya.format.ConfigurationFormats#getFormats()
+ */
+ public PropertySourceBasedConfigurationBuilder addPropertySource(URL url) {
+ try {
+ ConfigurationData data = getConfigurationDataFromURL(url);
+ addPropertySources(new SimplePropertySource(url.toString(), data.getCombinedProperties()));
+ } catch (IOException e) {
+ throw new ConfigException("Failed to read " + url.toString(), e);
+ }
+ return this;
+ }
+
+ protected ConfigurationData getConfigurationDataFromURL(URL url) throws IOException {
+ ConfigurationData data = ConfigurationFormats.readConfigurationData(url);
+
+ if (null == data) {
+ String mesg = format("No configuration format found which is able " +
+ "to read properties from %s.", url.toString());
+
+ throw new ConfigException(mesg);
+ }
+
+ return data;
+ }
+
+ public PropertySourceBasedConfigurationBuilder addPropertySourceURLs(URL... propertySourcesToAdd) {
+ return addPropertySourceURLs(Arrays.asList(propertySourcesToAdd));
+ }
+
+ public PropertySourceBasedConfigurationBuilder removePropertySources(Collection<String> propertySourcesToRemove) {
+ for(String key: propertySourcesToRemove){
+ this.propertySources.remove(key);
+ }
+ return this;
+ }
+
+ public PropertySourceBasedConfigurationBuilder removePropertySources(String... propertySourcesToRemove) {
+ return removePropertySources(Arrays.asList(propertySourcesToRemove));
+ }
+
+
+ /**
+ * Adds one or more resources with properties in an arbitrary format
+ * to the configuration to be build.
+ *
+ * <p>If a specific format is supported depends on the available
+ * {@link org.apache.tamaya.format.ConfigurationFormat} implementations.</p>
+ *
+ *<pre>{@code builder.addPropertySources("file:/etc/service/config.json",
+ * "file:/etc/defaults/values.properties");}
+ *</pre>
+ *
+ * @param urls list of resources with properties for the configuration to be
+ * build.
+ *
+ * @return the builder instance currently used
+ *
+ * @see org.apache.tamaya.format.ConfigurationFormat
+ * @see org.apache.tamaya.format.ConfigurationFormats#getFormats()
+ */
+ public PropertySourceBasedConfigurationBuilder addPropertySourceURLs(String... urls) {
+ for(String url:urls) {
+ if (url != null) {
+ try{
+ addPropertySource(new URL(url));
+ } catch(Exception e){
+ throw new ConfigException("Invalid URL: " + url);
+ }
+ }
+ }
+ return this;
+ }
+
+
+ /**
+ * Enables the automatic loading of all {@link PropertySource}
+ * service providers.
+ *
+ * @return the builder instance currently used
+ *
+ * @see PropertySource
+ * @see #disableProvidedPropertySources()
+ */
+ public PropertySourceBasedConfigurationBuilder enableProvidedPropertySources() {
+ checkBuilderState();
+
+ loadProvidedPropertySources = true;
+
+ return this;
+ }
+
+ /**
+ * Enables the automatic loading of all {@link PropertySource}
+ * service providers.
+ *
+ * @return the builder instance currently used
+ *
+ * @see PropertySource
+ * @see #enableProvidedPropertySources()
+ */
+ public PropertySourceBasedConfigurationBuilder disableProvidedPropertySources() {
+ checkBuilderState();
+
+ loadProvidedPropertySources = false;
+
+ return this;
+ }
+
+ /**
+ * Checks if the automatic loading of all {@link PropertySource
+ * PropertySource} service providers is enabled or disabled.
+ *
+ * @return {@code true} if the automatic loading is enabled,
+ * otherwise {@code false}.
+ */
+ public boolean isPropertySourcesLoadingEnabled() {
+ return loadProvidedPropertySources;
+ }
+
+
+ /**
+ * Checks if the automatic loading of all {@link PropertyFilter
+ * PropertyFilter} service providers is enabled or disabled.
+ *
+ * @return {@code true} if the automatic loading is enabled,
+ * otherwise {@code false}.
+ */
+ public boolean isPropertyFilterLoadingEnabled() {
+ return loadProvidedPropertyFilters;
+ }
+
+ /**
+ * Enables the automatic loading of all {@link PropertyFilter}
+ * service providers.
+ *
+ * @return the builder instance currently used
+ *
+ * @see PropertyFilter
+ * @see #disableProvidedPropertyFilters()
+ * @see #addPropertyFilters(PropertyFilter...)
+ */
+ public PropertySourceBasedConfigurationBuilder enabledProvidedPropertyFilters() {
+ checkBuilderState();
+
+ loadProvidedPropertyFilters = true;
+
+ return this;
+ }
+
+ /**
+ * Disables the automatic loading of all {@link PropertyFilter}
+ * service providers.
+ *
+ * @see PropertyFilter
+ * @see #enabledProvidedPropertyFilters()
+ * @see #addPropertyFilters(PropertyFilter...)
+ *
+ * @return the builder instance currently used
+ */
+ public PropertySourceBasedConfigurationBuilder disableProvidedPropertyFilters() {
+ checkBuilderState();
+
+ loadProvidedPropertyFilters = false;
+
+ return this;
+ }
+
+ private void checkBuilderState() {
+ if (built) {
+ throw new IllegalStateException("Configuration has already been build.");
+ }
+ }
+
+ /**
+ * Adds one or more property source provider instances to the configuration to be build.
+ *
+ * <pre>{@code PropertySourceProvider jc = new JavaConfigurationProvider();
+ *
+ * builder.addPropertySources(jc)};
+ * </pre>
+ *
+ * @return the builder instance currently used
+ *
+ * @see PropertySourceProvider
+ */
+ public PropertySourceBasedConfigurationBuilder enableProvidedPropertySourceProviders() {
+ checkBuilderState();
+
+ loadProvidedPropertySourceProviders = true;
+
+ return this;
+ }
+
+ /**
+ * Disables the automatic loading of {@link PropertySourceProvider
+ * property source providers} provided via the SPI API.
+ *
+ * @return the builder instance currently used
+ */
+ public PropertySourceBasedConfigurationBuilder disableProvidedPropertySourceProviders() {
+ checkBuilderState();
+
+ loadProvidedPropertySourceProviders = false;
+
+ return this;
+ }
+
+ /**
+ * Checks if the automatic loading of {@link PropertySourceProvider
+ * PropertySourceProviders} is enabled or disabled.
+ *
+ * @return {@code true} if the automatic loading is enabled,
+ * otherwise {@code false}.
+ */
+ public boolean isPropertySourceProvidersLoadingEnabled() {
+ return loadProvidedPropertySourceProviders;
+ }
+
+ /**
+ * Builds a new configuration based on the configuration of this builder instance.
+ *
+ * @return a new {@link org.apache.tamaya.Configuration configuration instance},
+ * never {@code null}.
+ */
+ public PropertySourceBasedConfiguration build() {
+ checkBuilderState();
+ loadProvidedPropertySources(isPropertySourcesLoadingEnabled());
+ loadProvidedPropertySourceProviders(isPropertySourceProvidersLoadingEnabled());
+ loadProvidedPropertyFilters(isPropertyFilterLoadingEnabled());
+
+ return new DefaultPropertySourceBasedConfiguration(this);
+ }
+
+ /**
+ * Mapper to map a URL given as string to an URL instance.
+ */
+ private static class StringToURLMapper {
+ public URL apply(String u) {
+ try {
+ return new URL(u);
+ } catch (MalformedURLException e) {
+ throw new ConfigException(u + " is not a valid URL", e);
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/PropertySourceBuilder.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/PropertySourceBuilder.java b/modules/builder/src/main/java/org/apache/tamaya/builder/PropertySourceBuilder.java
index e880fb4..5a69231 100644
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/PropertySourceBuilder.java
+++ b/modules/builder/src/main/java/org/apache/tamaya/builder/PropertySourceBuilder.java
@@ -18,6 +18,7 @@
*/
package org.apache.tamaya.builder;
+import org.apache.tamaya.builder.propertysource.SimplePropertySource;
import org.apache.tamaya.builder.spi.PropertySource;
import java.util.HashMap;
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/SimplePropertySource.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/SimplePropertySource.java b/modules/builder/src/main/java/org/apache/tamaya/builder/SimplePropertySource.java
deleted file mode 100644
index 8218bc8..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/SimplePropertySource.java
+++ /dev/null
@@ -1,86 +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.builder;
-
-import org.apache.tamaya.builder.spi.PropertySource;
-import org.apache.tamaya.builder.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;
-
- 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 0;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public PropertyValue get(String key) {
- return null;
- }
-
- @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/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultConfigurationContext.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultConfigurationContext.java b/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultConfigurationContext.java
deleted file mode 100644
index cab4a49..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultConfigurationContext.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.builder.internal;
-
-import org.apache.tamaya.ConfigurationProvider;
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.builder.spi.ConfigurationContext;
-import org.apache.tamaya.builder.spi.ConfigurationContextBuilder;
-import org.apache.tamaya.builder.spi.PropertyConverter;
-import org.apache.tamaya.builder.spi.PropertyFilter;
-import org.apache.tamaya.builder.spi.PropertySource;
-import org.apache.tamaya.builder.spi.PropertySourceProvider;
-import org.apache.tamaya.builder.spi.PropertyValueCombinationPolicy;
-import org.apache.tamaya.builder.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;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.logging.Logger;
-
-/**
- * Default Implementation of a simple ConfigurationContext.
- */
-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(DefaultConfigurationContextBuilder builder) {
- List<PropertySource> propertySources = new ArrayList<>();
- // first we load all PropertySources which got registered via java.util.ServiceLoader
- propertySources.addAll(builder.propertySources.values());
- // 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 = 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;
- }
-
- @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();
- }
- }
-
- 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);
- }
- }
-
- 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 <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/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultConfigurationContextBuilder.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultConfigurationContextBuilder.java b/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultConfigurationContextBuilder.java
deleted file mode 100644
index 56a3379..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultConfigurationContextBuilder.java
+++ /dev/null
@@ -1,153 +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.builder.internal;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.builder.spi.PropertyConverter;
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.builder.spi.ConfigurationContext;
-import org.apache.tamaya.builder.spi.ConfigurationContextBuilder;
-import org.apache.tamaya.builder.spi.PropertyFilter;
-import org.apache.tamaya.builder.spi.PropertySource;
-import org.apache.tamaya.builder.spi.PropertyValueCombinationPolicy;
-
-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}.
- */
-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;
-
- public DefaultConfigurationContextBuilder(){
- }
-
- @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 addPropertyConverter(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/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultConfigurationProvider.java b/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultConfigurationProvider.java
deleted file mode 100644
index 254edd1..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultConfigurationProvider.java
+++ /dev/null
@@ -1,62 +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.builder.internal;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.builder.spi.*;
-
-/**
- * Implementation of the Configuration API. This class uses the current {@link ConfigurationContext} to evaluate the
- * chain of {@link PropertySource} and {@link PropertyFilter}
- * instance to evaluate the current Configuration.
- */
-public class DefaultConfigurationProvider implements ConfigurationProviderSpi {
-
- private ConfigurationContext context = new DefaultConfigurationContext();
- private Configuration config = new DefaultConfiguration(context);
-
- @Override
- public Configuration getConfiguration() {
- return config;
- }
-
- @Override
- public ConfigurationContext getConfigurationContext() {
- return context;
- }
-
- @Override
- public ConfigurationContextBuilder getConfigurationContextBuilder() {
- return ServiceContextManager.getServiceContext().getService(ConfigurationContextBuilder.class);
- }
-
- @Override
- public void setConfigurationContext(ConfigurationContext context){
- // TODO think on a SPI or move event part into API...
- this.config = new DefaultConfiguration(context);
- this.context = context;
- }
-
-
- @Override
- public boolean isConfigurationContextSettable() {
- return true;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultServiceContext.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultServiceContext.java b/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultServiceContext.java
deleted file mode 100644
index c75f98d..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/DefaultServiceContext.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.builder.internal;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.builder.spi.ServiceContext;
-
-import javax.annotation.Priority;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.ServiceLoader;
-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 java.util.ServiceLoader} to load the services required.
- */
-public final class DefaultServiceContext 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(DefaultServiceContext.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 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;
- }
-
- @Override
- public int ordinal() {
- return 1;
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIActivator.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIActivator.java b/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIActivator.java
deleted file mode 100644
index df20d3b..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIActivator.java
+++ /dev/null
@@ -1,53 +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.builder.internal;
-
-
-
-import org.apache.tamaya.builder.spi.ServiceContextManager;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-import java.util.logging.Logger;
-
-/**
- * A bundle activator that registers the {@link OSGIServiceLoader}.
- */
-public class OSGIActivator implements BundleActivator {
-
- private static final Logger LOG = Logger.getLogger(OSGIActivator.class.getName());
-
- private OSGIServiceLoader serviceLoader;
-
- @Override
- public void start(BundleContext context) {
- // Register marker service
- ServiceContextManager.set(new OSGIServiceContext(context));
- LOG.info("Registered OSGI enabled ServiceContext...");
- serviceLoader = new OSGIServiceLoader();
- context.addBundleListener(serviceLoader);
- }
-
- @Override
- public void stop(BundleContext context) {
- if(serviceLoader!=null) {
- context.removeBundleListener(serviceLoader);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIServiceComparator.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIServiceComparator.java b/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIServiceComparator.java
deleted file mode 100644
index 2ee3ef5..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIServiceComparator.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.builder.internal;
-
-import org.osgi.framework.ServiceReference;
-
-import javax.annotation.Priority;
-import java.util.Comparator;
-
-/**
- * Comparator implementation for odering services loaded based on their increasing priority values.
- */
-class OSGIServiceComparator implements Comparator<ServiceReference> {
-
- @Override
- public int compare(ServiceReference o1, ServiceReference o2) {
- int prio = getPriority(o1) - getPriority(o2);
- if (prio < 0) {
- return 1;
- } else if (prio > 0) {
- return -1;
- } else {
- return 0; //o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
- }
- }
-
- /**
- * 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) {
- return getPriority(o.getClass());
- }
-
- /**
- * Checks the given type optionally annotated with a @Priority. If present the annotation's value s evaluated.
- * If no such annotation is present, a default priority is returned (1);
- *
- * @param type the type, not null.
- * @return a priority, by default 1.
- */
- public static int getPriority(Class type) {
- int prio = 1;
- Priority priority = (Priority)type.getAnnotation(Priority.class);
- if (priority != null) {
- prio = priority.value();
- }
- return prio;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIServiceContext.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIServiceContext.java b/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIServiceContext.java
deleted file mode 100644
index 05c830f..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIServiceContext.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.builder.internal;
-
-import org.apache.tamaya.builder.spi.ServiceContext;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * ServiceContext implementation based on OSGI Service mechanisms.
- */
-public class OSGIServiceContext implements ServiceContext{
-
- private static final OSGIServiceComparator REF_COMPARATOR = new OSGIServiceComparator();
-
- private final BundleContext bundleContext;
-
- public OSGIServiceContext(BundleContext bundleContext){
- this.bundleContext = Objects.requireNonNull(bundleContext);
- }
-
- public boolean isInitialized(){
- return bundleContext != null;
- }
-
-
- @Override
- public int ordinal() {
- return 10;
- }
-
- @Override
- public <T> T getService(Class<T> serviceType) {
- ServiceReference<T> ref = this.bundleContext.getServiceReference(serviceType);
- if(ref!=null){
- return this.bundleContext.getService(ref);
- }
- return null;
- }
-
- @Override
- public <T> List<T> getServices(Class<T> serviceType) {
- List<ServiceReference<T>> refs = new ArrayList<>();
- try {
- refs.addAll(this.bundleContext.getServiceReferences(serviceType, null));
- Collections.sort(refs, REF_COMPARATOR);
- List<T> services = new ArrayList<>(refs.size());
- for(ServiceReference<T> ref:refs){
- T service = bundleContext.getService(ref);
- if(service!=null) {
- services.add(service);
- }
- }
- return services;
- } catch (InvalidSyntaxException e) {
- e.printStackTrace();
- return Collections.emptyList();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIServiceLoader.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIServiceLoader.java b/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIServiceLoader.java
deleted file mode 100644
index cf307d5..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/OSGIServiceLoader.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.builder.internal;
-
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleListener;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.util.tracker.ServiceTracker;
-
-/**
- * An bundle listener that registers services defined in META-INF/services, when a bundle is starting.
- *
- * @author anatole@apache.org
- */
-public class OSGIServiceLoader implements BundleListener {
- // Provide logging
- private static final Logger log = Logger.getLogger(OSGIServiceLoader.class.getName());
-
- private Map<Class, ServiceTracker<Object,Object>> services = new ConcurrentHashMap<>();
-
- @Override
- public void bundleChanged(BundleEvent bundleEvent) {
- // Parse and create metadta on STARTING
- if (bundleEvent.getType() == BundleEvent.STARTED) {
- Bundle bundle = bundleEvent.getBundle();
- if (bundle.getEntry("META-INF/services/") == null) {
- return;
- }
- Enumeration<String> entryPaths = bundle.getEntryPaths("META-INF/services/");
- while (entryPaths.hasMoreElements()) {
- String entryPath = entryPaths.nextElement();
- if(!entryPath.endsWith("/")) {
- processEntryPath(bundle, entryPath);
- }
- }
- }
- }
-
- private void processEntryPath(Bundle bundle, String entryPath) {
- try {
- String serviceName = entryPath.substring("META-INF/services/".length());
- Class<?> serviceClass = bundle.loadClass(serviceName);
-
- URL child = bundle.getEntry(entryPath);
- InputStream inStream = child.openStream();
-
- BufferedReader br = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));
- String implClassName = br.readLine();
- while (implClassName != null){
- int hashIndex = implClassName.indexOf("#");
- if (hashIndex > 0) {
- implClassName = implClassName.substring(0, hashIndex-1);
- }
- else if (hashIndex == 0) {
- implClassName = "";
- }
- implClassName = implClassName.trim();
- if (implClassName.length() > 0) {
- try {
- // Load the service class
- Class<?> implClass = bundle.loadClass(implClassName);
- if (!serviceClass.isAssignableFrom(implClass)) {
- log.warning("Configured service: " + implClassName + " is not assignble to " +
- serviceClass.getName());
- continue;
- }
- // Provide service properties
- Hashtable<String, String> props = new Hashtable<>();
- props.put(Constants.VERSION_ATTRIBUTE, bundle.getVersion().toString());
- String vendor = bundle.getHeaders().get(Constants.BUNDLE_VENDOR);
- props.put(Constants.SERVICE_VENDOR, (vendor != null ? vendor : "anonymous"));
- // Translate annotated @Priority into a service ranking
- props.put(Constants.SERVICE_RANKING,
- String.valueOf(PriorityServiceComparator.getPriority(implClass)));
-
- // Register the service factory on behalf of the intercepted bundle
- JDKUtilServiceFactory factory = new JDKUtilServiceFactory(implClass);
- BundleContext bundleContext = bundle.getBundleContext();
- bundleContext.registerService(serviceName, factory, props);
- }
- catch(Exception e){
- log.log(Level.SEVERE,
- "Failed to load service class using ServiceLoader logic: " + implClassName, e);
- }
- }
- implClassName = br.readLine();
- }
- br.close();
- }
- catch (RuntimeException rte) {
- throw rte;
- }
- catch (Exception e) {
- log.log(Level.SEVERE, "Failed to read services from: " + entryPath, e);
- }
- }
-
-
- /**
- * Service factory simply instantiating the configured service.
- */
- static class JDKUtilServiceFactory implements ServiceFactory
- {
- private final Class<?> serviceClass;
-
- public JDKUtilServiceFactory(Class<?> serviceClass) {
- this.serviceClass = serviceClass;
- }
-
- @Override
- public Object getService(Bundle bundle, ServiceRegistration registration) {
- try {
- return serviceClass.newInstance();
- }
- catch (Exception ex) {
- ex.printStackTrace();
- throw new IllegalStateException("Cannot instanciate service", ex);
- }
- }
-
- @Override
- public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PriorityServiceComparator.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PriorityServiceComparator.java b/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PriorityServiceComparator.java
deleted file mode 100644
index c7e3656..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PriorityServiceComparator.java
+++ /dev/null
@@ -1,67 +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.builder.internal;
-
-import javax.annotation.Priority;
-import java.util.Comparator;
-
-/**
- * Comparator implementation for odering services loaded based on their increasing priority values.
- */
-public class PriorityServiceComparator implements Comparator<Object> {
-
- @Override
- public int compare(Object o1, Object o2) {
- int prio = getPriority(o1) - getPriority(o2);
- if (prio < 0) {
- return 1;
- } else if (prio > 0) {
- return -1;
- } else {
- return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
- }
- }
-
- /**
- * 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) {
- return getPriority(o.getClass());
- }
-
- /**
- * Checks the given type optionally annotated with a @Priority. If present the annotation's value s evaluated.
- * If no such annotation is present, a default priority is returned (1);
- *
- * @param type the type, not null.
- * @return a priority, by default 1.
- */
- public static int getPriority(Class type) {
- int prio = 1;
- Priority priority = (Priority)type.getAnnotation(Priority.class);
- if (priority != null) {
- prio = priority.value();
- }
- return prio;
- }
-}
[2/7] incubator-tamaya git commit: - Minimalized API. - Propagated
change to rest of modules.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/ByteConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/ByteConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/ByteConverter.java
new file mode 100644
index 0000000..0f2f7ca
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/ByteConverter.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.types.internal.converters;
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Byte, the supported format is one of the following:
+ * <ul>
+ * <li>123 (byte value)</li>
+ * <li>0xFF (byte value)</li>
+ * <li>0XDF (byte value)</li>
+ * <li>0D1 (byte value)</li>
+ * <li>-123 (byte value)</li>
+ * <li>-0xFF (byte value)</li>
+ * <li>-0XDF (byte value)</li>
+ * <li>-0D1 (byte value)</li>
+ * <li>MIN_VALUE (ignoring case)</li>
+ * <li>MIN (ignoring case)</li>
+ * <li>MAX_VALUE (ignoring case)</li>
+ * <li>MAX (ignoring case)</li>
+ * </ul>
+ */
+public class ByteConverter implements PropertyConverter<Byte> {
+
+ private final Logger LOG = Logger.getLogger(getClass().getName());
+
+ @Override
+ public Byte convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(),"<byte>", "MIN_VALUE", "MIN", "MAX_VALUE", "MAX");
+ String trimmed = Objects.requireNonNull(value).trim();
+ switch(trimmed.toUpperCase(Locale.ENGLISH)){
+ case "MIN_VALUE":
+ case "MIN":
+ return Byte.MIN_VALUE;
+ case "MAX_VALUE":
+ case "MAX":
+ return Byte.MAX_VALUE;
+ default:
+ try{
+ return Byte.decode(trimmed);
+ }
+ catch(Exception e){
+ LOG.log(Level.FINEST, "Unparseable Byte: " + value);
+ return null;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/CharConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/CharConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/CharConverter.java
new file mode 100644
index 0000000..fda210d
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/CharConverter.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.types.internal.converters;
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Character, the supported format is one of the following:
+ * <ul>
+ * <li>'a'</li>
+ * <li>123 (byte value)</li>
+ * <li>0xFF (byte value)</li>
+ * <li>0XDF (byte value)</li>
+ * <li>0D1 (byte value)</li>
+ * </ul>
+ */
+public class CharConverter implements PropertyConverter<Character> {
+
+ private static final Logger LOG = Logger.getLogger(CharConverter.class.getName());
+
+ @Override
+ public Character convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(),"\\'<char>\\'", "<char>", "<charNum>");
+ String trimmed = Objects.requireNonNull(value).trim();
+ if(trimmed.isEmpty()){
+ return null;
+ }
+ if(trimmed.startsWith("'")) {
+ try {
+ trimmed = trimmed.substring(1, trimmed.length() - 1);
+ if (trimmed.isEmpty()) {
+ return null;
+ }
+ return trimmed.charAt(0);
+ } catch (Exception e) {
+ LOG.finest("Invalid character format encountered: '" + value + "', valid formats are 'a', 101 and a.");
+ return null;
+ }
+ }
+ try {
+ Integer val = Integer.parseInt(trimmed);
+ return (char) val.shortValue();
+ } catch (Exception e) {
+ LOG.finest("Character format is not numeric: '" + value + "', using first character.");
+ return trimmed.charAt(0);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/ClassConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/ClassConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/ClassConverter.java
new file mode 100644
index 0000000..44650d7
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/ClassConverter.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.types.internal.converters;
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Class, hereby using the following classloaders:
+ * <ul>
+ * <li>The current ThreadContext ClassLoader</li>
+ * <li>The Classloader of this class</li>
+ * <li>The system Classloader</li>
+ * </ul>
+ */
+public class ClassConverter implements PropertyConverter<Class<?>> {
+
+ private final Logger LOG = Logger.getLogger(getClass().getName());
+
+ @Override
+ public Class<?> convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(),"<fullyQualifiedClassName>");
+ String trimmed = Objects.requireNonNull(value).trim();
+ try{
+ return Class.forName(trimmed, false, Thread.currentThread().getContextClassLoader());
+ }
+ catch(Exception e){
+ LOG.finest("Class not found in context CL: " + trimmed);
+ }
+ try{
+ return Class.forName(trimmed, false, ClassConverter.class.getClassLoader());
+ }
+ catch(Exception e){
+ LOG.finest("Class not found in ClassConverter's CL: " + trimmed);
+ }
+ try{
+ return Class.forName(trimmed, false, ClassLoader.getSystemClassLoader());
+ }
+ catch(Exception e){
+ LOG.finest("Class not found in System CL (giving up): " + trimmed);
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/CurrencyConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/CurrencyConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/CurrencyConverter.java
new file mode 100644
index 0000000..141878d
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/CurrencyConverter.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.types.internal.converters;
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.util.Currency;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Currency, the supported format is one of the following:
+ * <ul>
+ * <li>CHF (currency code)</li>
+ * <li>123 (numeric currency value >
+ * = 0)</li>
+ * <li>DE (ISO 2-digit country)</li>
+ * <li>de_DE, de_DE_123 (Locale)</li>
+ * </ul>
+ */
+public class CurrencyConverter implements PropertyConverter<Currency> {
+
+ private static final Logger LOG = Logger.getLogger(CurrencyConverter.class.getName());
+
+ @Override
+ public Currency convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(), "<currencyCode>, using Locale.ENGLISH", "<numericValue>", "<locale>");
+ String trimmed = Objects.requireNonNull(value).trim();
+ try {
+ return Currency.getInstance(trimmed.toUpperCase(Locale.ENGLISH));
+ } catch (Exception e) {
+ LOG.log(Level.FINEST, "Not a valid textual currency code: " + trimmed + ", checking for numeric...", e);
+ }
+ try {
+ // Check for numeric code
+ Integer numCode = Integer.parseInt(trimmed);
+ for (Currency currency : Currency.getAvailableCurrencies()) {
+ if (currency.getNumericCode() == numCode) {
+ return currency;
+ }
+ }
+ } catch (Exception e) {
+ LOG.log(Level.FINEST, "Not a valid numeric currency code: " + trimmed + ", checking for locale...", e);
+ }
+ try {
+ // Check for numeric code
+ String[] parts = trimmed.split("\\_");
+ Locale locale;
+ switch (parts.length) {
+ case 1:
+ locale = new Locale("", parts[0]);
+ break;
+ case 2:
+ locale = new Locale(parts[0], parts[1]);
+ break;
+ case 3:
+ locale = new Locale(parts[0], parts[1], parts[2]);
+ break;
+ default:
+ locale = null;
+ }
+ if (locale != null) {
+ return Currency.getInstance(locale);
+ }
+ LOG.finest("Not a valid currency: " + trimmed + ", giving up...");
+ } catch (Exception e) {
+ LOG.log(Level.FINEST, "Not a valid country locale for currency: " + trimmed + ", giving up...", e);
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/DoubleConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/DoubleConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/DoubleConverter.java
new file mode 100644
index 0000000..84ccda4
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/DoubleConverter.java
@@ -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 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.types.internal.converters;
+
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Double, using the Java number syntax:
+ * (-)?[0-9]*\.[0-9]*. In case of error the value given also is tried being parsed as integral number using
+ * {@link LongConverter}. Additionally the following values are supported:
+ * <ul>
+ * <li>NaN (ignoring case)</li>
+ * <li>POSITIVE_INFINITY (ignoring case)</li>
+ * <li>NEGATIVE_INFINITY (ignoring case)</li>
+ * </ul>
+ */
+public class DoubleConverter implements PropertyConverter<Double> {
+ /**
+ * The logger.
+ */
+ private static final Logger LOG = Logger.getLogger(DoubleConverter.class.getName());
+ /**
+ * The converter used, when floating point parse failed.
+ */
+ private final LongConverter integerConverter = new LongConverter();
+
+ @Override
+ public Double convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(), "<double>", "MIN", "MIN_VALUE", "MAX", "MAX_VALUE", "POSITIVE_INFINITY", "NEGATIVE_INFINITY", "NAN");
+ String trimmed = Objects.requireNonNull(value).trim();
+ switch (trimmed.toUpperCase(Locale.ENGLISH)) {
+ case "POSITIVE_INFINITY":
+ return Double.POSITIVE_INFINITY;
+ case "NEGATIVE_INFINITY":
+ return Double.NEGATIVE_INFINITY;
+ case "NAN":
+ return Double.NaN;
+ case "MIN_VALUE":
+ case "MIN":
+ return Double.MIN_VALUE;
+ case "MAX_VALUE":
+ case "MAX":
+ return Double.MAX_VALUE;
+ default:
+ try {
+ return Double.valueOf(trimmed);
+ } catch (Exception e) {
+ // OK perhaps we have an integral number that must be converted to the double type...
+ LOG.finest("Parsing of double as floating number failed, trying parsing integral" +
+ " number/hex instead...");
+ }
+ Long val = integerConverter.convert(trimmed, context);
+ if(val!=null){
+ return val.doubleValue();
+ }
+ return null;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/EnumConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/EnumConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/EnumConverter.java
new file mode 100644
index 0000000..54cfd58
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/EnumConverter.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.types.internal.converters;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+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.
+ */
+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/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/FloatConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/FloatConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/FloatConverter.java
new file mode 100644
index 0000000..026c740
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/FloatConverter.java
@@ -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 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.types.internal.converters;
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Float, using the Java number syntax:
+ * (-)?[0-9]*\.[0-9]*. In case of error the value given also is tried being parsed as integral number using
+ * {@link LongConverter}. Additionally the following values are supported:
+ * <ul>
+ * <li>NaN (ignoring case)</li>
+ * <li>POSITIVE_INFINITY (ignoring case)</li>
+ * <li>NEGATIVE_INFINITY (ignoring case)</li>
+ * </ul>
+ */
+public class FloatConverter implements PropertyConverter<Float> {
+ /**
+ * The logger.
+ */
+ private static final Logger LOG = Logger.getLogger(FloatConverter.class.getName());
+ /**
+ * The converter used, when floating point parse failed.
+ */
+ private final IntegerConverter integerConverter = new IntegerConverter();
+
+ @Override
+ public Float convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(), "<float>", "MIN", "MIN_VALUE", "MAX", "MAX_VALUE", "POSITIVE_INFINITY", "NEGATIVE_INFINITY", "NAN");
+ String trimmed = Objects.requireNonNull(value).trim();
+ switch(trimmed.toUpperCase(Locale.ENGLISH)){
+ case "POSITIVE_INFINITY":
+ return Float.POSITIVE_INFINITY;
+ case "NEGATIVE_INFINITY":
+ return Float.NEGATIVE_INFINITY;
+ case "NAN":
+ return Float.NaN;
+ case "MIN_VALUE":
+ case "MIN":
+ return Float.MIN_VALUE;
+ case "MAX_VALUE":
+ case "MAX":
+ return Float.MAX_VALUE;
+ default:
+ try {
+ return Float.valueOf(trimmed);
+ } catch(Exception e){
+ // OK perhaps we have an integral number that must be converted to the double type...
+ LOG.finest("Parsing of float as floating number failed, trying parsing integral" +
+ " number/hex instead...");
+ }
+ Integer val = integerConverter.convert(trimmed, context);
+ if(val!=null) {
+ return val.floatValue();
+ }
+ LOG.finest("Unparseable float value: " + trimmed);
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/IntegerConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/IntegerConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/IntegerConverter.java
new file mode 100644
index 0000000..4a69224
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/IntegerConverter.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.types.internal.converters;
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Integer, the supported format is one of the following:
+ * <ul>
+ * <li>123 (byte value)</li>
+ * <li>0xFF (byte value)</li>
+ * <li>0XDF (byte value)</li>
+ * <li>0D1 (byte value)</li>
+ * <li>-123 (byte value)</li>
+ * <li>-0xFF (byte value)</li>
+ * <li>-0XDF (byte value)</li>
+ * <li>-0D1 (byte value)</li>
+ * <li>MIN_VALUE (ignoring case)</li>
+ * <li>MIN (ignoring case)</li>
+ * <li>MAX_VALUE (ignoring case)</li>
+ * <li>MAX (ignoring case)</li>
+ * </ul>
+ */
+public class IntegerConverter implements PropertyConverter<Integer>{
+
+ /**
+ * The logger.
+ */
+ private static final Logger LOG = Logger.getLogger(IntegerConverter.class.getName());
+
+ @Override
+ public Integer convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(), "<int>", "MIN_VALUE", "MIN", "MAX_VALUE", "MAX");
+ String trimmed = Objects.requireNonNull(value).trim();
+ switch(trimmed.toUpperCase(Locale.ENGLISH)){
+ case "MIN_VALUE":
+ case "MIN":
+ return Integer.MIN_VALUE;
+ case "MAX_VALUE":
+ case "MAX":
+ return Integer.MAX_VALUE;
+ default:
+ try{
+ return Integer.decode(trimmed);
+ }
+ catch(Exception e){
+ LOG.finest("Unparseable Integer value: " + trimmed);
+ return null;
+ }
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/LongConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/LongConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/LongConverter.java
new file mode 100644
index 0000000..8af5fbe
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/LongConverter.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.types.internal.converters;
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Long, the supported format is one of the following:
+ * <ul>
+ * <li>123 (byte value)</li>
+ * <li>0xFF (byte value)</li>
+ * <li>0XDF (byte value)</li>
+ * <li>0D1 (byte value)</li>
+ * <li>-123 (byte value)</li>
+ * <li>-0xFF (byte value)</li>
+ * <li>-0XDF (byte value)</li>
+ * <li>-0D1 (byte value)</li>
+ * <li>MIN_VALUE (ignoring case)</li>
+ * <li>MIN (ignoring case)</li>
+ * <li>MAX_VALUE (ignoring case)</li>
+ * <li>MAX (ignoring case)</li>
+ * </ul>
+ */
+public class LongConverter implements PropertyConverter<Long>{
+
+ private static final Logger LOGGER = Logger.getLogger(LongConverter.class.getName());
+
+ @Override
+ public Long convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(), "<long>", "MIN", "MIN_VALUE", "MAX", "MAX_VALUE");
+
+ String trimmed = Objects.requireNonNull(value).trim();
+ switch (trimmed.toUpperCase(Locale.ENGLISH)) {
+ case "MIN_VALUE":
+ case "MIN":
+ return Long.MIN_VALUE;
+ case "MAX_VALUE":
+ case "MAX":
+ return Long.MAX_VALUE;
+ default:
+ try {
+ return Long.decode(trimmed);
+ }
+ catch(Exception e){
+ LOGGER.finest("Unable to parse Long value: " + value);
+ return null;
+ }
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/NumberConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/NumberConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/NumberConverter.java
new file mode 100644
index 0000000..b4af638
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/NumberConverter.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.types.internal.converters;
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.math.BigDecimal;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Number. Valid inputs are:
+ * <pre>
+ * POSITIVE_INFINITY -> Double.POSITIVE_INFINITY
+ * NEGATIVE_INFINITY -> Double.NEGATIVE_INFINITY
+ * NaN > Double.NaN
+ * 0xFFDCD3D2 -> Long
+ * 1234566789.23642327352735273752 -> new BigDecimal(input)
+ * </pre>
+ */
+public class NumberConverter implements PropertyConverter<Number>{
+ /** the logger. */
+ private static final Logger LOGGER = Logger.getLogger(NumberConverter.class.getName());
+ /** Converter used for trying to parse as an integral value. */
+ private final LongConverter longConverter = new LongConverter();
+
+ @Override
+ public Number convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(), "<double>, <long>", "0x (hex)", "0X... (hex)", "POSITIVE_INFINITY",
+ "NEGATIVE_INFINITY", "NAN");
+
+ String trimmed = Objects.requireNonNull(value).trim();
+ switch(trimmed.toUpperCase(Locale.ENGLISH)) {
+ case "POSITIVE_INFINITY":
+ return Double.POSITIVE_INFINITY;
+ case "NEGATIVE_INFINITY":
+ return Double.NEGATIVE_INFINITY;
+ case "NAN":
+ return Double.NaN;
+ default:
+ Long lVal = longConverter.convert(trimmed, context);
+ if (lVal != null) {
+ return lVal;
+ }
+ try{
+ return new BigDecimal(trimmed);
+ }
+ catch(Exception e){
+ LOGGER.finest("Unparseable Number: " + trimmed);
+ return null;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/ShortConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/ShortConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/ShortConverter.java
new file mode 100644
index 0000000..9c1db35
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/ShortConverter.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.types.internal.converters;
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Short, the supported format is one of the following:
+ * <ul>
+ * <li>123 (byte value)</li>
+ * <li>0xFF (byte value)</li>
+ * <li>0XDF (byte value)</li>
+ * <li>0D1 (byte value)</li>
+ * <li>-123 (byte value)</li>
+ * <li>-0xFF (byte value)</li>
+ * <li>-0XDF (byte value)</li>
+ * <li>-0D1 (byte value)</li>
+ * <li>MIN_VALUE (ignoring case)</li>
+ * <li>MIN (ignoring case)</li>
+ * <li>MAX_VALUE (ignoring case)</li>
+ * <li>MAX (ignoring case)</li>
+ * </ul>
+ */
+public class ShortConverter implements PropertyConverter<Short>{
+
+ /** the logger. */
+ private static final Logger LOG = Logger.getLogger(ShortConverter.class.getName());
+
+ @Override
+ public Short convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(), "short", "MIN", "MIN_VALUE", "MAX", "MAX_VALUE");
+ String trimmed = Objects.requireNonNull(value).trim();
+ switch(trimmed.toUpperCase(Locale.ENGLISH)){
+ case "MIN_VALUE":
+ case "MIN":
+ return Short.MIN_VALUE;
+ case "MAX_VALUE":
+ case "MAX":
+ return Short.MAX_VALUE;
+ default:
+ try{
+ return Short.decode(trimmed);
+ }
+ catch(Exception e){
+ LOG.finest("Unparseable Short: " + trimmed);
+ return null;
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/URIConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/URIConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/URIConverter.java
new file mode 100644
index 0000000..6a86d71
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/URIConverter.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.types.internal.converters;
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.net.URI;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to URI, using new URI(value).
+ */
+public class URIConverter implements PropertyConverter<URI> {
+
+ private final Logger LOG = Logger.getLogger(getClass().getName());
+
+ @Override
+ public URI convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(), "<uri> -> new URI(uri)");
+ String trimmed = Objects.requireNonNull(value).trim();
+ try {
+ return new URI(trimmed);
+ } catch (Exception e) {
+ LOG.log(Level.FINE, "Unparseable URI: " + trimmed, e);
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/URLConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/URLConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/URLConverter.java
new file mode 100644
index 0000000..0cff508
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/URLConverter.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.types.internal.converters;
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.net.URL;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to URI, using new URL(value).
+ */
+public class URLConverter implements PropertyConverter<URL> {
+
+ private final Logger LOG = Logger.getLogger(getClass().getName());
+
+ @Override
+ public URL convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(),"<URL>");
+ String trimmed = Objects.requireNonNull(value).trim();
+ try {
+ return new URL(trimmed);
+ } catch (Exception e) {
+ LOG.log(Level.FINE, "Unparseable URL: " + trimmed, e);
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/package-info.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/package-info.java b/modules/types/src/main/java/org/apache/tamaya/types/package-info.java
new file mode 100644
index 0000000..24c86a9
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/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
+ * {@link org.apache.tamaya.builder.ConfigurationBuilder a configuration
+ * builder} that allows to build a configuration manually without
+ * using exclusively on the Service Provider Interface API of Tamaya.
+ *
+ * @see org.apache.tamaya.builder.ConfigurationBuilder
+ * @see org.apache.tamaya.Configuration
+ */
+package org.apache.tamaya.builder;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/spi/ConversionContext.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/spi/ConversionContext.java b/modules/types/src/main/java/org/apache/tamaya/types/spi/ConversionContext.java
new file mode 100644
index 0000000..33e68de
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/spi/ConversionContext.java
@@ -0,0 +1,234 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.types.spi;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.types.TypeLiteral;
+
+import java.lang.reflect.AnnotatedElement;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A conversion context containing all the required values for implementing conversion. Use the included #Builder
+ * for creating new instances of. This class is thread-safe to use. Adding supported formats is synchronized.
+ * @see PropertyConverter
+ */
+public class ConversionContext {
+
+ private final Configuration configuration;
+ private final String key;
+ private final TypeLiteral<?> targetType;
+ private final AnnotatedElement annotatedElement;
+ private final List<String> supportedFormats = new ArrayList<>();
+
+ /**
+ * Private constructor used from builder.
+ * @param builder the builder, not null.
+ */
+ protected ConversionContext(Builder builder){
+ this.key = builder.key;
+ this.annotatedElement = builder.annotatedElement;
+ this.targetType = builder.targetType;
+ this.supportedFormats.addAll(builder.supportedFormats);
+ this.configuration = builder.configuration;
+ }
+
+ /**
+ * Get the key accessed. This information is very useful to evaluate additional metadata needed to determine/
+ * control further aspects of the conversion.
+ * @return the key. This may be null in case where a default value has to be converted and no unique underlying
+ * key/value configuration is present.
+ */
+ public String getKey(){
+ return key;
+ }
+
+ /**
+ * Get the target type required.
+ * @return the target type required.
+ */
+ public TypeLiteral<?> getTargetType(){
+ return targetType;
+ }
+
+ /**
+ * Get the annotated element, if conversion is performed using injection mechanisms.
+ * @return the annotated element, or null.
+ */
+ public AnnotatedElement getAnnotatedElement(){
+ return annotatedElement;
+ }
+
+ /**
+ * Get the configuration, which is targeted.
+ * @return the configuration instance, or null.
+ */
+ public Configuration getConfiguration(){
+ return configuration;
+ }
+
+ /**
+ * Allows to add information on the supported/tried formats, which can be shown to the user, especially when
+ * conversion failed. Adding of formats is synchronized, all formats are added in order to the overall list.
+ * This means formats should be passed in order of precedence.
+ * @param converterType the converter, which implements the formats provided.
+ * @param formatDescriptors the format descriptions in a human readable form, e.g. as regular expressions.
+ */
+ public void addSupportedFormats(Class<? extends PropertyConverter> converterType, String... formatDescriptors){
+ synchronized (supportedFormats){
+ for(String format: formatDescriptors) {
+ supportedFormats.add(format + " (" + converterType.getSimpleName() + ")");
+ }
+ }
+ }
+
+ /**
+ * Get the supported/tried formats in precedence order. The contents of this method depends on the
+ * {@link PropertyConverter} instances involved in a conversion.
+ * @return the supported/tried formats, never null.
+ */
+ public List<String> getSupportedFormats(){
+ synchronized (supportedFormats){
+ return new ArrayList<>(supportedFormats);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "ConversionContext{" +
+ "configuration=" + configuration +
+ ", key='" + key + '\'' +
+ ", targetType=" + targetType +
+ ", annotatedElement=" + annotatedElement +
+ ", supportedFormats=" + supportedFormats +
+ '}';
+ }
+
+ /**
+ * Builder to create new instances of {@link ConversionContext}.
+ */
+ public static final class Builder{
+ /** The backing configuration. */
+ private Configuration configuration;
+ /** The accessed key, or null. */
+ private String key;
+ /** The target type. */
+ private final TypeLiteral<?> targetType;
+ /** The injection target (only set with injection used). */
+ private AnnotatedElement annotatedElement;
+ /** The ordered list of formats tried. */
+ private final Set<String> supportedFormats = new HashSet<>();
+
+ /**
+ * Creates a new Builder instance.
+ * @param targetType the target type
+ */
+ public Builder(TypeLiteral<?> targetType) {
+ this(null, null, targetType);
+ }
+
+ /**
+ * Creates a new Builder instance.
+ * @param key the requested key, may be null.
+ * @param targetType the target type
+ */
+ public Builder(String key, TypeLiteral<?> targetType) {
+ this(null, key, targetType);
+ }
+
+ /**
+ * Creates a new Builder instance.
+ * @param configuration the configuration, not null.
+ * @param key the requested key, may be null.
+ * @param targetType the target type
+ */
+ public Builder(Configuration configuration, String key, TypeLiteral<?> targetType){
+ this.key = key;
+ this.configuration = configuration;
+ this.targetType = Objects.requireNonNull(targetType);
+ }
+
+ /**
+ * Sets the key.
+ * @param key the key, not null.
+ * @return the builder instance, for chaining
+ */
+ public Builder setKey(String key){
+ this.key = Objects.requireNonNull(key);
+ return this;
+ }
+
+ /**
+ * Sets the configuration.
+ * @param configuration the configuration, not null
+ * @return the builder instance, for chaining
+ */
+ public Builder setConfiguration(Configuration configuration){
+ this.configuration = Objects.requireNonNull(configuration);
+ return this;
+ }
+
+ /**
+ * Sets the annotated element, when configuration is injected.
+ * @param annotatedElement the annotated element, not null
+ * @return the builder instance, for chaining
+ */
+ public Builder setAnnotatedElement(AnnotatedElement annotatedElement){
+ this.annotatedElement = Objects.requireNonNull(annotatedElement);
+ return this;
+ }
+
+ /**
+ * Add the formats provided by a {@link PropertyConverter}. This method should be called by each converter
+ * performing/trying conversion, so the user can be given feedback on the supported formats on failure.
+ * @param converterType the converter type, not null.
+ * @param formatDescriptors the formats supported in a human readable form, e.g. as regular expressions.
+ * @return the builder instance, for chaining
+ */
+ public Builder addSupportedFormats(Class<? extends PropertyConverter> converterType, String... formatDescriptors){
+ for(String format: formatDescriptors) {
+ supportedFormats.add(format + " (" + converterType.getSimpleName() + ")");
+ }
+ return this;
+ }
+
+ /**
+ * Builds a new context instance.
+ * @return a new context, never null.
+ */
+ public ConversionContext build(){
+ return new ConversionContext(this);
+ }
+
+ @Override
+ public String toString() {
+ return "Builder{" +
+ "configuration=" + configuration +
+ ", key='" + key + '\'' +
+ ", targetType=" + targetType +
+ ", annotatedElement=" + annotatedElement +
+ ", supportedFormats=" + supportedFormats +
+ '}';
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/spi/PropertyConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/spi/PropertyConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/spi/PropertyConverter.java
new file mode 100644
index 0000000..8787cc0
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/spi/PropertyConverter.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.types.spi;
+
+
+/**
+ * Interface for an property that converts a configured String into something else.
+ * This is used for implementing type conversion from a property (String) to a certain target
+ * type. Hereby the target type can be multivalued (e.g. collections) or complex if needed.
+ *
+ * @param <T> the type of the type literal
+ */
+public interface PropertyConverter<T>{
+
+ /**
+ * Convert the given configuration keys from its String representation into the required target type.
+ * The context instance passed also allows to add a list of supported formats, which is very handy in case a
+ * value could not be converted. This list of supported formats can then shown to the user to give some hints
+ * how a value could be configured.
+ *
+ * @param value configuration key that needs to be converted
+ * @param context the {@link ConversionContext}, containing the String value and the requested configuration key.
+ * @return converted keys
+ * @see ConversionContext#addSupportedFormats(Class, String...)
+ */
+ T convert(String value, ConversionContext context);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/resources/META-INF/services/org.apache.tamaya.adapter.spi.ConfigurationAdapter
----------------------------------------------------------------------
diff --git a/modules/types/src/main/resources/META-INF/services/org.apache.tamaya.adapter.spi.ConfigurationAdapter b/modules/types/src/main/resources/META-INF/services/org.apache.tamaya.adapter.spi.ConfigurationAdapter
new file mode 100644
index 0000000..c05c7b7
--- /dev/null
+++ b/modules/types/src/main/resources/META-INF/services/org.apache.tamaya.adapter.spi.ConfigurationAdapter
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the 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.
+org.apache.tamaya.types.internal.adapters.TypedConfigurationAdapter
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/internal/PropertyConverterManagerTest.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/internal/PropertyConverterManagerTest.java b/modules/types/src/test/java/org/apache/tamaya/types/internal/PropertyConverterManagerTest.java
new file mode 100644
index 0000000..f53941e
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/internal/PropertyConverterManagerTest.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal;
+
+
+import org.apache.tamaya.builder.spi.ConversionContext;
+import org.apache.tamaya.builder.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/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/BigDecimalConverterTest.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/BigDecimalConverterTest.java b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/BigDecimalConverterTest.java
new file mode 100644
index 0000000..9c71688
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/BigDecimalConverterTest.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.core.internal.converters;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.junit.Test;
+
+import java.math.BigDecimal;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests the default converter for bytes.
+ */
+public class BigDecimalConverterTest {
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_BigDecimal_Decimal() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ BigDecimal valueRead = config.get("tests.converter.bd.decimal", BigDecimal.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead, new BigDecimal(101));
+ }
+
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_BigDecimal_Hex() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ BigDecimal valueRead = config.get("tests.converter.bd.hex.lowerX", BigDecimal.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead, new BigDecimal("47"));
+ valueRead = config.get("tests.converter.bd.hex.upperX", BigDecimal.class);
+ assertTrue(valueRead != null);
+ assertEquals(valueRead, new BigDecimal("63"));
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_NotPresent() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ BigDecimal valueRead = config.get("tests.converter.bd.foo", BigDecimal.class);
+ assertFalse(valueRead != null);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_BigDecimal_BigValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ BigDecimal valueRead = config.get("tests.converter.bd.big", BigDecimal.class);
+ assertTrue(valueRead != null);
+ assertEquals(new BigDecimal("101666666666666662333337263723628763821638923628193612983618293628763"),
+ valueRead);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_BigDecimal_BigFloatValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ BigDecimal valueRead = config.get("tests.converter.bd.bigFloat", BigDecimal.class);
+ assertTrue(valueRead != null);
+ assertEquals(new BigDecimal("1016666666666666623333372637236287638216389293628763.1016666666666666623333372" +
+ "63723628763821638923628193612983618293628763"), valueRead);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/BooleanConverterTest.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/BooleanConverterTest.java b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/BooleanConverterTest.java
new file mode 100644
index 0000000..ac75c34
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/BooleanConverterTest.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.converters;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.junit.Test;
+
+/**
+ * Tests the default converter for bytes.
+ */
+public class BooleanConverterTest {
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Byte() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ // trues
+ Boolean valueRead = config.get("tests.converter.boolean.y1", Boolean.class);
+ assertNotNull(valueRead);
+ assertEquals(valueRead, Boolean.TRUE);
+ valueRead = config.get("tests.converter.boolean.y2", Boolean.class);
+ assertNotNull(valueRead);
+ assertEquals(valueRead, Boolean.TRUE);
+ valueRead = config.get("tests.converter.boolean.yes1", Boolean.class);
+ assertNotNull(valueRead);
+ assertEquals(valueRead, Boolean.TRUE);
+ valueRead = config.get("tests.converter.boolean.yes2", Boolean.class);
+ assertNotNull(valueRead);
+ assertEquals(valueRead, Boolean.TRUE);
+ valueRead = config.get("tests.converter.boolean.yes3", Boolean.class);
+ assertNotNull(valueRead);
+ assertEquals(valueRead, Boolean.TRUE);
+ valueRead = config.get("tests.converter.boolean.true1", Boolean.class);
+ assertNotNull(valueRead);
+ assertEquals(valueRead, Boolean.TRUE);
+ valueRead = config.get("tests.converter.boolean.true2", Boolean.class);
+ assertNotNull(valueRead);
+ assertEquals(valueRead, Boolean.TRUE);
+ valueRead = config.get("tests.converter.boolean.true3", Boolean.class);
+ assertNotNull(valueRead);
+ assertEquals(valueRead, Boolean.TRUE);
+ valueRead = config.get("tests.converter.boolean.t1", Boolean.class);
+ assertNotNull(valueRead);
+ assertEquals(valueRead, Boolean.TRUE);
+ valueRead = config.get("tests.converter.boolean.t2", Boolean.class);
+ assertNotNull(valueRead);
+ assertEquals(valueRead, Boolean.TRUE);
+ // falses
+ valueRead = config.get("tests.converter.boolean.n1", Boolean.class);
+ assertNotNull(valueRead);
+ assertFalse(valueRead);
+ valueRead = config.get("tests.converter.boolean.n2", Boolean.class);
+ assertNotNull(valueRead);
+ assertFalse(valueRead);
+ valueRead = config.get("tests.converter.boolean.no1", Boolean.class);
+ assertFalse(valueRead);
+ assertFalse(valueRead);
+ valueRead = config.get("tests.converter.boolean.no2", Boolean.class);
+ assertNotNull(valueRead);
+ assertFalse(valueRead);
+ valueRead = config.get("tests.converter.boolean.no3", Boolean.class);
+ assertNotNull(valueRead);
+ assertFalse(valueRead);
+ valueRead = config.get("tests.converter.boolean.false1", Boolean.class);
+ assertNotNull(valueRead);
+ assertFalse(valueRead);
+ valueRead = config.get("tests.converter.boolean.false2", Boolean.class);
+ assertNotNull(valueRead);
+ assertFalse(valueRead);
+ valueRead = config.get("tests.converter.boolean.false3", Boolean.class);
+ assertNotNull(valueRead);
+ assertFalse(valueRead);
+ valueRead = config.get("tests.converter.boolean.f1", Boolean.class);
+ assertNotNull(valueRead);
+ assertFalse(valueRead);
+ valueRead = config.get("tests.converter.boolean.f2", Boolean.class);
+ assertNotNull(valueRead);
+ assertFalse(valueRead);
+ valueRead = config.get("tests.converter.boolean.foo", Boolean.class);
+ assertNull(valueRead);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/ByteConverterTest.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/ByteConverterTest.java b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/ByteConverterTest.java
new file mode 100644
index 0000000..132674d
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/ByteConverterTest.java
@@ -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 of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.converters;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests the default converter for bytes.
+ */
+public class ByteConverterTest {
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Byte() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Byte valueRead = config.get("tests.converter.byte.decimal", Byte.class);
+ assertNotNull(valueRead);
+ assertEquals(valueRead.byteValue(), 101);
+ valueRead = config.get("tests.converter.byte.octal", Byte.class);
+ assertNotNull(valueRead);
+ assertEquals(valueRead.byteValue(), Byte.decode("02").byteValue());
+ valueRead = config.get("tests.converter.byte.hex.lowerX", Byte.class);
+ assertNotNull(valueRead);
+ assertEquals(valueRead.byteValue(), Byte.decode("0x2F").byteValue());
+ valueRead = config.get("tests.converter.byte.hex.upperX", Byte.class);
+ assertNotNull(valueRead);
+ assertEquals(valueRead.byteValue(), Byte.decode("0X3F").byteValue());
+ valueRead = config.get("tests.converter.byte.foo", Byte.class);
+ assertNull(valueRead);
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Byte_MinValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Byte valueRead = config.get("tests.converter.byte.min", Byte.class);
+ assertTrue(valueRead!=null);
+ assertEquals(Byte.MIN_VALUE, valueRead.byteValue());
+ }
+
+ /**
+ * Test conversion. The value are provided by
+ * {@link ConverterTestsPropertySource}.
+ * @throws Exception
+ */
+ @Test
+ public void testConvert_Byte_MaxValue() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Byte valueRead = config.get("tests.converter.byte.max", Byte.class);
+ assertTrue(valueRead!=null);
+ assertEquals(Byte.MAX_VALUE, valueRead.byteValue());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/CharConverterTest.java
----------------------------------------------------------------------
diff --git a/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/CharConverterTest.java b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/CharConverterTest.java
new file mode 100644
index 0000000..f27a465
--- /dev/null
+++ b/modules/types/src/test/java/org/apache/tamaya/types/internal/converters/CharConverterTest.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.converters;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests conversion of the {@link CharConverter}.
+ */
+public class CharConverterTest {
+
+ @Test
+ public void testConvert_Character() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Character valueRead = config.get("tests.converter.char.f", Character.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.charValue(), 'f');
+ }
+
+ @Test
+ public void testConvert_Character_Numeric() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Character valueRead = config.get("tests.converter.char.f-numeric", Character.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.charValue(), (char)101);
+ }
+
+ @Test
+ public void testConvert_Character_Quoted() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Character valueRead = config.get("tests.converter.char.d", Character.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.charValue(), 'd');
+ }
+
+ @Test
+ public void testConvert_Character_WithWhitspace_Before() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Character valueRead = config.get("tests.converter.char.f-before", Character.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.charValue(), 'f');
+ }
+
+ @Test
+ public void testConvert_Character_WithWhitspace_After() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Character valueRead = config.get("tests.converter.char.f-after", Character.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.charValue(), 'f');
+ }
+
+ @Test
+ public void testConvert_Character_WithWhitspace_Around() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Character valueRead = config.get("tests.converter.char.f-around", Character.class);
+ assertTrue(valueRead!=null);
+ assertEquals(valueRead.charValue(), 'f');
+ }
+
+ @Test
+ public void testConvert_NotPresent() throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ Character valueRead = config.get("tests.converter.char.foo", Character.class);
+ assertNull(valueRead);
+ }
+}
[5/7] incubator-tamaya git commit: - Minimalized API. - Propagated
change to rest of modules.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PropertyConverterManager.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PropertyConverterManager.java b/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PropertyConverterManager.java
deleted file mode 100644
index 1f975ae..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PropertyConverterManager.java
+++ /dev/null
@@ -1,448 +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.builder.internal;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.builder.internal.converters.EnumConverter;
-import org.apache.tamaya.builder.spi.ConversionContext;
-import org.apache.tamaya.builder.spi.PropertyConverter;
-import org.apache.tamaya.builder.spi.ServiceContextManager;
-
-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.*;
-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;
-
-/**
- * Manager that deals with {@link PropertyConverter} instances.
- * This class is thread-safe.
- */
-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 = DefaultServiceContext.getPriority(o1) - DefaultServiceContext.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() {
- this(true);
- }
-
- public PropertyConverterManager(boolean init) {
- if (init) {
- 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) {
- return converters.containsKey(targetType) || transitiveConverters.containsKey(targetType) || 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(org.apache.tamaya.TypeLiteral)
- */
- public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
- Lock readLock = lock.readLock();
- try {
- readLock.lock();
- return new HashMap<>(this.converters);
- } finally {
- readLock.unlock();
- }
- }
-
- /**
- * 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.
- * 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>
- * </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).
- * @see #createDefaultPropertyConverter(org.apache.tamaya.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();
- addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList);
- } finally {
- readLock.unlock();
- }
- // transitive converter
- try {
- readLock.lock();
- addConvertersToList(List.class.cast(this.transitiveConverters.get(targetType)), converterList);
- } finally {
- readLock.unlock();
- }
- // handling of java.lang wrapper classes
- TypeLiteral<T> boxedType = mapBoxedType(targetType);
- if (boxedType != null) {
- try {
- readLock.lock();
- addConvertersToList(List.class.cast(this.converters.get(boxedType)), converterList);
- } finally {
- readLock.unlock();
- }
- }
- 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();
- addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList);
- } finally {
- readLock.unlock();
- }
- }
- }
- // 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.
- *
- * @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 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) {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- @Override
- public Object run() {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- @Override
- public Object run() {
- constr.setAccessible(true);
- return null;
- }
- });
- return null;
- }
- });
- try {
- return constr.newInstance(value);
- } catch (Exception e) {
- LOG.log(Level.SEVERE, "Error creating new PropertyConverter instance " + targetType, e);
- }
- return null;
- }
- };
- }
- 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;
- }
-
- 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/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PropertyFiltering.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PropertyFiltering.java b/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PropertyFiltering.java
index 75d7ad7..a97cf77 100644
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PropertyFiltering.java
+++ b/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PropertyFiltering.java
@@ -18,7 +18,7 @@
*/
package org.apache.tamaya.builder.internal;
-import org.apache.tamaya.builder.spi.ConfigurationContext;
+import org.apache.tamaya.builder.PropertySourceBasedConfiguration;
import org.apache.tamaya.builder.spi.FilterContext;
import org.apache.tamaya.builder.spi.PropertyFilter;
import org.apache.tamaya.builder.spi.PropertySource;
@@ -31,7 +31,7 @@ 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
+ * Implementation of the Configuration API. This class uses the current {@link PropertySourceBasedConfiguration} to evaluate the
* chain of {@link PropertySource} and {@link PropertyFilter}
* instance to evaluate the current Configuration.
*/
@@ -51,7 +51,7 @@ public final class PropertyFiltering{
*/
private PropertyFiltering(){}
- public static String applyFilter(String key, Map<String,String> configData, ConfigurationContext configurationContext) {
+ public static String applyFilter(String key, Map<String,String> configData, PropertySourceBasedConfiguration configurationContext) {
// Apply filters to values, prevent values filtered to null!
String result = configData.get(key);
for (int i = 0; i < MAX_FILTER_LOOPS; i++) {
@@ -89,7 +89,7 @@ public final class PropertyFiltering{
return result;
}
- public static Map<String, String> applyFilters(Map<String, String> inputMap, ConfigurationContext configurationContext) {
+ public static Map<String, String> applyFilters(Map<String, String> inputMap, PropertySourceBasedConfiguration configurationContext) {
Map<String, String> resultMap = new HashMap<>(inputMap);
// Apply filters to values, prevent values filtered to null!
Map<String, String> metaData = filterMetadata(inputMap);
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PropertySourceBasedConfigurationAdapter.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PropertySourceBasedConfigurationAdapter.java b/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PropertySourceBasedConfigurationAdapter.java
new file mode 100644
index 0000000..d4eecf5
--- /dev/null
+++ b/modules/builder/src/main/java/org/apache/tamaya/builder/internal/PropertySourceBasedConfigurationAdapter.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.builder.internal;
+
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.adapter.spi.ConfigurationAdapter;
+import org.apache.tamaya.builder.PropertySourceBasedConfiguration;
+
+/**
+ * Created by atsticks on 19.07.16.
+ */
+public class PropertySourceBasedConfigurationAdapter implements ConfigurationAdapter {
+
+ @Override
+ public <T> T adapt(Configuration configuration, Class<T> targetType) {
+ if(PropertySourceBasedConfiguration.class.equals(targetType)){
+ if(configuration instanceof PropertySourceBasedConfiguration){
+ return (T)configuration;
+ }
+ return (T)new DelegatingPropertySourceBasedConfiguration(configuration);
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/package-info.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/package-info.java b/modules/builder/src/main/java/org/apache/tamaya/builder/package-info.java
index 24c86a9..f0509d1 100644
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/package-info.java
+++ b/modules/builder/src/main/java/org/apache/tamaya/builder/package-info.java
@@ -17,12 +17,11 @@
* under the License.
*/
/**
- * This package provides
- * {@link org.apache.tamaya.builder.ConfigurationBuilder a configuration
- * builder} that allows to build a configuration manually without
- * using exclusively on the Service Provider Interface API of Tamaya.
+ * This package provides an adapter and builder for managing configuration
+ * organized as a well ordered list of {@link org.apache.tamaya.builder.spi.PropertySource}
+ * instances.
*
- * @see org.apache.tamaya.builder.ConfigurationBuilder
+ * @see org.apache.tamaya.builder.PropertySourceBasedConfigurationBuilder
* @see org.apache.tamaya.Configuration
*/
package org.apache.tamaya.builder;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConfigurationContext.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConfigurationContext.java b/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConfigurationContext.java
deleted file mode 100644
index c206e98..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConfigurationContext.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.builder.spi;
-
-
-import org.apache.tamaya.TypeLiteral;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Central SPI for programmatically dealing with the setup of the configuration system.
- * This includes adding and enlisting {@link PropertySource}s,
- * managing {@link PropertyConverter}s, ConfigFilters, etc.
- */
-public interface ConfigurationContext {
-
- /**
- * This method can be used for programmatically adding {@link PropertySource}s.
- * It is not needed for normal 'usage' by end users, but only for Extension Developers!
- *
- * @param propertySourcesToAdd the PropertySources to add
- */
- void addPropertySources(PropertySource... propertySourcesToAdd);
-
- /**
- * This method returns the current list of registered PropertySources ordered via their ordinal.
- * PropertySources with a lower ordinal come last. The PropertySource with the
- * highest ordinal comes first.
- * If two PropertySources have the same ordinal number they will get sorted
- * using their class name just to ensure the user at least gets the same ordering
- * after a JVM restart, hereby names before are added last.
- * PropertySources are loaded when this method is called the first time, which basically is
- * when the first time configuration is accessed.
- *
- * @return a sorted list of registered PropertySources. The returned list need not be modifiable
- */
- List<PropertySource> getPropertySources();
-
-
- /**
- * This method can be used for programmatically adding {@link PropertyConverter}s.
- * It is not needed for normal 'usage' by end users, but only for Extension Developers!
- *
- * @param <T> the type of the type literal
- * @param typeToConvert the type which the converter is for
- * @param propertyConverter the PropertyConverters to add for this type
- */
- <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter);
-
- /**
- * <p>
- * This method returns the Map of registered PropertyConverters
- * per type.
- * The List for each type is ordered via their {@link javax.annotation.Priority} and
- * cladd name.
- * </p>
- *
- * <p>A simplified scenario could be like:</p>
- * <pre>
- * {
- * Date.class -> {StandardDateConverter, TimezoneDateConverter, MyCustomDateConverter }
- * Boolean.class -> {StandardBooleanConverter, FrenchBooleanConverter}
- * Integer.class -> {DynamicDefaultConverter}
- * }
- * </pre>
- *
- * @return map with sorted list of registered PropertySources per type.
- */
- Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters();
-
- /**
- * <p>
- * This method returns the registered PropertyConverters for a given type.
- * The List for each type is ordered via their {@link javax.annotation.Priority}.
- * </p>
- *
- * <p>
- * PropertyConverters with a higher Priority come first. The PropertyConverter with the
- * lowest Priority comes last.
- * If two PropertyConverter have the same ordinal number they will get sorted
- * using their class name just to ensure the user at least gets the same ordering
- * after a JVM restart.
- * </p>
- *
- * <p>
- * Additionally if a PropertyProvider is accessed, which is not registered the implementation
- * should try to figure out, if there could be a default implementation as follows:</p>
- * <ol>
- * <li>Look for static factory methods: {@code of(String), valueOf(String), getInstance(String),
- * instanceOf(String), fomr(String)}</li>
- * <li>Look for a matching constructor: {@code T(String)}.</li>
- * </ol>
- *
- * <p>
- * If a correspoding factory method or constructor could be found, a corresponding
- * PropertyConverter should be created and registered automatically for the given
- * type.
- * </p>
- *
- * <p> The scenario could be like:</p>
- *
- * <pre>
- * {
- * Date.class -> {MyCustomDateConverter,StandardDateConverter, TimezoneDateConverter}
- * Boolean.class -> {StandardBooleanConverter, FrenchBooleanConverter}
- * Integer.class -> {DynamicDefaultConverter}
- * }
- * </pre>
- *
- * <p>
- * The converters returned for a type should be used as a chain, whereas the result of the
- * first converter that is able to convert the configured value, is taken as the chain's result.
- * No more converters are called after a converter has successfully converted the input into
- * the required target type.
- * </p>
- *
- * @param <T> the type of the type literal
- * @param type type of the desired converter
- * @return a sorted list of registered PropertySources per type.
- */
- <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> type);
-
- /**
- * Access the current PropertyFilter instances.
- * @return the list of registered PropertyFilters, never null.
- */
- List<PropertyFilter> getPropertyFilters();
-
- /**
- * Access the {@link PropertyValueCombinationPolicy} used to evaluate the final
- * property values.
- * @return the {@link PropertyValueCombinationPolicy} used, never null.
- */
- PropertyValueCombinationPolicy getPropertyValueCombinationPolicy();
-
- /**
- * Creates a {@link ConfigurationContextBuilder} preinitialized with the data from this instance.
- * @return a new builder instance, never null.
- */
- ConfigurationContextBuilder toBuilder();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConfigurationContextBuilder.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConfigurationContextBuilder.java b/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConfigurationContextBuilder.java
deleted file mode 100644
index 5dfda4f..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConfigurationContextBuilder.java
+++ /dev/null
@@ -1,174 +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.builder.spi;
-
-import org.apache.tamaya.TypeLiteral;
-
-import java.util.Collection;
-
-/**
- * A builder for creating new or adapting instances of {@link ConfigurationContext}.
- * Builders can be obtained in exactly two ways:
- * <ol>
- * <li>By accessing a preinitialized builder from an existing {@link ConfigurationContext},
- * by calling {@link ConfigurationContext#toBuilder()}.</li>
- * <li>By accessing an empty builder instance from
- * {@link org.apache.tamaya.ConfigurationProvider#getConfigurationContextBuilder()}.</li>
- * </ol>
- * After all changes are applied to a builder a new {@link ConfigurationContext} instance can
- * be created and can be applied by calling
- * {@link org.apache.tamaya.ConfigurationProvider#setConfigurationContext(ConfigurationContext)}.
- *
- */
-
-/* @todo This is some Javadoc which is outdated. I am not sure if I can deleted it. The author
- * should take care. Oliver B. Fischer, 2015-12-23
- * Since this method can
- * throw an UnsupportedOperationException, you should check before if changing the current ConfigurationContext
- * programmatically is supported by calling
- * {@link org.apache.tamaya.ConfigurationProvider#is}.
- */
-public interface ConfigurationContextBuilder {
-
- /**
- * Init this builder instance with the given {@link ConfigurationContext} instance. This
- * method will replace any existing data in the current builder with the data contained in the given
- * {@link ConfigurationContext}.
- *
- * @param context the {@link ConfigurationContext} instance to be used, not null.
- * @return this builder, for chaining, never null.
- */
- ConfigurationContextBuilder setContext(ConfigurationContext context);
-
- /**
- * This method can be used for programmatically adding {@link PropertySource}s.
- * It is not needed for normal 'usage' by end users, but only for Extension Developers!
- *
- * @param propertySourcesToAdd the PropertySources to add
- * @return this builder, for chaining, never null.
- */
- ConfigurationContextBuilder addPropertySources(PropertySource... propertySourcesToAdd);
-
- /**
- * This method can be used for programmatically adding {@link PropertySource}s.
- * It is not needed for normal 'usage' by end users, but only for Extension Developers!
- *
- * @param propertySourcesToAdd the PropertySources to add
- * @return this builder, for chaining, never null.
- */
- ConfigurationContextBuilder addPropertySources(Collection<PropertySource> propertySourcesToAdd);
-
- /**
- * This method can be used for programmatically adding {@link PropertySource}s.
- * It is not needed for normal 'usage' by end users, but only for Extension Developers!
- *
- * @param propertySourcesNames the PropertySource names of the sources to remove
- * @return this builder, for chaining, never null.
- */
- ConfigurationContextBuilder removePropertySources(String... propertySourcesNames);
-
- /**
- * This method can be used for programmatically adding {@link PropertySource}s.
- * It is not needed for normal 'usage' by end users, but only for Extension Developers!
- *
- * @param propertySourcesNames the PropertySource names of the sources to remove
- * @return this builder, for chaining, never null.
- */
- ConfigurationContextBuilder removePropertySources(Collection<String> propertySourcesNames);
-
- /**
- * Adds the given PropertyFilter instances.
- *
- * @param filters the filters to add
- * @return this builder, for chaining, never null.
- */
- ConfigurationContextBuilder addPropertyFilters(PropertyFilter... filters);
-
- /**
- * Adds the given PropertyFilter instances.
- *
- * @param filters the filters to add
- * @return this builder, for chaining, never null.
- */
- ConfigurationContextBuilder addPropertyFilters(Collection<PropertyFilter> filters);
-
- /**
- * Removes the given PropertyFilter instances.
- *
- * @param filters the filters to remove
- * @return this builder, for chaining, never null.
- */
- ConfigurationContextBuilder removePropertyFilters(PropertyFilter... filters);
-
- /**
- * Removes the given PropertyFilter instances.
- *
- * @param filters the filters to remove
- * @return this builder, for chaining, never null.
- */
- ConfigurationContextBuilder removePropertyFilters(Collection<PropertyFilter> filters);
-
- /**
- * This method can be used for programmatically adding {@link PropertyConverter}s.
- * It is not needed for normal 'usage' by end users, but only for Extension Developers!
- *
- * @param <T> the type of the type literal
- * @param typeToConvert the type for which the converter is for
- * @param propertyConverter the PropertyConverters to add for this type
- * @return this builder, for chaining, never null.
- */
- <T> ConfigurationContextBuilder addPropertyConverter(TypeLiteral<T> typeToConvert,
- PropertyConverter<T> propertyConverter);
-
- /**
- * Removes the given PropertyConverter instances.
- *
- * @param typeToConvert the type which the converter is for
- * @param converters the converters to remove
- * @return this builder, for chaining, never null.
- */
- ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert,
- PropertyConverter<?>... converters);
-
- /**
- * Removes the given PropertyConverter instances.
- *
- * @param typeToConvert the type which the converter is for
- * @param converters the converters to remove
- * @return this builder, for chaining, never null.
- */
- ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert,
- Collection<PropertyConverter<?>> converters);
-
- /**
- * Sets the {@link PropertyValueCombinationPolicy} used to evaluate the final
- * property values.
- *
- * @param policy the {@link PropertyValueCombinationPolicy} used, not null
- * @return this builder, for chaining, never null.
- */
- ConfigurationContextBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy);
-
- /**
- * Builds a {@link ConfigurationContext} based on the data set.
- * @return final context with the current builder's properties.
- */
- ConfigurationContext build();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConfigurationProviderSpi.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConfigurationProviderSpi.java b/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConfigurationProviderSpi.java
deleted file mode 100644
index 2769d0a..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConfigurationProviderSpi.java
+++ /dev/null
@@ -1,76 +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.builder.spi;
-
-import org.apache.tamaya.Configuration;
-
-/**
- * SPI that must be implemented to provide the component that manages all {@link org.apache.tamaya.Configuration}
- * instances in a system. In SE this may be a true singleton containing exact one {@link org.apache.tamaya.Configuration}
- * instance, whereas in Java EE and other more complex environments instances may be returned depending the current
- * runtime context.
- */
-public interface ConfigurationProviderSpi {
-
- /**
- * Access the current {@link org.apache.tamaya.Configuration}.
- *
- * @return the current {@link org.apache.tamaya.Configuration} instance, never null.
- */
- Configuration getConfiguration();
-
- /**
- * Get access to the current {@link ConfigurationContext}.
- *
- * @return the current {@link ConfigurationContext}, never null.
- * @deprecated Will be removed in favour of {@link Configuration#getContext()}.
- */
- @Deprecated
- ConfigurationContext getConfigurationContext();
-
- /**
- * This method allows to replace the current {@link ConfigurationContext} with a new
- * instance. This can be used to update the context with a new one, e.g. because some of the configuration
- * data has changed and must be updated. It is the responsibility of the ConfigurationProvider to trigger
- * corresponding update event for the current {@link ConfigurationContext} or
- * {@link org.apache.tamaya.Configuration}.
- *
- * @param context the new ConfigurationContext to be applied.
- * @throws java.lang.UnsupportedOperationException if the current provider is read-only.
- */
- void setConfigurationContext(ConfigurationContext context);
-
- /**
- * Method that allows to determine if a new {@link ConfigurationContext} can be applied
- * programmatically.
- *
- * @return true, if {@link #setConfigurationContext(ConfigurationContext)} is supported
- * by the current implementation.
- * @see #setConfigurationContext(ConfigurationContext)
- */
- boolean isConfigurationContextSettable();
-
- /**
- * Creates a new {@link ConfigurationContextBuilder} instance.
- *
- * @return a new {@link ConfigurationContextBuilder}, never null.
- */
- ConfigurationContextBuilder getConfigurationContextBuilder();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConversionContext.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConversionContext.java b/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConversionContext.java
deleted file mode 100644
index 298e8bc..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ConversionContext.java
+++ /dev/null
@@ -1,255 +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.builder.spi;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.TypeLiteral;
-
-import java.lang.reflect.AnnotatedElement;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * A conversion context containing all the required values for implementing conversion. Use the included #Builder
- * for creating new instances of. This class is thread-safe to use. Adding supported formats is synchronized.
- * @see PropertyConverter
- */
-public class ConversionContext {
-
- private final Configuration configuration;
- private final String key;
- private final TypeLiteral<?> targetType;
- private final AnnotatedElement annotatedElement;
- private final List<String> supportedFormats = new ArrayList<>();
- private final ConfigurationContext configurationContext;
-
- /**
- * Private constructor used from builder.
- * @param builder the builder, not null.
- */
- protected ConversionContext(Builder builder){
- this.key = builder.key;
- this.annotatedElement = builder.annotatedElement;
- this.targetType = builder.targetType;
- this.supportedFormats.addAll(builder.supportedFormats);
- this.configuration = builder.configuration;
- this.configurationContext = builder.configurationContext;
- }
-
- /**
- * Get the key accessed. This information is very useful to evaluate additional metadata needed to determine/
- * control further aspects of the conversion.
- * @return the key. This may be null in case where a default value has to be converted and no unique underlying
- * key/value configuration is present.
- */
- public String getKey(){
- return key;
- }
-
- /**
- * Get the target type required.
- * @return the target type required.
- */
- public TypeLiteral<?> getTargetType(){
- return targetType;
- }
-
- /**
- * Get the annotated element, if conversion is performed using injection mechanisms.
- * @return the annotated element, or null.
- */
- public AnnotatedElement getAnnotatedElement(){
- return annotatedElement;
- }
-
- /**
- * Get the configuration, which is targeted.
- * @return the configuration instance, or null.
- */
- public Configuration getConfiguration(){
- return configuration;
- }
-
- /**
- * Allows to add information on the supported/tried formats, which can be shown to the user, especially when
- * conversion failed. Adding of formats is synchronized, all formats are added in order to the overall list.
- * This means formats should be passed in order of precedence.
- * @param converterType the converter, which implements the formats provided.
- * @param formatDescriptors the format descriptions in a human readable form, e.g. as regular expressions.
- */
- public void addSupportedFormats(Class<? extends PropertyConverter> converterType, String... formatDescriptors){
- synchronized (supportedFormats){
- for(String format: formatDescriptors) {
- supportedFormats.add(format + " (" + converterType.getSimpleName() + ")");
- }
- }
- }
-
- /**
- * Get the supported/tried formats in precedence order. The contents of this method depends on the
- * {@link PropertyConverter} instances involved in a conversion.
- * @return the supported/tried formats, never null.
- */
- public List<String> getSupportedFormats(){
- synchronized (supportedFormats){
- return new ArrayList<>(supportedFormats);
- }
- }
-
- @Override
- public String toString() {
- return "ConversionContext{" +
- "configuration=" + configuration +
- ", key='" + key + '\'' +
- ", targetType=" + targetType +
- ", annotatedElement=" + annotatedElement +
- ", supportedFormats=" + supportedFormats +
- '}';
- }
-
- public ConfigurationContext getConfigurationContext() {
- return configurationContext;
- }
-
- /**
- * Builder to create new instances of {@link ConversionContext}.
- */
- public static final class Builder{
- /** The backing configuration. */
- private Configuration configuration;
- /** The configuration context. */
- private ConfigurationContext configurationContext;
- /** The accessed key, or null. */
- private String key;
- /** The target type. */
- private final TypeLiteral<?> targetType;
- /** The injection target (only set with injection used). */
- private AnnotatedElement annotatedElement;
- /** The ordered list of formats tried. */
- private final Set<String> supportedFormats = new HashSet<>();
-
- /**
- * Creates a new Builder instance.
- * @param targetType the target type
- */
- public Builder(TypeLiteral<?> targetType) {
- this(null, null, null, targetType);
- }
-
- /**
- * Creates a new Builder instance.
- * @param key the requested key, may be null.
- * @param targetType the target type
- */
- public Builder(String key, TypeLiteral<?> targetType) {
- this(null, null, key, targetType);
- }
-
- /**
- * Creates a new Builder instance.
- * @param configuration the configuration, not null.
- * @param configurationContext configuration context, not null.
- * @param key the requested key, may be null.
- * @param targetType the target type
- */
- public Builder(Configuration configuration, ConfigurationContext configurationContext, String key, TypeLiteral<?> targetType){
- this.key = key;
- this.configuration = configuration;
- this.configurationContext = configurationContext;
- this.targetType = Objects.requireNonNull(targetType);
- }
-
- /**
- * Sets the key.
- * @param key the key, not null.
- * @return the builder instance, for chaining
- */
- public Builder setKey(String key){
- this.key = Objects.requireNonNull(key);
- return this;
- }
-
- /**
- * Sets the configuration.
- * @param configuration the configuration, not null
- * @return the builder instance, for chaining
- */
- public Builder setConfiguration(Configuration configuration){
- this.configuration = Objects.requireNonNull(configuration);
- return this;
- }
-
- /**
- * Sets the configuration.
- * @param configurationContext the configuration, not null
- * @return the builder instance, for chaining
- */
- public Builder setConfigurationContext(ConfigurationContext configurationContext){
- this.configurationContext = Objects.requireNonNull(configurationContext);
- return this;
- }
-
- /**
- * Sets the annotated element, when configuration is injected.
- * @param annotatedElement the annotated element, not null
- * @return the builder instance, for chaining
- */
- public Builder setAnnotatedElement(AnnotatedElement annotatedElement){
- this.annotatedElement = Objects.requireNonNull(annotatedElement);
- return this;
- }
-
- /**
- * Add the formats provided by a {@link PropertyConverter}. This method should be called by each converter
- * performing/trying conversion, so the user can be given feedback on the supported formats on failure.
- * @param converterType the converter type, not null.
- * @param formatDescriptors the formats supported in a human readable form, e.g. as regular expressions.
- * @return the builder instance, for chaining
- */
- public Builder addSupportedFormats(Class<? extends PropertyConverter> converterType, String... formatDescriptors){
- for(String format: formatDescriptors) {
- supportedFormats.add(format + " (" + converterType.getSimpleName() + ")");
- }
- return this;
- }
-
- /**
- * Builds a new context instance.
- * @return a new context, never null.
- */
- public ConversionContext build(){
- return new ConversionContext(this);
- }
-
- @Override
- public String toString() {
- return "Builder{" +
- "configuration=" + configuration +
- "context=" + configurationContext +
- ", key='" + key + '\'' +
- ", targetType=" + targetType +
- ", annotatedElement=" + annotatedElement +
- ", supportedFormats=" + supportedFormats +
- '}';
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/spi/PropertyConverter.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/spi/PropertyConverter.java b/modules/builder/src/main/java/org/apache/tamaya/builder/spi/PropertyConverter.java
deleted file mode 100644
index 83f6644..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/spi/PropertyConverter.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.builder.spi;
-
-
-/**
- * Interface for an property that converts a configured String into something else.
- * This is used for implementing type conversion from a property (String) to a certain target
- * type. Hereby the target type can be multivalued (e.g. collections) or complex if needed.
- *
- * @param <T> the type of the type literal
- */
-public interface PropertyConverter<T>{
-
- /**
- * Convert the given configuration keys from its String representation into the required target type.
- * The context instance passed also allows to add a list of supported formats, which is very handy in case a
- * value could not be converted. This list of supported formats can then shown to the user to give some hints
- * how a value could be configured.
- *
- * @param value configuration key that needs to be converted
- * @param context the {@link ConversionContext}, containing the String value and the requested configuration key.
- * @return converted keys
- * @see ConversionContext#addSupportedFormats(Class, String...)
- */
- T convert(String value, ConversionContext context);
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ServiceContext.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ServiceContext.java b/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ServiceContext.java
deleted file mode 100644
index 9fbfce8..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ServiceContext.java
+++ /dev/null
@@ -1,59 +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.builder.spi;
-
-import java.util.List;
-
-
-/**
- * This class models the component that is managing the lifecycle current the
- * services used by the Configuration API.
- */
-public interface ServiceContext {
-
- /**
- * @return ordinal of the ServiceContext. The one with the highest ordinal will be taken.
- */
- int ordinal();
-
- /**
- * Access a service singleton via its type.
- * If multiple implementations for the very serviceType exist then
- * the one with the highest {@link javax.annotation.Priority} will be used.
- *
- * @param <T> the type of the service type.
- * @param serviceType the service type.
- * @return The instance to be used, or {@code null}
- * @throws org.apache.tamaya.ConfigException if there are multiple service implementations with the maximum priority.
- */
- <T> T getService(Class<T> serviceType);
-
- /**
- * Access a list current services, given its type. The bootstrap mechanism should
- * order the instance for precedence, hereby the most significant should be
- * first in order.
- *
- * @param serviceType
- * the service type.
- * @param <T> the type of the list element returned by this method
- * @return The instance to be used, never {@code null}
- */
- <T> List<T> getServices(Class<T> serviceType);
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ServiceContextManager.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ServiceContextManager.java b/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ServiceContextManager.java
deleted file mode 100644
index 3d0e136..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/spi/ServiceContextManager.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.builder.spi;
-
-import java.util.Objects;
-import java.util.ServiceLoader;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.apache.tamaya.ConfigException;
-
-
-/**
- * This singleton provides access to the services available in the current {@link ServiceContext}. The
- * behaviour can be adapted, by calling {@link ServiceContextManager#set(ServiceContext)} before accessing any
- * services.
- */
-public final class ServiceContextManager {
-
- /** The logger used. */
- private static final Logger LOG = Logger.getLogger(ServiceContextManager.class.getName());
-
- /**
- * The ServiceProvider used.
- */
- private static volatile ServiceContext serviceContextProviderDelegate;
-
- /**
- * Private singletons constructor.
- */
- private ServiceContextManager() {
- }
-
- /**
- * Load the {@link ServiceContext} to be used.
- *
- * @return {@link ServiceContext} to be used for loading the services.
- */
- private static ServiceContext loadDefaultServiceProvider() {
- ServiceContext highestServiceContext = null;
- try {
- int highestOrdinal = 0;
- for (ServiceContext serviceContext : ServiceLoader.load(ServiceContext.class)) {
- if(highestServiceContext==null){
- highestServiceContext = serviceContext;
- }else if (serviceContext.ordinal() > highestOrdinal) {
- highestServiceContext = serviceContext;
- highestOrdinal = serviceContext.ordinal();
- }
- }
- } catch (Exception e) {
- throw new ConfigException("ServiceContext not loadable", e);
- }
- if (highestServiceContext==null){
- throw new ConfigException("No ServiceContext found");
- }
- LOG.info("Using Service Context of type: " + highestServiceContext.getClass().getName());
- return highestServiceContext;
- }
-
- /**
- * Replace the current {@link ServiceContext} in use.
- *
- * @param serviceContextProvider the new {@link ServiceContext}, not null.
- * @return the currently used context after setting it.
- */
- public static ServiceContext set(ServiceContext serviceContextProvider) {
- ServiceContext currentContext = ServiceContextManager.serviceContextProviderDelegate;
- Objects.requireNonNull(serviceContextProvider);
-
- synchronized (ServiceContextManager.class) {
- if (ServiceContextManager.serviceContextProviderDelegate == null) {
- ServiceContextManager.serviceContextProviderDelegate = serviceContextProvider;
- LOG.log(Level.INFO, "Using ServiceProvider: " + serviceContextProvider.getClass().getName());
- } else {
- LOG.log(Level.WARNING, "Replacing ServiceProvider " +
- ServiceContextManager.serviceContextProviderDelegate.getClass().getName() +
- " with: " + serviceContextProvider.getClass().getName());
- ServiceContextManager.serviceContextProviderDelegate = serviceContextProvider;
- }
- }
-
- return currentContext;
- }
-
- /**
- * Ge {@link ServiceContext}. If necessary the {@link ServiceContext} will be laziliy loaded.
- *
- * @return the {@link ServiceContext} used.
- */
- public static ServiceContext getServiceContext() {
- if (serviceContextProviderDelegate == null) {
- synchronized (ServiceContextManager.class) {
- if (serviceContextProviderDelegate == null) {
- serviceContextProviderDelegate = loadDefaultServiceProvider();
- }
- }
- }
- return serviceContextProviderDelegate;
- }
-
-}
[7/7] incubator-tamaya git commit: - Minimalized API. - Propagated
change to rest of modules.
Posted by an...@apache.org.
- Minimalized API.
- Propagated change to rest of modules.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/7144e3f9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/7144e3f9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/7144e3f9
Branch: refs/heads/tamaya-next
Commit: 7144e3f983cdbb441949e9e54b0c7ec0d31ca7f7
Parents: a728930
Author: anatole <an...@apache.org>
Authored: Wed Jul 20 02:58:59 2016 +0200
Committer: anatole <an...@apache.org>
Committed: Wed Jul 20 02:58:59 2016 +0200
----------------------------------------------------------------------
.../java/org/apache/tamaya/Configuration.java | 70 --
.../org/apache/tamaya/ConfigExceptionTest.java | 90 +-
.../org/apache/tamaya/TestConfiguration.java | 81 --
.../tamaya/TestConfigurationProvider.java | 34 -
.../java/org/apache/tamaya/TypeLiteralTest.java | 61 --
.../services/org.apache.tamaya.Configuration | 19 +
....tamaya.builder.spi.ConfigurationProviderSpi | 19 -
...org.apache.tamaya.builder.spi.ServiceContext | 19 -
code/core/pom.xml | 18 -
.../examples/builder/UsingABuilderExample.java | 4 +-
modules/adaptersupport/pom.xml | 66 ++
.../apache/tamaya/adapter/AdapterManager.java | 143 +++
.../org/apache/tamaya/adapter/package-info.java | 27 +
.../adapter/spi/ConfigurationAdapter.java | 52 ++
...ache.tamaya.adapter.spi.ConfigurationAdapter | 18 +
modules/builder/pom.xml | 15 +
.../tamaya/builder/ConfigurationBuilder.java | 605 ------------
...DefaultPropertySourceBasedConfiguration.java | 306 +++++++
.../ProgrammaticConfigurationContext.java | 388 --------
.../PropertySourceBasedConfiguration.java | 76 ++
...PropertySourceBasedConfigurationBuilder.java | 483 ++++++++++
.../tamaya/builder/PropertySourceBuilder.java | 1 +
.../tamaya/builder/SimplePropertySource.java | 86 --
.../internal/DefaultConfigurationContext.java | 278 ------
.../DefaultConfigurationContextBuilder.java | 153 ----
.../internal/DefaultConfigurationProvider.java | 62 --
.../builder/internal/DefaultServiceContext.java | 156 ----
.../tamaya/builder/internal/OSGIActivator.java | 53 --
.../builder/internal/OSGIServiceComparator.java | 69 --
.../builder/internal/OSGIServiceContext.java | 82 --
.../builder/internal/OSGIServiceLoader.java | 156 ----
.../internal/PriorityServiceComparator.java | 67 --
.../internal/PropertyConverterManager.java | 448 ---------
.../builder/internal/PropertyFiltering.java | 8 +-
...PropertySourceBasedConfigurationAdapter.java | 41 +
.../org/apache/tamaya/builder/package-info.java | 9 +-
.../builder/spi/ConfigurationContext.java | 159 ----
.../spi/ConfigurationContextBuilder.java | 174 ----
.../builder/spi/ConfigurationProviderSpi.java | 76 --
.../tamaya/builder/spi/ConversionContext.java | 255 ------
.../tamaya/builder/spi/PropertyConverter.java | 44 -
.../tamaya/builder/spi/ServiceContext.java | 59 --
.../builder/spi/ServiceContextManager.java | 118 ---
.../builder/ConfigurationBuilderTest.java | 908 -------------------
...ertySourceBasedConfigurationBuilderTest.java | 899 ++++++++++++++++++
.../ConverterTestsPropertySource.java | 4 +-
.../internal/converters/EnumConverterTest.java | 2 +-
modules/defaultconfig/pom.xml | 62 ++
.../defaults/ConfigurationWithDefaults.java | 72 ++
.../ConfigurationWithDefaultsAdapter.java | 37 +
.../DefaultConfigurationWithDefaults.java | 105 +++
.../apache/tamaya/defaults/package-info.java | 26 +
...ache.tamaya.adapter.spi.ConfigurationAdapter | 17 +
modules/formats/pom.xml | 5 +
.../format/FlattenedDefaultPropertySource.java | 4 +-
.../internal/DefaultDynamicValueTest.java | 4 +-
modules/pom.xml | 4 +
.../tamaya/servicecontext/ServiceContext.java | 67 ++
.../servicecontext/ServiceContextManager.java | 116 +++
.../internal/DefaultServiceContext.java | 155 ++++
.../servicecontext/internal/OSGIActivator.java | 51 ++
.../internal/OSGIServiceComparator.java | 69 ++
.../internal/OSGIServiceContext.java | 98 ++
.../internal/OSGIServiceLoader.java | 156 ++++
.../internal/PriorityServiceComparator.java | 67 ++
...tServiceContextTest$InvalidPriorityInterface | 18 +
...efaultServiceContextTest$MultiImplsInterface | 20 +
.../internal/PriorityServiceComparator.java | 67 ++
.../internal/PropertyConverterManager.java | 449 +++++++++
.../tamaya/types/internal/ReflectionUtil.java | 42 +
.../adapters/DefaultTypedConfiguration.java | 154 ++++
.../converters/BigDecimalConverter.java | 63 ++
.../converters/BigIntegerConverter.java | 94 ++
.../internal/converters/BooleanConverter.java | 57 ++
.../internal/converters/ByteConverter.java | 71 ++
.../internal/converters/CharConverter.java | 69 ++
.../internal/converters/ClassConverter.java | 63 ++
.../internal/converters/CurrencyConverter.java | 90 ++
.../internal/converters/DoubleConverter.java | 82 ++
.../internal/converters/EnumConverter.java | 68 ++
.../internal/converters/FloatConverter.java | 81 ++
.../internal/converters/IntegerConverter.java | 74 ++
.../internal/converters/LongConverter.java | 72 ++
.../internal/converters/NumberConverter.java | 72 ++
.../internal/converters/ShortConverter.java | 72 ++
.../types/internal/converters/URIConverter.java | 47 +
.../types/internal/converters/URLConverter.java | 47 +
.../org/apache/tamaya/types/package-info.java | 28 +
.../tamaya/types/spi/ConversionContext.java | 234 +++++
.../tamaya/types/spi/PropertyConverter.java | 44 +
...ache.tamaya.adapter.spi.ConfigurationAdapter | 17 +
.../internal/PropertyConverterManagerTest.java | 178 ++++
.../converters/BigDecimalConverterTest.java | 103 +++
.../converters/BooleanConverterTest.java | 108 +++
.../internal/converters/ByteConverterTest.java | 81 ++
.../internal/converters/CharConverterTest.java | 86 ++
.../ConverterTestsPropertySource.java | 253 ++++++
.../converters/CurrencyConverterTest.java | 154 ++++
.../converters/DoubleConverterTest.java | 175 ++++
.../internal/converters/EnumConverterTest.java | 59 ++
.../internal/converters/FloatConverterTest.java | 176 ++++
.../converters/IntegerConverterTest.java | 111 +++
.../internal/converters/LongConverterTest.java | 111 +++
.../converters/NumberConverterTest.java | 103 +++
.../internal/converters/ShortConverterTest.java | 111 +++
.../types/util/mockito/NotMockedAnswer.java | 57 ++
.../tamaya/types/util/types/CustomTypeA.java | 34 +
.../tamaya/types/util/types/CustomTypeB.java | 39 +
.../tamaya/types/util/types/CustomTypeC.java | 36 +
.../types/CustomTypeCPropertyConverter.java | 29 +
110 files changed, 7514 insertions(+), 4761 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/code/api/src/main/java/org/apache/tamaya/Configuration.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/Configuration.java b/code/api/src/main/java/org/apache/tamaya/Configuration.java
index 188a3ff..2b63d29 100644
--- a/code/api/src/main/java/org/apache/tamaya/Configuration.java
+++ b/code/api/src/main/java/org/apache/tamaya/Configuration.java
@@ -47,79 +47,9 @@ public interface Configuration {
String get(String key);
/**
- * Access a property.
- *
- * @param key the property's key, not null.
- * @param defaultValue value to be returned, if no value is present.
- * @return the property's keys.
- */
- String getOrDefault(String key, final String defaultValue);
-
-// /**
-// * Access a property providing a value supplier called, if no configured value is available.
-// *
-// * @param key the property's key, not null.
-// * @param defaultValueSupplier value supplier to be called, if no value is present.
-// * @return the property value.
-// */
-// default String getOrDefault(String key, Supplier<String> defaultValueSupplier){
-// String value = get(key);
-// if(value==null){
-// return defaultValueSupplier.supply();
-// }
-// return value;
-// }
-
- /**
* Access all currently known configuration properties as a full {@code Map<String,String>}.
* @return all currently known configuration properties.
*/
Map<String,String> getProperties();
-// /**
-// * Access a typed property providing a conversion.
-// *
-// * @param key the property's key, not null.
-// * @param conversion the value conversion, called if a configured value is present for the given key,
-// * not null.
-// * @return the property value, or null, if no such value has been found.
-// */
-// default <T> T get(String key, Function<String,T> conversion){
-// String value = get(key);
-// if(value!=null){
-// return conversion.apply(value);
-// }
-// return null;
-// }
-//
-// /**
-// * Access a typed property providing a conversion and a default value.
-// *
-// * @param key the property's key, not null.
-// * @param conversion the value conversion, called if a configured value is present for the given key,
-// * not null.
-// * @param defaultValue the default value to be returned, if no configured value has been found, including
-// * {@code null}.
-// * @return the property value, or null, if no such value has been found.
-// */
-// default <T> T getOrDefault(String key, Function<String,T> conversion, final T defaultValue){
-// return getOrDefault(key, conversion, () -> defaultValue);
-// }
-// /**
-// * Access a typed property providing a conversion and a default value supplier.
-// *
-// * @param key the property's key, not null.
-// * @param conversion the value conversion, called if a configured value is present for the given key,
-// * not null.
-// * @param defaultValueSupplier the default value supplier to be called, if no configured value has been found..
-// * @return the property value, or null, if no such value has been found.
-// */
-// default <T> T getOrDefault(String key, Function<String,T> conversion, Supplier<T> defaultValueSupplier){
-// String value = get(key);
-// if(value!=null){
-// return conversion.apply(value);
-// }
-// return defaultValueSupplier.supply();
-// }
-
}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/code/api/src/test/java/org/apache/tamaya/ConfigExceptionTest.java
----------------------------------------------------------------------
diff --git a/code/api/src/test/java/org/apache/tamaya/ConfigExceptionTest.java b/code/api/src/test/java/org/apache/tamaya/ConfigExceptionTest.java
index 09b8d88..fa7da0a 100644
--- a/code/api/src/test/java/org/apache/tamaya/ConfigExceptionTest.java
+++ b/code/api/src/test/java/org/apache/tamaya/ConfigExceptionTest.java
@@ -1,45 +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;
-//
-//import org.junit.Test;
-//
-//import static org.junit.Assert.*;
-//
-///**
-// * Tests instantiating {@link ConfigException}.
-// */
-//public class ConfigExceptionTest {
-//
-// @Test
-// public void testCreationMessage(){
-// ConfigException ex = new ConfigException("test");
-// assertNull(ex.getCause());
-// assertEquals(ex.getMessage(), "test");
-// }
-//
-// @Test
-// public void testCreationMessageThrowable(){
-// Exception e = new IllegalStateException("blabla");
-// ConfigException ex = new ConfigException("test", e);
-// assertTrue(ex.getCause() == e);
-// assertEquals("test", ex.getMessage());
-// }
-//
-//}
\ No newline at end of file
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests instantiating {@link ConfigException}.
+ */
+public class ConfigExceptionTest {
+
+ @Test
+ public void testCreationMessage(){
+ ConfigException ex = new ConfigException("test");
+ assertNull(ex.getCause());
+ assertEquals(ex.getMessage(), "test");
+ }
+
+ @Test
+ public void testCreationMessageThrowable(){
+ Exception e = new IllegalStateException("blabla");
+ ConfigException ex = new ConfigException("test", e);
+ assertTrue(ex.getCause() == e);
+ assertEquals("test", ex.getMessage());
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/code/api/src/test/java/org/apache/tamaya/TestConfiguration.java
----------------------------------------------------------------------
diff --git a/code/api/src/test/java/org/apache/tamaya/TestConfiguration.java b/code/api/src/test/java/org/apache/tamaya/TestConfiguration.java
index a324be1..5038bc7 100644
--- a/code/api/src/test/java/org/apache/tamaya/TestConfiguration.java
+++ b/code/api/src/test/java/org/apache/tamaya/TestConfiguration.java
@@ -46,87 +46,6 @@ public class TestConfiguration implements Configuration{
}
@Override
- public String getOrDefault(String key, String defaultValue) {
- String val = get(key);
- if(val==null){
- return defaultValue;
- }
- return val;
- }
-
-// @Override
-// public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
-// T val = get(key, type);
-// if(val==null){
-// return defaultValue;
-// }
-// return val;
-// }
-//
-// @Override
-// public <T> T get(String key, Class<T> type) {
-// if(type.equals(Long.class)){
-// return (T)(Object)Long.MAX_VALUE;
-// }
-// else if(type.equals(Integer.class)){
-// return (T)(Object) Integer.MAX_VALUE;
-// }
-// else if(type.equals(Double.class)){
-// return (T)(Object) Double.MAX_VALUE;
-// }
-// else if(type.equals(Float.class)){
-// return (T)(Object) Float.MAX_VALUE;
-// }
-// else if(type.equals(Short.class)){
-// return (T)(Object) Short.MAX_VALUE;
-// }
-// else if(type.equals(Byte.class)){
-// return (T)(Object) Byte.MAX_VALUE;
-// }
-// else if(type.equals(Boolean.class)){
-// if("booleanTrue".equals(key)) {
-// return (T)Boolean.TRUE;
-// }
-// else{
-// return (T)Boolean.FALSE;
-// }
-// }
-// else if(type.equals(String.class)){
-// return (T)"aStringValue";
-// }
-// throw new ConfigException("No such property: " + key);
-// }
-//
-// @Override
-// public <T> T get(String key, TypeLiteral<T> type) {
-// throw new RuntimeException("Method not implemented yet.");
-// }
-//
-// @Override
-// public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) {
-// T val = get(key, type);
-// if(val==null){
-// return defaultValue;
-// }
-// return val;
-// }
-//
-// @Override
-// public Configuration with(ConfigOperator operator) {
-// return null;
-// }
-//
-// @Override
-// public <T> T query(ConfigQuery<T> query) {
-// throw new RuntimeException("Method not implemented yet.");
-// }
-//
-// @Override
-// public ConfigurationContext getContext() {
-// return null;
-// }
-
- @Override
public Map<String, String> getProperties() {
throw new RuntimeException("Method not implemented yet.");
}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/code/api/src/test/java/org/apache/tamaya/TestConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/code/api/src/test/java/org/apache/tamaya/TestConfigurationProvider.java b/code/api/src/test/java/org/apache/tamaya/TestConfigurationProvider.java
deleted file mode 100644
index cc66d35..0000000
--- a/code/api/src/test/java/org/apache/tamaya/TestConfigurationProvider.java
+++ /dev/null
@@ -1,34 +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;
-
-
-/**
- * Test Configuration class, that is used to testdata the default methods provided by the API.
- */
-public class TestConfigurationProvider extends ConfigurationProvider {
-
- private static final Configuration config = new TestConfiguration();
-
- @Override
- public Configuration getConfiguration() {
- return config;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/code/api/src/test/java/org/apache/tamaya/TypeLiteralTest.java
----------------------------------------------------------------------
diff --git a/code/api/src/test/java/org/apache/tamaya/TypeLiteralTest.java b/code/api/src/test/java/org/apache/tamaya/TypeLiteralTest.java
deleted file mode 100644
index a04636d..0000000
--- a/code/api/src/test/java/org/apache/tamaya/TypeLiteralTest.java
+++ /dev/null
@@ -1,61 +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;
-//
-//import org.junit.Test;
-//
-//import java.util.ArrayList;
-//import java.util.List;
-//
-//import static org.junit.Assert.assertEquals;
-//
-///**
-// * Tests for the {@link TypeLiteral} class.
-// */
-//public class TypeLiteralTest {
-//
-// @Test
-// public void test_constrcutor(){
-// TypeLiteral<List<String>> listTypeLiteral = new TypeLiteral<List<String>>(){};
-// assertEquals(List.class, listTypeLiteral.getRawType());
-// assertEquals(String.class, TypeLiteral.getTypeParameters(listTypeLiteral.getType())[0]);
-// }
-//
-// @Test
-// public void test_of(){
-// class MyListClass extends ArrayList<String>{}
-// TypeLiteral<MyListClass> listTypeLiteral = TypeLiteral.of(MyListClass.class);
-// assertEquals(MyListClass.class, listTypeLiteral.getRawType());
-// assertEquals(MyListClass.class, listTypeLiteral.getType());
-// }
-//
-// @Test
-// public void test_getTypeParameter(){
-// TypeLiteral<List<String>> listTypeLiteral = new TypeLiteral<List<String>>(){};
-// assertEquals(List.class, listTypeLiteral.getRawType());
-// assertEquals(String.class, TypeLiteral.getTypeParameters(listTypeLiteral.getType())[0]);
-// }
-//
-// @Test
-// public void test_getGenericInterfaceTypeParameter(){
-// class MyListClass extends ArrayList<String> implements List<String>{}
-// assertEquals(String.class, TypeLiteral.getGenericInterfaceTypeParameters(MyListClass.class, List.class)[0]);
-// }
-//
-//}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/code/api/src/test/resources/META-INF/services/org.apache.tamaya.Configuration
----------------------------------------------------------------------
diff --git a/code/api/src/test/resources/META-INF/services/org.apache.tamaya.Configuration b/code/api/src/test/resources/META-INF/services/org.apache.tamaya.Configuration
new file mode 100644
index 0000000..cb8aac4
--- /dev/null
+++ b/code/api/src/test/resources/META-INF/services/org.apache.tamaya.Configuration
@@ -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.TestConfiguration
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/code/api/src/test/resources/META-INF/services/org.apache.tamaya.builder.spi.ConfigurationProviderSpi
----------------------------------------------------------------------
diff --git a/code/api/src/test/resources/META-INF/services/org.apache.tamaya.builder.spi.ConfigurationProviderSpi b/code/api/src/test/resources/META-INF/services/org.apache.tamaya.builder.spi.ConfigurationProviderSpi
deleted file mode 100644
index b9c5ba5..0000000
--- a/code/api/src/test/resources/META-INF/services/org.apache.tamaya.builder.spi.ConfigurationProviderSpi
+++ /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.TestConfigurationProvider
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/code/api/src/test/resources/META-INF/services/org.apache.tamaya.builder.spi.ServiceContext
----------------------------------------------------------------------
diff --git a/code/api/src/test/resources/META-INF/services/org.apache.tamaya.builder.spi.ServiceContext b/code/api/src/test/resources/META-INF/services/org.apache.tamaya.builder.spi.ServiceContext
deleted file mode 100644
index 8da8805..0000000
--- a/code/api/src/test/resources/META-INF/services/org.apache.tamaya.builder.spi.ServiceContext
+++ /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.builder.spi.TestServiceContext
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/code/core/pom.xml
----------------------------------------------------------------------
diff --git a/code/core/pom.xml b/code/core/pom.xml
index 94e966e..5e7f358 100644
--- a/code/core/pom.xml
+++ b/code/core/pom.xml
@@ -30,10 +30,6 @@ under the License.
<name>Apache Tamaya Core Implementation</name>
<packaging>bundle</packaging>
- <properties>
- <osgi.compendium.version>5.0.0</osgi.compendium.version>
- </properties>
-
<dependencies>
<dependency>
<groupId>org.apache.tamaya</groupId>
@@ -48,20 +44,6 @@ under the License.
<groupId>org.hamcrest</groupId>
<artifactId>java-hamcrest</artifactId>
</dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- <scope>provided</scope>
- <version>${osgi.compendium.version}</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <version>${osgi.version}</version>
- <scope>provided</scope>
- <optional>true</optional>
- </dependency>
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/examples/7-builder-example/src/main/java/org/apache/tamaya/examples/builder/UsingABuilderExample.java
----------------------------------------------------------------------
diff --git a/examples/7-builder-example/src/main/java/org/apache/tamaya/examples/builder/UsingABuilderExample.java b/examples/7-builder-example/src/main/java/org/apache/tamaya/examples/builder/UsingABuilderExample.java
index de73854..13f5aab 100644
--- a/examples/7-builder-example/src/main/java/org/apache/tamaya/examples/builder/UsingABuilderExample.java
+++ b/examples/7-builder-example/src/main/java/org/apache/tamaya/examples/builder/UsingABuilderExample.java
@@ -19,7 +19,7 @@
package org.apache.tamaya.examples.builder;
import org.apache.tamaya.Configuration;
-import org.apache.tamaya.builder.ConfigurationBuilder;
+import org.apache.tamaya.builder.PropertySourceBasedConfigurationBuilder;
import org.apache.tamaya.resource.ConfigResources;
@@ -33,7 +33,7 @@ public class UsingABuilderExample {
public static void main(String... args) {
- ConfigurationBuilder builder = new ConfigurationBuilder();
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
Configuration config = builder.addPropertySources(ConfigResources.getResourceResolver().getResources("META-INF/boot/*.ini"))
.addPropertySources(ConfigResources.getResourceResolver().getResources("META-INF/config/*.properties"))
.enableProvidedPropertyConverters()
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/adaptersupport/pom.xml
----------------------------------------------------------------------
diff --git a/modules/adaptersupport/pom.xml b/modules/adaptersupport/pom.xml
new file mode 100644
index 0000000..798c84f
--- /dev/null
+++ b/modules/adaptersupport/pom.xml
@@ -0,0 +1,66 @@
+<?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.
+-->
+<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>
+ </parent>
+
+ <artifactId>tamaya-adaptersupport</artifactId>
+ <name>Apache Tamaya Modules - Configuration Adapter Support</name>
+ <packaging>jar</packaging> <!-- bundle -->
+
+ <inceptionYear>2016</inceptionYear>
+
+ <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-servicecontext</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>java-hamcrest</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+
+
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/adaptersupport/src/main/java/org/apache/tamaya/adapter/AdapterManager.java
----------------------------------------------------------------------
diff --git a/modules/adaptersupport/src/main/java/org/apache/tamaya/adapter/AdapterManager.java b/modules/adaptersupport/src/main/java/org/apache/tamaya/adapter/AdapterManager.java
new file mode 100644
index 0000000..4ae50ac
--- /dev/null
+++ b/modules/adaptersupport/src/main/java/org/apache/tamaya/adapter/AdapterManager.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.adapter;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.adapter.spi.ConfigurationAdapter;
+import org.apache.tamaya.servicecontext.ServiceContext;
+import org.apache.tamaya.servicecontext.ServiceContextManager;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+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;
+
+/**
+ * Manager that deals with {@link ConfigurationAdapter} instances.
+ * This class is thread-safe.
+ */
+public final class AdapterManager implements ConfigurationAdapter{
+ /**
+ * The logger used.
+ */
+ private static final Logger LOG = Logger.getLogger(AdapterManager.class.getName());
+ /**
+ * The registered converters.
+ */
+ private final List<ConfigurationAdapter> adapters = new ArrayList<>();
+
+ private static final AdapterManager INSTANCE = new AdapterManager();
+
+ /**
+ * 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) {
+ ServiceContext serviceContext = ServiceContextManager.getServiceContext();
+ int prio = serviceContext.getPriority(o1) - serviceContext.getPriority(o2);
+ if (prio < 0) {
+ return 1;
+ } else if (prio > 0) {
+ return -1;
+ } else {
+ return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
+ }
+ }
+ };
+
+ /**
+ * Get the instance of the adapter manager.
+ * @return the instance of the adapter manager, not null.
+ */
+ public static final AdapterManager getInstance(){
+ return INSTANCE;
+ }
+
+ /**
+ * Constructor.
+ */
+ private AdapterManager() {
+ this.adapters.addAll(ServiceContextManager.getServiceContext().getServices(ConfigurationAdapter.class));
+ Collections.sort(this.adapters, PRIORITY_COMPARATOR);
+ }
+
+ /**
+ * Registers a new adapter instance.
+ *
+ * @param adapter the new adapter, not null.
+ */
+ public void registerAdapter(ConfigurationAdapter adapter) {
+ Lock writeLock = lock.writeLock();
+ try {
+ writeLock.lock();
+ this.adapters.addAll(ServiceContextManager.getServiceContext().getServices(ConfigurationAdapter.class));
+ Collections.sort(this.adapters, PRIORITY_COMPARATOR);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Get a list of all currently loaded {@link ConfigurationAdapter} in order of relevance.
+ *
+ * @return the list of currently available adapters.
+ */
+ public List<ConfigurationAdapter> getAdapters() {
+ Lock readLock = lock.readLock();
+ try {
+ readLock.lock();
+ return new ArrayList<>(this.adapters);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ @Override
+ public <T> T adapt(Configuration configuration, Class<T> targetType) {
+ for(ConfigurationAdapter adapter:adapters){
+ try {
+ Object o = adapter.adapt(configuration, targetType);
+ if(o!=null){
+ return (T)o;
+ }
+ }catch(Exception e){
+ LOG.log(Level.SEVERE, "Error adapting configuration to: " + targetType.getName(), e);
+ }
+ }
+ throw new ConfigException("Cannot adapt configuration to " + targetType.getName());
+ }
+
+
+ @Override
+ public String toString() {
+ return "AdapterManager{" +
+ "adapters=" + adapters +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/adaptersupport/src/main/java/org/apache/tamaya/adapter/package-info.java
----------------------------------------------------------------------
diff --git a/modules/adaptersupport/src/main/java/org/apache/tamaya/adapter/package-info.java b/modules/adaptersupport/src/main/java/org/apache/tamaya/adapter/package-info.java
new file mode 100644
index 0000000..0442f0f
--- /dev/null
+++ b/modules/adaptersupport/src/main/java/org/apache/tamaya/adapter/package-info.java
@@ -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.
+ */
+/**
+ * This package provides a singleton managing the currently available
+ * {@link org.apache.tamaya.adapter.spi.org.apache.tamaya.adapter.spi.ConfigurationAdapter}
+ * instances. It also supports creating proxy interfaces supporting multiple adapted types
+ * at once.
+ *
+ * @see org.apache.tamaya.Configuration
+ */
+package org.apache.tamaya.adapter;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/adaptersupport/src/main/java/org/apache/tamaya/adapter/spi/ConfigurationAdapter.java
----------------------------------------------------------------------
diff --git a/modules/adaptersupport/src/main/java/org/apache/tamaya/adapter/spi/ConfigurationAdapter.java b/modules/adaptersupport/src/main/java/org/apache/tamaya/adapter/spi/ConfigurationAdapter.java
new file mode 100644
index 0000000..79ea7a1
--- /dev/null
+++ b/modules/adaptersupport/src/main/java/org/apache/tamaya/adapter/spi/ConfigurationAdapter.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.adapter.spi;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+
+import java.util.Map;
+
+/**
+ * <p>A adapter that transforms/adapts a {@link org.apache.tamaya.Configuration} to implement
+ * another interface. Adapters are ordered internally by their annotated {@link javax.annotation.Priority}
+ * value (highest first). Returning a non null value for the adapted target type ends traversal of
+ * possible adapters and returns immedeately the result.
+ *
+ * Normally adapters should not be cached. Caching is within the responsibility of the caller logic.
+ * <h3>Implementation Requirements</h3>
+ * Implementations of this interface must be
+ * <ul>
+ * <li>Thread safe</li>
+ * <li>Immutable</li>
+ * </ul>
+ */
+public interface ConfigurationAdapter {
+
+ /**
+ * Adapts a configuration. If this factory is not capable of providing the required
+ * target type, it is safe to return {@code null}.
+ *
+ * @param configuration the configuration to be adapted, not null.
+ * @param targetType the target type, not null.
+ * @return the adapter, or null.
+ */
+ <T> T adapt(Configuration configuration, Class<T> targetType);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/adaptersupport/src/test/resources/META-INF/services/org.apache.tamaya.adapter.spi.ConfigurationAdapter
----------------------------------------------------------------------
diff --git a/modules/adaptersupport/src/test/resources/META-INF/services/org.apache.tamaya.adapter.spi.ConfigurationAdapter b/modules/adaptersupport/src/test/resources/META-INF/services/org.apache.tamaya.adapter.spi.ConfigurationAdapter
new file mode 100644
index 0000000..f3199f2
--- /dev/null
+++ b/modules/adaptersupport/src/test/resources/META-INF/services/org.apache.tamaya.adapter.spi.ConfigurationAdapter
@@ -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 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.
+#
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/pom.xml
----------------------------------------------------------------------
diff --git a/modules/builder/pom.xml b/modules/builder/pom.xml
index 96f6244..815867c 100644
--- a/modules/builder/pom.xml
+++ b/modules/builder/pom.xml
@@ -39,6 +39,21 @@ under the License.
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-adaptersupport</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-types</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-servicecontext</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.tamaya.ext</groupId>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/ConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/ConfigurationBuilder.java b/modules/builder/src/main/java/org/apache/tamaya/builder/ConfigurationBuilder.java
deleted file mode 100644
index 6188f83..0000000
--- a/modules/builder/src/main/java/org/apache/tamaya/builder/ConfigurationBuilder.java
+++ /dev/null
@@ -1,605 +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.builder;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.builder.spi.PropertyConverter;
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.format.ConfigurationData;
-import org.apache.tamaya.format.ConfigurationFormats;
-import org.apache.tamaya.format.FlattenedDefaultPropertySource;
-import org.apache.tamaya.builder.spi.ConfigurationContext;
-import org.apache.tamaya.builder.spi.PropertyFilter;
-import org.apache.tamaya.builder.spi.PropertySource;
-import org.apache.tamaya.builder.spi.PropertySourceProvider;
-import org.apache.tamaya.builder.spi.PropertyValueCombinationPolicy;
-import org.apache.tamaya.spisupport.DefaultConfiguration;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Collection;
-import java.util.Objects;
-
-import static java.lang.String.format;
-
-/**
- * <p>Builder class used for building a configuration manually without relying
- * only on the Service Provider Interface API.</p>
- *
- * <p><strong>Features of the builder</strong></p>
- *
- * <ol>
- * <li>Adding of property converters manually</li>
- * <li>Adding of property sources directly</li>
- * <li>Adding of property sources via URL</li>
- * <li>Adding of property source providers directly</li>
- * <li>Enabling and disabling of via SPI mechanism provided resources as converters,
- * property sources, etc.</li>
- * </ol>
- *
- * <p><strong>Example</strong></p>
- *
- * <pre>{@code ConfigurationBuilder builder = new ConfigurationBuilder();
- * builder.disableProvidedPropertySources() // Do not load provided property
- * .disableProvidedPropertySourceProviders() // sources and providers automatically
- * .addPropertySource("file:/etc/conf.properties"); // Load properties from conf.properties
- *
- * Configuration config = builder.build();
- * }</pre>
- *
- * <p><strong>Support for configuration formats</strong></p>
- *
- * The configuration builder allows you to put property resources
- * via a URL, as shown in the code example above, without implementing
- * a {@link PropertySource PropertySource} or providing an
- * instance of a {@link PropertySource PropertySource}.
- * If a property resource in
- * a specific format can be added to configuration builder or not depends
- * on the available implementations of
- * {@link org.apache.tamaya.format.ConfigurationFormat} in the classpath.
- * Which formats are available can be checked via
- * {@link org.apache.tamaya.format.ConfigurationFormats#getFormats()}.
- */
-public class ConfigurationBuilder {
- /** Builder used to create new ConfigurationContext instances. */
- private final ProgrammaticConfigurationContext.Builder contextBuilder = new ProgrammaticConfigurationContext.Builder();
-
- /**
- * Flag if the config has already been built.
- * Configuration can be built only once
- */
- private boolean built;
-
- /**
- * Flag if all existing property converter service providers
- * should be loaded if the configuration is build.
- */
- private boolean loadProvidedPropertyConverters = true;
-
- /**
- * Flag if all existing property source service providers
- * will be loaded if the configuration is build.
- */
- private boolean loadProvidedPropertySources = false;
- private boolean loadProvidedPropertySourceProviders = false;
-
- private boolean isLoadProvidedPropertyFilters = false;
-
- /**
- * Creates a new builder instance.
- */
- public ConfigurationBuilder() {
- }
-
- /**
- * Allows to set configuration context during unit tests.
- */
- ConfigurationBuilder setConfigurationContext(ConfigurationContext configurationContext) {
- //noinspection deprecation
- contextBuilder.setConfigurationContext(configurationContext);
- return this;
- }
-
- /**
- * Adds one resources with properties in an arbitrary format
- * to the configuration to be build.
- *
- * <p>If a specific format is supported depends on the available
- * {@link org.apache.tamaya.format.ConfigurationFormat} implementations.</p>
- *
- * <pre>{@code URL resource = new URL("file:/etc/service/config.json");
- *
- * builder.addPropertySources(resource);}
- * </pre>
- *
- * @param url resource with properties for the the configuration to be build.
- *
- * @return the builder instance currently used
- *
- * @see org.apache.tamaya.format.ConfigurationFormat
- * @see org.apache.tamaya.format.ConfigurationFormats#getFormats()
- */
- public ConfigurationBuilder addPropertySource(URL url) {
- try {
- ConfigurationData data = getConfigurationDataFromURL(url);
-
- FlattenedDefaultPropertySource propertySource = new FlattenedDefaultPropertySource(data);
- addPropertySources(propertySource);
- } catch (IOException e) {
- throw new ConfigException("Failed to read " + url.toString(), e);
- }
- return this;
- }
-
- protected ConfigurationData getConfigurationDataFromURL(URL url) throws IOException {
- ConfigurationData data = ConfigurationFormats.readConfigurationData(url);
-
- if (null == data) {
- String mesg = format("No configuration format found which is able " +
- "to read properties from %s.", url.toString());
-
- throw new ConfigException(mesg);
- }
-
- return data;
- }
-
- /**
- * Adds one or more resources with properties in an arbitrary format
- * to the configuration to be build.
- *
- * <p>If a specific format is supported depends on the available
- * {@link org.apache.tamaya.format.ConfigurationFormat} implementations.</p>
- *
- *<pre>{@code URL first = new URL("file:/etc/service/config.json");
- * URL second = new URL("file:/etc/defaults/values.properties");
- *
- * builder.addPropertySources(first, second);}
- *</pre>
- *
- * @param urls list of resources with properties for the configuration to be
- * build.
- *
- * @return the builder instance currently used
- *
- * @see org.apache.tamaya.format.ConfigurationFormat
- * @see org.apache.tamaya.format.ConfigurationFormats#getFormats()
- */
- public ConfigurationBuilder addPropertySources(URL... urls) {
- for(URL url:urls){
- if(url!=null){
- addPropertySource(url);
- }
- }
- return this;
- }
-
- /**
- * Adds one or more resources with properties in an arbitrary format
- * to the configuration to be build.
- *
- * <p>If a specific format is supported depends on the available
- * {@link org.apache.tamaya.format.ConfigurationFormat} implementations.</p>
- *
- *<pre>{@code URL first = new URL("file:/etc/service/config.json");
- * URL second = new URL("file:/etc/defaults/values.properties");
- *
- * builder.addPropertySources(first, second);}
- *</pre>
- *
- * @param urls list of resources with properties for the configuration to be
- * build.
- *
- * @return the builder instance currently used
- *
- * @see org.apache.tamaya.format.ConfigurationFormat
- * @see org.apache.tamaya.format.ConfigurationFormats#getFormats()
- */
- public ConfigurationBuilder addPropertySources(Collection<URL> urls) {
- for(URL url:urls) {
- if (url != null) {
- addPropertySource(url);
- }
- }
- return this;
- }
-
-
- /**
- * Adds one or more resources with properties in an arbitrary format
- * to the configuration to be build.
- *
- * <p>If a specific format is supported depends on the available
- * {@link org.apache.tamaya.format.ConfigurationFormat} implementations.</p>
- *
- *<pre>{@code builder.addPropertySources("file:/etc/service/config.json",
- * "file:/etc/defaults/values.properties");}
- *</pre>
- *
- * @param urls list of resources with properties for the configuration to be
- * build.
- *
- * @return the builder instance currently used
- *
- * @see org.apache.tamaya.format.ConfigurationFormat
- * @see org.apache.tamaya.format.ConfigurationFormats#getFormats()
- */
- public ConfigurationBuilder addPropertySources(String... urls) {
- for(String url:urls) {
- if (url != null) {
- try{
- addPropertySource(new URL(url));
- } catch(Exception e){
- throw new ConfigException("Invalid URL: " + url);
- }
- }
- }
- return this;
- }
-
- /**
- * Adds one or more property source instances to the configuration to be build.
- *
- *<pre>{@code PropertySource first = new CustomPropertySource();
- * PropertySource second = new YetAnotherPropertySource();
- *
- * builder.addPropertySources(first, second)};
- *</pre>
- *
- * @param sources list of property source instances with properties for the
- * configuration to be build.
- *
- * @return the builder instance currently used
- *
- * @see PropertySource
- */
- public ConfigurationBuilder addPropertySources(PropertySource... sources){
- checkBuilderState();
-
- contextBuilder.addPropertySources(Objects.requireNonNull(sources));
- return this;
- }
-
- private void checkBuilderState() {
- if (built) {
- throw new IllegalStateException("Configuration has already been build.");
- }
- }
-
- /**
- * Adds one or more property source provider instances to the configuration to be build.
- *
- * <pre>{@code PropertySourceProvider jc = new JavaConfigurationProvider();
- *
- * builder.addPropertySources(jc)};
- * </pre>
- *
- * @param providers list of property source provider instances each providing a set
- * of property source instances for the configuration to be build.
- *
- * @return the builder instance currently used
- *
- * @see PropertySourceProvider
- */
- public ConfigurationBuilder addPropertySourceProviders(PropertySourceProvider... providers){
- contextBuilder.addPropertySourceProviders(providers);
- return this;
- }
-
- /**
- * Adds one or more property filter instances to the configuration to be build.
- *
- * <pre>{@code PropertyFilter quoteReplacingFilter = new QuoteFilter();
- * PropertyFilter commaRemovingFilter = new CommaFilter();
- *
- * builder.addPropertyFilters(commaRemovingFilter, quoteReplacingFilter)};
- * </pre>
- *
- * @param filters list of property filter instances which should be applied
- * to the properties of the configuration to be build.
- *
- * @return the builder instance currently used
- *
- * @see PropertyFilter
- * @see #disableProvidedPropertyFilters()
- * @see #enabledProvidedPropertyFilters()
- */
- public ConfigurationBuilder addPropertyFilters(PropertyFilter... filters){
- Objects.requireNonNull(filters);
-
- contextBuilder.addPropertyFilters(filters);
- return this;
- }
-
-
- /**
- * @param propertyValueCombinationPolicy combination policy to use for this builder.
- * @return the builder instance currently in use.
- */
- public ConfigurationBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy propertyValueCombinationPolicy){
- contextBuilder.setPropertyValueCombinationPolicy(propertyValueCombinationPolicy);
- return this;
- }
-
- /**
- * Adds a property converter for the a given type to the configuration to
- * be build.
- *
- * <pre>{@code PropertyConverter<MyType> converter = value -> new MyType(value, 42);
- *
- * builder.addPropertyConverter(MyType.class, converter}
- * </pre>
- *
- * @param <T> the type of the configuration
- * @param type the required target type the converter should be applied to
- * @param converter the converter to be used to convert the string property
- * to the given target type.
- *
- * @return the builder instance currently used
- *
- * @see PropertyConverter
- * @see #enableProvidedPropertyConverters()
- * @see #disableProvidedPropertyConverters()
- */
- public <T> ConfigurationBuilder addPropertyConverter(Class<T> type, PropertyConverter<T> converter) {
- Objects.requireNonNull(type);
- Objects.requireNonNull(converter);
- return addPropertyConverter(TypeLiteral.of(type), (PropertyConverter<Object>)converter);
- }
-
- /**
- * Adds a propertyConverter of a given type.
- *
- * @param <T> the type of the configuration
- * @param type type literal of this converter.
- * @param propertyConverter property converter.
- * @return the builder instance currently used
- */
- public <T> ConfigurationBuilder addPropertyConverter(TypeLiteral<T> type, PropertyConverter<T> propertyConverter){
- Objects.requireNonNull(type);
- Objects.requireNonNull(propertyConverter);
- contextBuilder.addPropertyConverter(type, propertyConverter);
- return this;
- }
-
- /**
- * Checks if the automatic loading of all {@link PropertyConverter
- * PropertyConverter} service providers is enabled or disabled.
- *
- * @return {@code true} if the automatic loading is enabled,
- * otherwise {@code false}.
- *
- * @see #enableProvidedPropertyConverters()
- * @see #disableProvidedPropertyConverters()
- * @see #addPropertyConverter(Class, PropertyConverter)
- * @see #addPropertyConverter(org.apache.tamaya.TypeLiteral, PropertyConverter)
- */
- public boolean isPropertyConverterLoadingEnabled() {
- return loadProvidedPropertyConverters;
- }
-
- /**
- * Enables the loading of all {@link PropertyConverter}
- * service providers.
- *
- * @return the builder instance currently used
- *
- * @see PropertyConverter
- * @see #disableProvidedPropertyConverters()
- * @see #enableProvidedPropertyConverters()
- */
- public ConfigurationBuilder enableProvidedPropertyConverters() {
- checkBuilderState();
-
- loadProvidedPropertyConverters = true;
-
- return this;
- }
-
- /**
- * Disables the automatic loading of all {@link PropertyConverter}
- * service providers.
- *
- * @return the builder instance currently used
- *
- * @see PropertyConverter
- * @see #enableProvidedPropertyConverters()
- * @see #addPropertyConverter(Class, PropertyConverter)
- */
- public ConfigurationBuilder disableProvidedPropertyConverters() {
- checkBuilderState();
-
- loadProvidedPropertyConverters = false;
-
- return this;
- }
-
-
- /**
- * Enables the automatic loading of all {@link PropertySource}
- * service providers.
- *
- * @return the builder instance currently used
- *
- * @see PropertySource
- * @see #disableProvidedPropertySources()
- */
- public ConfigurationBuilder enableProvidedPropertySources() {
- checkBuilderState();
-
- loadProvidedPropertySources = true;
-
- return this;
- }
-
- /**
- * Checks if the automatic loading of all {@link PropertySource
- * PropertySource} service providers is enabled or disabled.
- *
- * @return {@code true} if the automatic loading is enabled,
- * otherwise {@code false}.
- */
- public boolean isPropertySourcesLoadingEnabled() {
- return loadProvidedPropertySources;
- }
-
-
- /**
- * Checks if the automatic loading of all {@link PropertyFilter
- * PropertyFilter} service providers is enabled or disabled.
- *
- * @return {@code true} if the automatic loading is enabled,
- * otherwise {@code false}.
- */
- public boolean isPropertyFilterLoadingEnabled() {
- return isLoadProvidedPropertyFilters;
- }
-
- /**
- * Enables the automatic loading of all {@link PropertyFilter}
- * service providers.
- *
- * @return the builder instance currently used
- *
- * @see PropertyFilter
- * @see #disableProvidedPropertyFilters()
- * @see #addPropertyFilters(PropertyFilter...)
- */
- public ConfigurationBuilder enabledProvidedPropertyFilters() {
- checkBuilderState();
-
- isLoadProvidedPropertyFilters = true;
-
- return this;
- }
-
- /**
- * Disables the automatic loading of all {@link PropertyFilter}
- * service providers.
- *
- * @see PropertyFilter
- * @see #enabledProvidedPropertyFilters()
- * @see #addPropertyFilters(PropertyFilter...)
- *
- * @return the builder instance currently used
- */
- public ConfigurationBuilder disableProvidedPropertyFilters() {
- checkBuilderState();
-
- isLoadProvidedPropertyFilters = false;
-
- return this;
- }
-
- /**
- * Disables the automatic loading of all {@link PropertySource}
- * service providers.
- *
- * @return the builder instance currently used
- *
- * @see PropertySource
- * @see #enableProvidedPropertySources()
- */
- public ConfigurationBuilder disableProvidedPropertySources() {
- checkBuilderState();
-
- loadProvidedPropertySources = false;
-
- return this;
- }
-
- /**
- * Enables the automatic loading of {@link PropertySourceProvider
- * property source providers} provided via the SPI API.
- *
- * @return the builder instance currently used
- *
- * @see PropertySourceProvider
- */
- public ConfigurationBuilder enableProvidedPropertySourceProviders() {
- checkBuilderState();
-
- loadProvidedPropertySourceProviders = true;
-
- return this;
- }
-
- /**
- * Disables the automatic loading of {@link PropertySourceProvider
- * property source providers} provided via the SPI API.
- *
- * @return the builder instance currently used
- */
- public ConfigurationBuilder disableProvidedPropertySourceProviders() {
- checkBuilderState();
-
- loadProvidedPropertySourceProviders = false;
-
- return this;
- }
-
- /**
- * Checks if the automatic loading of {@link PropertySourceProvider
- * PropertySourceProviders} is enabled or disabled.
- *
- * @return {@code true} if the automatic loading is enabled,
- * otherwise {@code false}.
- */
- public boolean isPropertySourceProvidersLoadingEnabled() {
- return loadProvidedPropertySourceProviders;
- }
-
- //X TODO think on a functionality/API for using the default PropertyConverters and use the configured ones here
- //X TODO as overrides used first.
-
-
- /**
- * Builds a new configuration based on the configuration of this builder instance.
- *
- * @return a new {@link org.apache.tamaya.Configuration configuration instance},
- * never {@code null}.
- */
- public Configuration build() {
- checkBuilderState();
-
- built = true;
-
- contextBuilder.loadProvidedPropertyConverters(isPropertyConverterLoadingEnabled());
- contextBuilder.loadProvidedPropertySources(isPropertySourcesLoadingEnabled());
- contextBuilder.loadProvidedPropertySourceProviders(isPropertySourceProvidersLoadingEnabled());
- contextBuilder.loadProvidedPropertyFilters(isLoadProvidedPropertyFilters);
-
- return new DefaultConfiguration(contextBuilder.build());
- }
-
- /**
- * Mapper to map a URL given as string to an URL instance.
- */
- private static class StringToURLMapper {
- public URL apply(String u) {
- try {
- return new URL(u);
- } catch (MalformedURLException e) {
- throw new ConfigException(u + " is not a valid URL", e);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/main/java/org/apache/tamaya/builder/DefaultPropertySourceBasedConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/main/java/org/apache/tamaya/builder/DefaultPropertySourceBasedConfiguration.java b/modules/builder/src/main/java/org/apache/tamaya/builder/DefaultPropertySourceBasedConfiguration.java
new file mode 100644
index 0000000..a459a4c
--- /dev/null
+++ b/modules/builder/src/main/java/org/apache/tamaya/builder/DefaultPropertySourceBasedConfiguration.java
@@ -0,0 +1,306 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.builder;
+
+import org.apache.tamaya.builder.internal.PropertyFiltering;
+import org.apache.tamaya.builder.spi.PropertyFilter;
+import org.apache.tamaya.builder.spi.PropertySource;
+import org.apache.tamaya.builder.spi.PropertySourceProvider;
+import org.apache.tamaya.builder.spi.PropertyValueCombinationPolicy;
+import org.apache.tamaya.servicecontext.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.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Default Implementation of a simple ConfigurationContext.
+ */
+class DefaultPropertySourceBasedConfiguration implements PropertySourceBasedConfiguration {
+ /** The logger used. */
+ private final static Logger LOG = Logger.getLogger(DefaultPropertySourceBasedConfiguration.class.getName());
+
+ /**
+ * 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 DefaultPropertySourceBasedConfiguration() {
+ 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);
+ }
+
+ DefaultPropertySourceBasedConfiguration(PropertySourceBasedConfigurationBuilder builder) {
+ List<PropertySource> propertySources = new ArrayList<>();
+ // first we load all PropertySources which got registered via java.util.ServiceLoader
+ propertySources.addAll(builder.propertySources.values());
+ // 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 = builder.combinationPolicy;
+ if(propertyValueCombinationPolicy==null){
+ propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().getService(PropertyValueCombinationPolicy.class);
+ }
+ if(propertyValueCombinationPolicy==null){
+ propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+ }
+ LOG.info("Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
+ }
+
+ @Override
+ public String get(String key) {
+ Map<String,String> value = evaluteRawValue(key);
+ if(value==null || value.get(key)==null){
+ return null;
+ }
+ return PropertyFiltering.applyFilter(key, value, this);
+ }
+
+ /**
+ * Get the current properties, composed by the loaded {@link PropertySource} and filtered
+ * by registered {@link PropertyFilter}.
+ *
+ * @return the final properties.
+ */
+ @Override
+ public Map<String, String> getProperties() {
+ return PropertyFiltering.applyFilters(evaluateUnfilteredMap(), this);
+ }
+
+ protected Map<String, String> evaluateUnfilteredMap() {
+ List<PropertySource> propertySources = new ArrayList<>(getPropertySources());
+ Collections.reverse(propertySources);
+ Map<String, String> result = new HashMap<>();
+ for (PropertySource propertySource : propertySources) {
+ try {
+ int origSize = result.size();
+ Map<String, String> otherMap = propertySource.getProperties();
+ LOG.log(Level.FINEST, null, "Overriding with properties from " + propertySource.getName());
+ result.putAll(otherMap);
+ LOG.log(Level.FINEST, null, "Handled properties from " + propertySource.getName() + "(new: " +
+ (result.size() - origSize) + ", overrides: " + origSize + ", total: " + result.size());
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE, "Error adding properties from PropertySource: " + propertySource + ", ignoring PropertySource.", e);
+ }
+ }
+ return result;
+ }
+
+ protected Map<String,String> evaluteRawValue(String key) {
+ List<PropertySource> propertySources = getPropertySources();
+ Map<String,String> unfilteredValue = null;
+ PropertyValueCombinationPolicy combinationPolicy = getPropertyValueCombinationPolicy();
+ for (PropertySource propertySource : propertySources) {
+ unfilteredValue = combinationPolicy.collect(unfilteredValue, key, propertySource);
+ }
+ return unfilteredValue;
+ }
+
+ /**
+ * 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();
+ }
+ }
+
+ 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);
+ }
+ }
+
+ 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 List<PropertyFilter> getPropertyFilters() {
+ return immutablePropertyFilters;
+ }
+
+ @Override
+ public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(){
+ return propertyValueCombinationPolicy;
+ }
+
+ @Override
+ public PropertySourceBasedConfigurationBuilder toBuilder() {
+ return new PropertySourceBasedConfigurationBuilder()
+ .setConfiguration(this);
+ }
+
+}
[3/7] incubator-tamaya git commit: - Minimalized API. - Propagated
change to rest of modules.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/package-info.java
----------------------------------------------------------------------
diff --git a/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/package-info.java b/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/package-info.java
new file mode 100644
index 0000000..7edba91
--- /dev/null
+++ b/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/package-info.java
@@ -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.
+ */
+/**
+ * This package provides an decorator for {@link org.apache.tamaya.defaults.ConfigurationWithDefaults}
+ * that allows additionally to pass default values either as Strings or typed
+ * objects.
+ *
+ * @see org.apache.tamaya.defaults.ConfigurationWithDefaults
+ */
+package org.apache.tamaya.defaults;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/defaultconfig/src/main/resources/META-INF/services/org.apache.tamaya.adapter.spi.ConfigurationAdapter
----------------------------------------------------------------------
diff --git a/modules/defaultconfig/src/main/resources/META-INF/services/org.apache.tamaya.adapter.spi.ConfigurationAdapter b/modules/defaultconfig/src/main/resources/META-INF/services/org.apache.tamaya.adapter.spi.ConfigurationAdapter
new file mode 100644
index 0000000..56fc494
--- /dev/null
+++ b/modules/defaultconfig/src/main/resources/META-INF/services/org.apache.tamaya.adapter.spi.ConfigurationAdapter
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the 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.
+org.apache.tamaya.defaults.internal.ConfigurationWithDefaultsAdapter
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/formats/pom.xml
----------------------------------------------------------------------
diff --git a/modules/formats/pom.xml b/modules/formats/pom.xml
index f85a9d4..96282f5 100644
--- a/modules/formats/pom.xml
+++ b/modules/formats/pom.xml
@@ -42,6 +42,11 @@ under the License.
</dependency>
<dependency>
<groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-builder</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
<artifactId>tamaya-resources</artifactId>
<version>${project.version}</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/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
index 9d2097f..a1d510a 100644
--- a/modules/formats/src/main/java/org/apache/tamaya/format/FlattenedDefaultPropertySource.java
+++ b/modules/formats/src/main/java/org/apache/tamaya/format/FlattenedDefaultPropertySource.java
@@ -18,8 +18,8 @@
*/
package org.apache.tamaya.format;
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.builder.spi.PropertySource;
+import org.apache.tamaya.builder.spi.PropertyValue;
import java.util.Collections;
import java.util.HashMap;
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/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
index de770db..c31f946 100644
--- 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
@@ -20,7 +20,7 @@ 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.builder.PropertySourceBasedConfigurationBuilder;
import org.apache.tamaya.inject.api.ConfiguredItemSupplier;
import org.apache.tamaya.inject.api.DynamicValue;
import org.apache.tamaya.inject.api.Config;
@@ -66,7 +66,7 @@ public class DefaultDynamicValueTest {
};
private Map<String,String> properties = new HashMap<>();
- private Configuration config = new ConfigurationBuilder().addPropertySources(
+ private Configuration config = new PropertySourceBasedConfigurationBuilder().addPropertySources(
new PropertySource() {
@Override
public int getOrdinal() {
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/pom.xml
----------------------------------------------------------------------
diff --git a/modules/pom.xml b/modules/pom.xml
index 43f75e5..e99b6eb 100644
--- a/modules/pom.xml
+++ b/modules/pom.xml
@@ -33,6 +33,10 @@ under the License.
<packaging>pom</packaging>
<modules>
+ <module>servicecontext</module>
+ <module>adaptersupport</module>
+ <module>types</module>
+ <module>defaultconfig</module>
<module>builder</module>
<module>classloader-support</module>
<module>collections</module>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/ServiceContext.java
----------------------------------------------------------------------
diff --git a/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/ServiceContext.java b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/ServiceContext.java
new file mode 100644
index 0000000..56dae8d
--- /dev/null
+++ b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/ServiceContext.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.servicecontext;
+
+import java.util.List;
+
+
+/**
+ * This class models the component that is managing the lifecycle current the
+ * services used by the Configuration API.
+ */
+public interface ServiceContext {
+
+ /**
+ * @return ordinal of the ServiceContext. The one with the highest ordinal will be taken.
+ */
+ int ordinal();
+
+ /**
+ * Access a service singleton via its type.
+ * If multiple implementations for the very serviceType exist then
+ * the one with the highest {@link javax.annotation.Priority} will be used.
+ *
+ * @param <T> the type of the service type.
+ * @param serviceType the service type.
+ * @return The instance to be used, or {@code null}
+ * @throws org.apache.tamaya.ConfigException if there are multiple service implementations with the maximum priority.
+ */
+ <T> T getService(Class<T> serviceType);
+
+ /**
+ * Access a list current services, given its type. The bootstrap mechanism should
+ * order the instance for precedence, hereby the most significant should be
+ * first in order.
+ *
+ * @param serviceType
+ * the service type.
+ * @param <T> the type of the list element returned by this method
+ * @return The instance to be used, never {@code null}
+ */
+ <T> List<T> getServices(Class<T> serviceType);
+
+ /**
+ * 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.
+ */
+ int getPriority(Object o);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/ServiceContextManager.java
----------------------------------------------------------------------
diff --git a/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/ServiceContextManager.java b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/ServiceContextManager.java
new file mode 100644
index 0000000..5749fc4
--- /dev/null
+++ b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/ServiceContextManager.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.servicecontext;
+
+import java.util.Objects;
+import java.util.ServiceLoader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * This singleton provides access to the services available in the current {@link ServiceContext}. The
+ * behaviour can be adapted, by calling {@link ServiceContextManager#set(ServiceContext)} before accessing any
+ * services.
+ */
+public final class ServiceContextManager {
+
+ /** The logger used. */
+ private static final Logger LOG = Logger.getLogger(ServiceContextManager.class.getName());
+
+ /**
+ * The ServiceProvider used.
+ */
+ private static volatile ServiceContext serviceContextProviderDelegate;
+
+ /**
+ * Private singletons constructor.
+ */
+ private ServiceContextManager() {
+ }
+
+ /**
+ * Load the {@link ServiceContext} to be used.
+ *
+ * @return {@link ServiceContext} to be used for loading the services.
+ */
+ private static ServiceContext loadDefaultServiceProvider() {
+ ServiceContext highestServiceContext = null;
+ try {
+ int highestOrdinal = 0;
+ for (ServiceContext serviceContext : ServiceLoader.load(ServiceContext.class)) {
+ if(highestServiceContext==null){
+ highestServiceContext = serviceContext;
+ }else if (serviceContext.ordinal() > highestOrdinal) {
+ highestServiceContext = serviceContext;
+ highestOrdinal = serviceContext.ordinal();
+ }
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException("ServiceContext not loadable", e);
+ }
+ if (highestServiceContext==null){
+ throw new IllegalStateException("No ServiceContext found");
+ }
+ LOG.info("Using Service Context of type: " + highestServiceContext.getClass().getName());
+ return highestServiceContext;
+ }
+
+ /**
+ * Replace the current {@link ServiceContext} in use.
+ *
+ * @param serviceContextProvider the new {@link ServiceContext}, not null.
+ * @return the currently used context after setting it.
+ */
+ public static ServiceContext set(ServiceContext serviceContextProvider) {
+ ServiceContext currentContext = ServiceContextManager.serviceContextProviderDelegate;
+ Objects.requireNonNull(serviceContextProvider);
+
+ synchronized (ServiceContextManager.class) {
+ if (ServiceContextManager.serviceContextProviderDelegate == null) {
+ ServiceContextManager.serviceContextProviderDelegate = serviceContextProvider;
+ LOG.log(Level.INFO, "Using ServiceProvider: " + serviceContextProvider.getClass().getName());
+ } else {
+ LOG.log(Level.WARNING, "Replacing ServiceProvider " +
+ ServiceContextManager.serviceContextProviderDelegate.getClass().getName() +
+ " with: " + serviceContextProvider.getClass().getName());
+ ServiceContextManager.serviceContextProviderDelegate = serviceContextProvider;
+ }
+ }
+
+ return currentContext;
+ }
+
+ /**
+ * Ge {@link ServiceContext}. If necessary the {@link ServiceContext} will be laziliy loaded.
+ *
+ * @return the {@link ServiceContext} used.
+ */
+ public static ServiceContext getServiceContext() {
+ if (serviceContextProviderDelegate == null) {
+ synchronized (ServiceContextManager.class) {
+ if (serviceContextProviderDelegate == null) {
+ serviceContextProviderDelegate = loadDefaultServiceProvider();
+ }
+ }
+ }
+ return serviceContextProviderDelegate;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/DefaultServiceContext.java
----------------------------------------------------------------------
diff --git a/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/DefaultServiceContext.java b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/DefaultServiceContext.java
new file mode 100644
index 0000000..3f2bfb7
--- /dev/null
+++ b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/DefaultServiceContext.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.servicecontext.internal;
+
+import org.apache.tamaya.servicecontext.ServiceContext;
+
+import javax.annotation.Priority;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class implements the (default) {@link org.apache.tamaya.servicecontext.ServiceContext} interface and hereby uses the JDK
+ * {@link java.util.ServiceLoader} to load the services required.
+ */
+public final class DefaultServiceContext 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(DefaultServiceContext.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 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 IllegalStateException 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 IllegalStateException(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/blob/7144e3f9/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIActivator.java
----------------------------------------------------------------------
diff --git a/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIActivator.java b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIActivator.java
new file mode 100644
index 0000000..3eac8b9
--- /dev/null
+++ b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIActivator.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.servicecontext.internal;
+
+import org.apache.tamaya.servicecontext.ServiceContextManager;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+import java.util.logging.Logger;
+
+/**
+ * A bundle activator that registers the {@link OSGIServiceLoader}.
+ */
+public class OSGIActivator implements BundleActivator {
+
+ private static final Logger LOG = Logger.getLogger(OSGIActivator.class.getName());
+
+ private OSGIServiceLoader serviceLoader;
+
+ @Override
+ public void start(BundleContext context) {
+ // Register marker service
+ ServiceContextManager.set(new OSGIServiceContext(context));
+ LOG.info("Registered OSGI enabled ServiceContext...");
+ serviceLoader = new OSGIServiceLoader();
+ context.addBundleListener(serviceLoader);
+ }
+
+ @Override
+ public void stop(BundleContext context) {
+ if(serviceLoader!=null) {
+ context.removeBundleListener(serviceLoader);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIServiceComparator.java
----------------------------------------------------------------------
diff --git a/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIServiceComparator.java b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIServiceComparator.java
new file mode 100644
index 0000000..87d6881
--- /dev/null
+++ b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIServiceComparator.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.servicecontext.internal;
+
+import org.osgi.framework.ServiceReference;
+
+import javax.annotation.Priority;
+import java.util.Comparator;
+
+/**
+ * Comparator implementation for odering services loaded based on their increasing priority values.
+ */
+class OSGIServiceComparator implements Comparator<ServiceReference> {
+
+ @Override
+ public int compare(ServiceReference o1, ServiceReference o2) {
+ int prio = getPriority(o1) - getPriority(o2);
+ if (prio < 0) {
+ return 1;
+ } else if (prio > 0) {
+ return -1;
+ } else {
+ return 0; //o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
+ }
+ }
+
+ /**
+ * 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) {
+ return getPriority(o.getClass());
+ }
+
+ /**
+ * Checks the given type optionally annotated with a @Priority. If present the annotation's value s evaluated.
+ * If no such annotation is present, a default priority is returned (1);
+ *
+ * @param type the type, not null.
+ * @return a priority, by default 1.
+ */
+ public static int getPriority(Class type) {
+ int prio = 1;
+ Priority priority = (Priority)type.getAnnotation(Priority.class);
+ if (priority != null) {
+ prio = priority.value();
+ }
+ return prio;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIServiceContext.java
----------------------------------------------------------------------
diff --git a/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIServiceContext.java b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIServiceContext.java
new file mode 100644
index 0000000..7669361
--- /dev/null
+++ b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIServiceContext.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.servicecontext.internal;
+
+import org.apache.tamaya.servicecontext.ServiceContext;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+import javax.annotation.Priority;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * ServiceContext implementation based on OSGI Service mechanisms.
+ */
+public class OSGIServiceContext implements ServiceContext{
+
+ private static final OSGIServiceComparator REF_COMPARATOR = new OSGIServiceComparator();
+
+ private final BundleContext bundleContext;
+
+ public OSGIServiceContext(BundleContext bundleContext){
+ this.bundleContext = Objects.requireNonNull(bundleContext);
+ }
+
+ public boolean isInitialized(){
+ return bundleContext != null;
+ }
+
+
+ @Override
+ public int ordinal() {
+ return 10;
+ }
+
+ @Override
+ public <T> T getService(Class<T> serviceType) {
+ ServiceReference<T> ref = this.bundleContext.getServiceReference(serviceType);
+ if(ref!=null){
+ return this.bundleContext.getService(ref);
+ }
+ return null;
+ }
+
+ @Override
+ public <T> List<T> getServices(Class<T> serviceType) {
+ List<ServiceReference<T>> refs = new ArrayList<>();
+ try {
+ refs.addAll(this.bundleContext.getServiceReferences(serviceType, null));
+ Collections.sort(refs, REF_COMPARATOR);
+ List<T> services = new ArrayList<>(refs.size());
+ for(ServiceReference<T> ref:refs){
+ T service = bundleContext.getService(ref);
+ if(service!=null) {
+ services.add(service);
+ }
+ }
+ return services;
+ } catch (InvalidSyntaxException e) {
+ e.printStackTrace();
+ return Collections.emptyList();
+ }
+ }
+
+ /**
+ * 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 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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIServiceLoader.java
----------------------------------------------------------------------
diff --git a/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIServiceLoader.java b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIServiceLoader.java
new file mode 100644
index 0000000..dc43801
--- /dev/null
+++ b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/OSGIServiceLoader.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.servicecontext.internal;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * An bundle listener that registers services defined in META-INF/services, when a bundle is starting.
+ *
+ * @author anatole@apache.org
+ */
+public class OSGIServiceLoader implements BundleListener {
+ // Provide logging
+ private static final Logger log = Logger.getLogger(OSGIServiceLoader.class.getName());
+
+ private Map<Class, ServiceTracker<Object,Object>> services = new ConcurrentHashMap<>();
+
+ @Override
+ public void bundleChanged(BundleEvent bundleEvent) {
+ // Parse and create metadta on STARTING
+ if (bundleEvent.getType() == BundleEvent.STARTED) {
+ Bundle bundle = bundleEvent.getBundle();
+ if (bundle.getEntry("META-INF/services/") == null) {
+ return;
+ }
+ Enumeration<String> entryPaths = bundle.getEntryPaths("META-INF/services/");
+ while (entryPaths.hasMoreElements()) {
+ String entryPath = entryPaths.nextElement();
+ if(!entryPath.endsWith("/")) {
+ processEntryPath(bundle, entryPath);
+ }
+ }
+ }
+ }
+
+ private void processEntryPath(Bundle bundle, String entryPath) {
+ try {
+ String serviceName = entryPath.substring("META-INF/services/".length());
+ Class<?> serviceClass = bundle.loadClass(serviceName);
+
+ URL child = bundle.getEntry(entryPath);
+ InputStream inStream = child.openStream();
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));
+ String implClassName = br.readLine();
+ while (implClassName != null){
+ int hashIndex = implClassName.indexOf("#");
+ if (hashIndex > 0) {
+ implClassName = implClassName.substring(0, hashIndex-1);
+ }
+ else if (hashIndex == 0) {
+ implClassName = "";
+ }
+ implClassName = implClassName.trim();
+ if (implClassName.length() > 0) {
+ try {
+ // Load the service class
+ Class<?> implClass = bundle.loadClass(implClassName);
+ if (!serviceClass.isAssignableFrom(implClass)) {
+ log.warning("Configured service: " + implClassName + " is not assignble to " +
+ serviceClass.getName());
+ continue;
+ }
+ // Provide service properties
+ Hashtable<String, String> props = new Hashtable<>();
+ props.put(Constants.VERSION_ATTRIBUTE, bundle.getVersion().toString());
+ String vendor = bundle.getHeaders().get(Constants.BUNDLE_VENDOR);
+ props.put(Constants.SERVICE_VENDOR, (vendor != null ? vendor : "anonymous"));
+ // Translate annotated @Priority into a service ranking
+ props.put(Constants.SERVICE_RANKING,
+ String.valueOf(PriorityServiceComparator.getPriority(implClass)));
+
+ // Register the service factory on behalf of the intercepted bundle
+ JDKUtilServiceFactory factory = new JDKUtilServiceFactory(implClass);
+ BundleContext bundleContext = bundle.getBundleContext();
+ bundleContext.registerService(serviceName, factory, props);
+ }
+ catch(Exception e){
+ log.log(Level.SEVERE,
+ "Failed to load service class using ServiceLoader logic: " + implClassName, e);
+ }
+ }
+ implClassName = br.readLine();
+ }
+ br.close();
+ }
+ catch (RuntimeException rte) {
+ throw rte;
+ }
+ catch (Exception e) {
+ log.log(Level.SEVERE, "Failed to read services from: " + entryPath, e);
+ }
+ }
+
+
+ /**
+ * Service factory simply instantiating the configured service.
+ */
+ static class JDKUtilServiceFactory implements ServiceFactory
+ {
+ private final Class<?> serviceClass;
+
+ public JDKUtilServiceFactory(Class<?> serviceClass) {
+ this.serviceClass = serviceClass;
+ }
+
+ @Override
+ public Object getService(Bundle bundle, ServiceRegistration registration) {
+ try {
+ return serviceClass.newInstance();
+ }
+ catch (Exception ex) {
+ ex.printStackTrace();
+ throw new IllegalStateException("Cannot instanciate service", ex);
+ }
+ }
+
+ @Override
+ public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/PriorityServiceComparator.java
----------------------------------------------------------------------
diff --git a/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/PriorityServiceComparator.java b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/PriorityServiceComparator.java
new file mode 100644
index 0000000..3895cb0
--- /dev/null
+++ b/modules/servicecontext/src/main/java/org/apache/tamaya/servicecontext/internal/PriorityServiceComparator.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.servicecontext.internal;
+
+import javax.annotation.Priority;
+import java.util.Comparator;
+
+/**
+ * Comparator implementation for odering services loaded based on their increasing priority values.
+ */
+public class PriorityServiceComparator implements Comparator<Object> {
+
+ @Override
+ public int compare(Object o1, Object o2) {
+ int prio = getPriority(o1) - getPriority(o2);
+ if (prio < 0) {
+ return 1;
+ } else if (prio > 0) {
+ return -1;
+ } else {
+ return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
+ }
+ }
+
+ /**
+ * 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) {
+ return getPriority(o.getClass());
+ }
+
+ /**
+ * Checks the given type optionally annotated with a @Priority. If present the annotation's value s evaluated.
+ * If no such annotation is present, a default priority is returned (1);
+ *
+ * @param type the type, not null.
+ * @return a priority, by default 1.
+ */
+ public static int getPriority(Class type) {
+ int prio = 1;
+ Priority priority = (Priority)type.getAnnotation(Priority.class);
+ if (priority != null) {
+ prio = priority.value();
+ }
+ return prio;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/servicecontext/src/test/resources/services/org.apache.tamaya.servicecontext.internal.DefaultServiceContextTest$InvalidPriorityInterface
----------------------------------------------------------------------
diff --git a/modules/servicecontext/src/test/resources/services/org.apache.tamaya.servicecontext.internal.DefaultServiceContextTest$InvalidPriorityInterface b/modules/servicecontext/src/test/resources/services/org.apache.tamaya.servicecontext.internal.DefaultServiceContextTest$InvalidPriorityInterface
new file mode 100644
index 0000000..f203fa6
--- /dev/null
+++ b/modules/servicecontext/src/test/resources/services/org.apache.tamaya.servicecontext.internal.DefaultServiceContextTest$InvalidPriorityInterface
@@ -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.
+org.apache.tamaya.core.internal.DefaultServiceContextTest$InvalidPriorityImpl1
+org.apache.tamaya.core.internal.DefaultServiceContextTest$InvalidPriorityImpl2
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/servicecontext/src/test/resources/services/org.apache.tamaya.servicecontext.internal.DefaultServiceContextTest$MultiImplsInterface
----------------------------------------------------------------------
diff --git a/modules/servicecontext/src/test/resources/services/org.apache.tamaya.servicecontext.internal.DefaultServiceContextTest$MultiImplsInterface b/modules/servicecontext/src/test/resources/services/org.apache.tamaya.servicecontext.internal.DefaultServiceContextTest$MultiImplsInterface
new file mode 100644
index 0000000..b144790
--- /dev/null
+++ b/modules/servicecontext/src/test/resources/services/org.apache.tamaya.servicecontext.internal.DefaultServiceContextTest$MultiImplsInterface
@@ -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.
+
+org.apache.tamaya.core.internal.DefaultServiceContextTest$MultiImpl1
+org.apache.tamaya.core.internal.DefaultServiceContextTest$MultiImpl2
+org.apache.tamaya.core.internal.DefaultServiceContextTest$MultiImpl3
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/PriorityServiceComparator.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/PriorityServiceComparator.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/PriorityServiceComparator.java
new file mode 100644
index 0000000..c7e3656
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/PriorityServiceComparator.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.builder.internal;
+
+import javax.annotation.Priority;
+import java.util.Comparator;
+
+/**
+ * Comparator implementation for odering services loaded based on their increasing priority values.
+ */
+public class PriorityServiceComparator implements Comparator<Object> {
+
+ @Override
+ public int compare(Object o1, Object o2) {
+ int prio = getPriority(o1) - getPriority(o2);
+ if (prio < 0) {
+ return 1;
+ } else if (prio > 0) {
+ return -1;
+ } else {
+ return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
+ }
+ }
+
+ /**
+ * 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) {
+ return getPriority(o.getClass());
+ }
+
+ /**
+ * Checks the given type optionally annotated with a @Priority. If present the annotation's value s evaluated.
+ * If no such annotation is present, a default priority is returned (1);
+ *
+ * @param type the type, not null.
+ * @return a priority, by default 1.
+ */
+ public static int getPriority(Class type) {
+ int prio = 1;
+ Priority priority = (Priority)type.getAnnotation(Priority.class);
+ if (priority != null) {
+ prio = priority.value();
+ }
+ return prio;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/PropertyConverterManager.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/PropertyConverterManager.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/PropertyConverterManager.java
new file mode 100644
index 0000000..1fcfb22
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/PropertyConverterManager.java
@@ -0,0 +1,449 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.types.internal;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.servicecontext.ServiceContext;
+import org.apache.tamaya.servicecontext.ServiceContextManager;
+import org.apache.tamaya.types.TypeLiteral;
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+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.*;
+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;
+
+/**
+ * Manager that deals with {@link PropertyConverter} instances.
+ * This class is thread-safe.
+ */
+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) {
+ ServiceContext serviceContext = ServiceContextManager.getServiceContext();
+ int prio = serviceContext.getPriority(o1) - serviceContext.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() {
+ this(true);
+ }
+
+ public PropertyConverterManager(boolean init) {
+ if (init) {
+ 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) {
+ return converters.containsKey(targetType) || transitiveConverters.containsKey(targetType) || 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(org.apache.tamaya.types.TypeLiteral)
+ */
+ public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+ Lock readLock = lock.readLock();
+ try {
+ readLock.lock();
+ return new HashMap<>(this.converters);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * 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.
+ * 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>
+ * </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).
+ * @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();
+ addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList);
+ } finally {
+ readLock.unlock();
+ }
+ // transitive converter
+ try {
+ readLock.lock();
+ addConvertersToList(List.class.cast(this.transitiveConverters.get(targetType)), converterList);
+ } finally {
+ readLock.unlock();
+ }
+ // handling of java.lang wrapper classes
+ TypeLiteral<T> boxedType = mapBoxedType(targetType);
+ if (boxedType != null) {
+ try {
+ readLock.lock();
+ addConvertersToList(List.class.cast(this.converters.get(boxedType)), converterList);
+ } finally {
+ readLock.unlock();
+ }
+ }
+ 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();
+ addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList);
+ } finally {
+ readLock.unlock();
+ }
+ }
+ }
+ // 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.
+ *
+ * @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 org.apache.tamaya.types.internal.converters.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 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) {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ constr.setAccessible(true);
+ return null;
+ }
+ });
+ return null;
+ }
+ });
+ try {
+ return constr.newInstance(value);
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE, "Error creating new PropertyConverter instance " + targetType, e);
+ }
+ return null;
+ }
+ };
+ }
+ 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;
+ }
+
+ 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/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/ReflectionUtil.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/ReflectionUtil.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/ReflectionUtil.java
new file mode 100644
index 0000000..da8a74c
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/ReflectionUtil.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.builder.internal;
+//
+//import java.lang.reflect.ParameterizedType;
+//import java.lang.reflect.Type;
+//
+//
+///**
+// * Small utility class used by other parts.
+// */
+//public final class ReflectionUtil {
+//
+// private ReflectionUtil(){}
+//
+// public static ParameterizedType getParametrizedType(Class<?> clazz) {
+// Type[] genericTypes = clazz.getGenericInterfaces();
+// for (Type type : genericTypes) {
+// if (type instanceof ParameterizedType) {
+// return (ParameterizedType) type;
+// }
+//
+// }
+// return null;
+// }
+//}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/adapters/DefaultTypedConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/adapters/DefaultTypedConfiguration.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/adapters/DefaultTypedConfiguration.java
new file mode 100644
index 0000000..8f919e1
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/adapters/DefaultTypedConfiguration.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.types.internal.adapters;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.types.TypeLiteral;
+import org.apache.tamaya.types.TypedConfiguration;
+import org.apache.tamaya.types.internal.PropertyConverterManager;
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of the {@link TypedConfiguration} API.
+ */
+public class DefaultTypedConfiguration implements TypedConfiguration {
+ /**
+ * The logger.
+ */
+ private static final Logger LOG = Logger.getLogger(DefaultTypedConfiguration.class.getName());
+
+ private Configuration configuration;
+
+ private PropertyConverterManager propertyConverterManager = new PropertyConverterManager();
+
+ /**
+ * Constructor.
+ * @param configuration The configuration to be decorated.
+ */
+ public DefaultTypedConfiguration(Configuration configuration){
+ this.configuration = Objects.requireNonNull(configuration);
+ }
+
+ private Configuration getConfig(){
+ return this.configuration!=null?this.configuration:ConfigurationProvider.getConfiguration();
+ }
+
+ @Override
+ public String get(String key) {
+ return getConfig().get(key);
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return getConfig().getProperties();
+ }
+
+ /**
+ * Accesses the current String value for the given key and tries to convert it
+ * using the {@link org.apache.tamaya.types.spi.PropertyConverter} instances provided by
+ * the current context.
+ *
+ * @param key the property's absolute, or relative path, e.g. @code
+ * a/b/c/d.myProperty}.
+ * @param type The target type required, not null.
+ * @param <T> the value type
+ * @return the converted value, never null.
+ */
+ @Override
+ public <T> T get(String key, Class<T> type) {
+ return get(key, (TypeLiteral<T>)TypeLiteral.of(type));
+ }
+
+ /**
+ * Accesses the current String value for the given key and tries to convert it
+ * using the {@link org.apache.tamaya.types.spi.PropertyConverter} instances provided by the current
+ * context.
+ *
+ * @param key the property's absolute, or relative path, e.g. @code
+ * a/b/c/d.myProperty}.
+ * @param type The target type required, not null.
+ * @param <T> the value type
+ * @return the converted value, never null.
+ */
+ @Override
+ public <T> T get(String key, TypeLiteral<T> type) {
+ return convertValue(key, get(key), type);
+ }
+
+ @Override
+ public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+ this.propertyConverterManager.register(typeToConvert, propertyConverter);
+ }
+
+ @Override
+ public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+ return this.propertyConverterManager.getPropertyConverters();
+ }
+
+ @Override
+ public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> type) {
+ return this.propertyConverterManager.getPropertyConverters(type);
+ }
+
+ @Override
+ public void removePropertyConverters(TypeLiteral<?> typeToConvert, PropertyConverter<?>... converters) {
+ removePropertyConverters(typeToConvert, Arrays.asList(converters));
+ }
+
+ @Override
+ public void removePropertyConverters(TypeLiteral<?> typeToConvert, Collection<PropertyConverter<?>> converters) {
+ List<? extends PropertyConverter<?>> existing = this.propertyConverterManager.getPropertyConverters(typeToConvert);
+ if(existing!=null) {
+ existing.removeAll(converters);
+ }
+ }
+
+
+ protected <T> T convertValue(String key, String value, TypeLiteral<T> type) {
+ if (value != null) {
+ List<PropertyConverter<T>> converters = propertyConverterManager.getPropertyConverters(type);
+ ConversionContext context = new ConversionContext.Builder(this, key, type).build();
+ for (PropertyConverter<T> converter : converters) {
+ try {
+ T t = converter.convert(value, context);
+ if (t != null) {
+ return t;
+ }
+ } catch (Exception e) {
+ LOG.log(Level.INFO, "PropertyConverter: " + converter + " failed to convert value: " + value, e);
+ }
+ }
+ throw new ConfigException("Unparseable config value for type: " + type.getRawType().getName() + ": " + key +
+ ", supported formats: " + context.getSupportedFormats());
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/BigDecimalConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/BigDecimalConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/BigDecimalConverter.java
new file mode 100644
index 0000000..27a997e
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/BigDecimalConverter.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.types.internal.converters;
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to BigDecimal, the supported format is one of the following:
+ * <ul>
+ * <li>232573527352.76352753</li>
+ * <li>-23257352.735276352753</li>
+ * <li>-0xFFFFFF (integral numbers only)</li>
+ * <li>-0XFFFFAC (integral numbers only)</li>
+ * <li>0xFFFFFF (integral numbers only)</li>
+ * <li>0XFFFFAC (integral numbers only)</li>
+ * </ul>
+ */
+public class BigDecimalConverter implements PropertyConverter<BigDecimal> {
+ /** The logger. */
+ private static final Logger LOG = Logger.getLogger(BigDecimalConverter.class.getName());
+ /** Converter to be used if the format is not directly supported by BigDecimal, e.g. for integral hex values. */
+ private final BigIntegerConverter integerConverter = new BigIntegerConverter();
+
+ @Override
+ public BigDecimal convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(), "<bigDecimal> -> new BigDecimal(String)");
+
+ String trimmed = Objects.requireNonNull(value).trim();
+ try{
+ return new BigDecimal(trimmed);
+ } catch(Exception e){
+ LOG.finest("Parsing BigDecimal failed, trying BigInteger for: " + value);
+ BigInteger bigInt = integerConverter.convert(value, context);
+ if(bigInt!=null){
+ return new BigDecimal(bigInt);
+ }
+ LOG.finest("Failed to parse BigDecimal from: " + value);
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/BigIntegerConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/BigIntegerConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/BigIntegerConverter.java
new file mode 100644
index 0000000..f7941cf
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/BigIntegerConverter.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.types.internal.converters;
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.math.BigInteger;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to BigInteger, the supported format is one of the following:
+ * <ul>
+ * <li>0xFFFFFF</li>
+ * <li>0XFFFFAC</li>
+ * <li>23257352735276352753</li>
+ * <li>-0xFFFFFF</li>
+ * <li>-0XFFFFAC</li>
+ * <li>-23257352735276352753</li>
+ * </ul>
+ */
+public class BigIntegerConverter implements PropertyConverter<BigInteger> {
+
+ /** The logger. */
+ private static final Logger LOG = Logger.getLogger(BigIntegerConverter.class.getName());
+ /** Converter used to decode hex, octal values. */
+ private final ByteConverter byteConverter = new ByteConverter();
+
+ @Override
+ public BigInteger convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(), "[-]0X.. (hex)", "[-]0x... (hex)", "<bigint> -> new BigInteger(bigint)");
+ String trimmed = Objects.requireNonNull(value).trim();
+ if(trimmed.startsWith("0x") || trimmed.startsWith("0X")){
+ LOG.finest("Parsing Hex value to BigInteger: " + value);
+ trimmed = trimmed.substring(2);
+ StringBuilder decimal = new StringBuilder();
+ for(int offset = 0;offset < trimmed.length();offset+=2){
+ if(offset==trimmed.length()-1){
+ LOG.finest("Invalid Hex-Byte-String: " + value);
+ return null;
+ }
+ byte val = byteConverter.convert("0x" + trimmed.substring(offset, offset + 2), context);
+ if(val<10){
+ decimal.append('0').append(val);
+ } else{
+ decimal.append(val);
+ }
+ }
+ return new BigInteger(decimal.toString());
+ } else if(trimmed.startsWith("-0x") || trimmed.startsWith("-0X")){
+ LOG.finest("Parsing Hex value to BigInteger: " + value);
+ trimmed = trimmed.substring(3);
+ StringBuilder decimal = new StringBuilder();
+ for(int offset = 0;offset < trimmed.length();offset+=2){
+ if(offset==trimmed.length()-1){
+ LOG.finest("Invalid Hex-Byte-String: " + trimmed);
+ return null;
+ }
+ byte val = byteConverter.convert("0x" + trimmed.substring(offset, offset + 2), context);
+ if(val<10){
+ decimal.append('0').append(val);
+ } else{
+ decimal.append(val);
+ }
+ }
+ return new BigInteger('-' + decimal.toString());
+ }
+ try{
+ return new BigInteger(trimmed);
+ } catch(Exception e){
+ LOG.log(Level.FINEST, "Failed to parse BigInteger from: " + value, e);
+ return null;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/BooleanConverter.java
----------------------------------------------------------------------
diff --git a/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/BooleanConverter.java b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/BooleanConverter.java
new file mode 100644
index 0000000..ed5dec3
--- /dev/null
+++ b/modules/types/src/main/java/org/apache/tamaya/types/internal/converters/BooleanConverter.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.types.internal.converters;
+
+import org.apache.tamaya.types.spi.ConversionContext;
+import org.apache.tamaya.types.spi.PropertyConverter;
+
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Boolean.
+ */
+public class BooleanConverter implements PropertyConverter<Boolean> {
+
+ private final Logger LOG = Logger.getLogger(getClass().getName());
+
+ @Override
+ public Boolean convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(), "yes (ignore case)", "y (ignore case)", "true (ignore case)", "t (ignore case)", "no (ignore case)", "n (ignore case)", "false (ignore case)", "f (ignore case)");
+ String ignoreCaseValue = Objects.requireNonNull(value)
+ .trim()
+ .toLowerCase(Locale.ENGLISH);
+ switch(ignoreCaseValue) {
+ case "yes":
+ case "y":
+ case "true":
+ case "t":
+ return Boolean.TRUE;
+ case "no":
+ case "n":
+ case "false":
+ case "f":
+ return Boolean.FALSE;
+ default:
+ LOG.finest("Unknown boolean value encountered: " + value);
+ }
+ return null;
+ }
+}
[4/7] incubator-tamaya git commit: - Minimalized API. - Propagated
change to rest of modules.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/test/java/org/apache/tamaya/builder/ConfigurationBuilderTest.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/test/java/org/apache/tamaya/builder/ConfigurationBuilderTest.java b/modules/builder/src/test/java/org/apache/tamaya/builder/ConfigurationBuilderTest.java
deleted file mode 100644
index 54cab63..0000000
--- a/modules/builder/src/test/java/org/apache/tamaya/builder/ConfigurationBuilderTest.java
+++ /dev/null
@@ -1,908 +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.builder;
-
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.builder.spi.*;
-import org.apache.tamaya.builder.util.types.CustomTypeA;
-import org.apache.tamaya.builder.util.types.CustomTypeB;
-import org.apache.tamaya.builder.util.types.CustomTypeC;
-import org.apache.tamaya.spi.*;
-import org.hamcrest.CoreMatchers;
-import org.hamcrest.Matchers;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-
-import java.io.IOException;
-import java.net.URL;
-
-import static java.util.Arrays.asList;
-import static org.apache.tamaya.builder.util.mockito.NotMockedAnswer.NOT_MOCKED_ANSWER;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.CALLS_REAL_METHODS;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-
-public class ConfigurationBuilderTest {
-
- @Test
- public void buildCanBuildEmptyConfiguration() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.build();
-
- assertThat(config, notNullValue());
- }
-
- @Test(expected = IllegalStateException.class)
- public void buildCanBeCalledOnlyOnce() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.build();
- builder.build();
- }
-
- /*********************************************************************
- * Tests for adding P r o p e r t y S o u r c e s
- */
-
- @Test(expected = NullPointerException.class)
- public void addPropertySourcesDoesNotAcceptNullValue() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.addPropertySources((PropertySource[])null);
- }
-
- @Test(expected = IllegalStateException.class)
- public void propertySourceCanNotBeAddedAfterBuildingTheConfiguration() {
- PropertySource first = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("first").when(first).getName();
- doReturn(100).when(first).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder().addPropertySources(first);
-
- builder.build();
-
- PropertySource second = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("second").when(first).getName();
-
- builder.addPropertySources(second);
- }
-
- @Test
- public void singleAddedPropertySourceIsUsed() {
- PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("one").when(source).getName();
- doReturn(PropertyValue.of("keyOfA","a", "test")).when(source).get("keyOfA");
- doReturn(100).when(source).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder().addPropertySources(source);
-
- Configuration config = builder.build();
-
- String valueOfA = config.get("keyOfA");
-
- assertThat(valueOfA, notNullValue());
- assertThat(valueOfA, equalTo("a"));
- }
-
- @Test
- public void twoAddedPropertySourcesAreUsed() {
- PropertySource sourceOne = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("one").when(sourceOne).getName();
- doReturn(PropertyValue.of("keyOfA","b", "test")).when(sourceOne).get("keyOfA");
- doReturn(10).when(sourceOne).getOrdinal();
-
- PropertySource sourceTwo = mock(PropertySource.class, NOT_MOCKED_ANSWER);
- doReturn("two").when(sourceTwo).getName();
- doReturn(PropertyValue.of("keyOfA","a", "test")).when(sourceTwo).get("keyOfA");
- doReturn(10).when(sourceTwo).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder().addPropertySources(sourceOne)
- .addPropertySources(sourceTwo);
-
- Configuration config = builder.build();
-
- String valueOfA = config.get("keyOfA");
-
- assertThat(valueOfA, notNullValue());
- assertThat(valueOfA, equalTo("a"));
- }
-
- @Ignore
- @Test(expected = ConfigException.class)
- public void twoPropertySourcesSamePrioritySameKey() {
- PropertySource sourceOne = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("one").when(sourceOne).getName();
- doReturn("b").when(sourceOne).get("keyOfA");
- doReturn(20).when(sourceOne).getOrdinal();
-
- PropertySource sourceTwo = mock(PropertySource.class, NOT_MOCKED_ANSWER);
- doReturn("two").when(sourceTwo).getName();
- doReturn("a").when(sourceTwo).get("keyOfA");
- doReturn(20).when(sourceTwo).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder().addPropertySources(sourceOne)
- .addPropertySources(sourceTwo);
-
- Configuration config = builder.build();
-
- config.get("keyOfA");
- }
-
- @Test
- public void twoPropertySourcesDiffPrioritySameKeyLowerAddedFirst() {
- PropertySource sourceOne = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("one").when(sourceOne).getName();
- doReturn(PropertyValue.of("keyOfA","b", "test")).when(sourceOne).get("keyOfA");
- doReturn(10).when(sourceOne).getOrdinal();
-
- PropertySource sourceTwo = mock(PropertySource.class, NOT_MOCKED_ANSWER);
- doReturn("two").when(sourceTwo).getName();
- doReturn(PropertyValue.of("keyOfA","a", "test")).when(sourceTwo).get("keyOfA");
- doReturn(20).when(sourceTwo).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder().addPropertySources(sourceOne)
- .addPropertySources(sourceTwo);
-
- Configuration config = builder.build();
-
- String valueOfA = config.get("keyOfA");
-
- assertThat(valueOfA, notNullValue());
- assertThat(valueOfA, equalTo("a"));
- }
-
- @Test
- public void twoPropertySourcesDiffPrioritySameKeyHigherAddedFirst() {
- PropertySource sourceOne = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("one").when(sourceOne).getName();
- doReturn(PropertyValue.of("keyOfA","b", "test")).when(sourceOne).get("keyOfA");
- doReturn(30).when(sourceOne).getOrdinal();
-
- PropertySource sourceTwo = mock(PropertySource.class, NOT_MOCKED_ANSWER);
- doReturn("two").when(sourceTwo).getName();
- doReturn(PropertyValue.of("keyOfA","a", "test")).when(sourceTwo).get("keyOfA");
- doReturn(20).when(sourceTwo).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder().addPropertySources(sourceOne, sourceTwo);
-
- Configuration config = builder.build();
-
- String valueOfA = config.get("keyOfA");
-
- assertThat(valueOfA, notNullValue());
- assertThat(valueOfA, equalTo("b"));
- }
-
- @Test
- public void consecutiveCallsToAddPropertySourceArePossible() {
- PropertySource sourceOne = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("one").when(sourceOne).getName();
- doReturn(null).when(sourceOne).get(anyString());
- doReturn(PropertyValue.of("b","b", "test")).when(sourceOne).get("b");
- doReturn(30).when(sourceOne).getOrdinal();
-
- PropertySource sourceTwo = mock(PropertySource.class, NOT_MOCKED_ANSWER);
- doReturn("two").when(sourceTwo).getName();
- doReturn(null).when(sourceTwo).get(anyString());
- doReturn(PropertyValue.of("a","a", "test")).when(sourceTwo).get("a");
- doReturn(30).when(sourceTwo).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder().addPropertySources(sourceOne)
- .addPropertySources(sourceTwo);
-
- Configuration config = builder.build();
-
- assertThat(config.get("b"), equalTo("b"));
- assertThat(config.get("a"), equalTo("a"));
- }
-
- @Test
- public void addMultiplePropertySourcesWhereOneIsNull() {
- PropertySource sourceOne = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("one").when(sourceOne).getName();
- doReturn(null).when(sourceOne).get(anyString());
- doReturn(PropertyValue.of("b","b", "test")).when(sourceOne).get("b");
- doReturn(30).when(sourceOne).getOrdinal();
-
- PropertySource sourceTwo = mock(PropertySource.class, NOT_MOCKED_ANSWER);
- doReturn("two").when(sourceTwo).getName();
- doReturn(null).when(sourceTwo).get(anyString());
- doReturn(PropertyValue.of("a","a", "test")).when(sourceTwo).get("a");
- doReturn(30).when(sourceTwo).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder().addPropertySources(sourceOne, null, sourceTwo);
-
- Configuration config = builder.build();
-
- assertThat(config.get("b"), equalTo("b"));
- assertThat(config.get("a"), equalTo("a"));
- }
-
- /**
- * ******************************************************************
- * Tests for adding P r o p e r t y C o n v e r t e r
- */
-
- @Test(expected = NullPointerException.class)
- public void canNotAddNullPropertyConverter() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.addPropertyConverter(TypeLiteral.of(CustomTypeA.class), null);
- }
-
- @Test(expected = NullPointerException.class)
- public void canNotAddNullTypeLiteralButPropertyConverter() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
- builder.addPropertyConverter((TypeLiteral)null,
- new PropertyConverter() {
- @Override
- public CustomTypeA convert(final String prop, ConversionContext context) {
- return new CustomTypeA(prop, prop);
- }
- });
- }
-
- @Test
- public void addedPropertyConverterWithTypeLiteralIsUsedByConfiguration() {
- PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("source").when(source).getName();
- doReturn(PropertyValue.of("key","A", "test")).when(source).get("key");
- doReturn(100).when(source).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.addPropertyConverter(TypeLiteral.of(CustomTypeA.class),
- new PropertyConverter() {
- @Override
- public CustomTypeA convert(final String prop, ConversionContext context) {
- return new CustomTypeA(prop, prop);
- }
- });
- builder.addPropertySources(source);
-
- Configuration config = builder.build();
-
- Object resultRaw = config.get("key", CustomTypeA.class);
-
- assertThat(resultRaw, CoreMatchers.notNullValue());
-
- CustomTypeA result = (CustomTypeA)resultRaw;
-
- assertThat(result.getName(), equalTo("AA"));
- }
-
- @Test
- public void addedPropertyConverterWithClassIsUsedByConfiguration() {
- PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("source").when(source).getName();
- doReturn(PropertyValue.of("key","A", "test")).when(source).get("key");
- doReturn(100).when(source).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.addPropertyConverter(TypeLiteral.of(CustomTypeA.class),
- new PropertyConverter() {
- @Override
- public CustomTypeA convert(final String prop, ConversionContext context) {
- return new CustomTypeA(prop, prop);
- }
- });
- builder.addPropertySources(source);
-
- Configuration config = builder.build();
-
- Object resultRaw = config.get("key", CustomTypeA.class);
-
- assertThat(resultRaw, CoreMatchers.notNullValue());
-
- CustomTypeA result = (CustomTypeA)resultRaw;
-
- assertThat(result.getName(), equalTo("AA"));
- }
-
- @Test
- public void canGetAndConvertPropertyViaOfMethod() {
- PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("source").when(source).getName();
- doReturn(PropertyValue.of("key","A", "test")).when(source).get("key");
- doReturn(100).when(source).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.addPropertySources(source);
-
- Configuration config = builder.build();
-
- Object resultRaw = config.get("key", CustomTypeB.class);
-
- assertThat(resultRaw, CoreMatchers.notNullValue());
-
- CustomTypeB result = (CustomTypeB)resultRaw;
-
- assertThat(result.getName(), equalTo("A"));
- }
-
- /*********************************************************************
- * Tests for adding P r o p e r t y F i l t e r
- */
-
- @Test(expected = NullPointerException.class)
- public void canNotAddNullAsPropertyFilter() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
- builder.addPropertyFilters((PropertyFilter[])null);
- }
-
- @Test
- public void canAddNonSPIPropertyFilter() {
- PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn(PropertyValue.of("key","M", "test")).when(source).get("key");
- doReturn("source").when(source).getName();
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.addPropertySources(source)
- .addPropertyFilters(new TestANonSPIPropertyFilter())
- .build();
-
- String property = config.get("key");
-
- assertThat(property, CoreMatchers.notNullValue());
- assertThat(property, CoreMatchers.containsString("ABC"));
- }
-
- @Test
- public void canAddNonSPIPropertyFiltersViaConsecutiveCalls() {
- PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn(PropertyValue.of("key","M", "test")).when(source).get("key");
- doReturn("source").when(source).getName();
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.addPropertySources(source)
- .addPropertyFilters(new TestANonSPIPropertyFilter())
- .addPropertyFilters(new TestBNonSPIPropertyFilter())
- .build();
-
- String property = config.get("key");
-
- assertThat(property, CoreMatchers.notNullValue());
- assertThat(property, CoreMatchers.containsString("ABC"));
- assertThat(property, CoreMatchers.containsString("XYZ"));
- }
-
- @Test
- public void canAddMultipleNonSPIPropertyFiltersWhileOneIsNull() {
- PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn(PropertyValue.of("key","M", "test")).when(source).get("key");
- doReturn("source").when(source).getName();
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.addPropertySources(source)
- .addPropertyFilters(new TestANonSPIPropertyFilter(),
- null,
- new TestBNonSPIPropertyFilter())
- .build();
-
- String property = config.get("key");
-
- assertThat(property, CoreMatchers.notNullValue());
- assertThat(property, CoreMatchers.containsString("ABC"));
- assertThat(property, CoreMatchers.containsString("XYZ"));
- }
-
- @Test
- public void overhandedNullPropertyFilterIsSafelyHandled() {
- PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn(PropertyValue.of("key","M", "test")).when(source).get("key");
- doReturn("source").when(source).getName();
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.addPropertySources(source)
- .addPropertyFilters((PropertyFilter)null) // The cast is needed!
- .addPropertyFilters(new TestBNonSPIPropertyFilter())
- .build();
-
- String property = config.get("key");
-
- assertThat(property, CoreMatchers.notNullValue());
- assertThat(property, CoreMatchers.containsString("XYZ"));
- }
-
- @Test
- public void canAddMultipleNonSPIPropertyFilter() {
- PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn(PropertyValue.of("key","M", "test")).when(source).get("key");
- doReturn("source").when(source).getName();
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.addPropertySources(source)
- .addPropertyFilters(new TestANonSPIPropertyFilter(),
- new TestBNonSPIPropertyFilter())
- .build();
-
- String property = config.get("key");
-
- assertThat(property, CoreMatchers.notNullValue());
- assertThat(property, CoreMatchers.containsString("ABC"));
- assertThat(property, CoreMatchers.containsString("XYZ"));
- }
-
- /*********************************************************************
- * Tests for adding
- * P r o p e r t y S o u r c e P r o v i d e r s
- */
-
- @Test
- public void handlesSafelyPropertyProviderReturningNullInsteadOfPropertySource() {
- PropertySourceProvider nullReturning = mock(PropertySourceProvider.class, NOT_MOCKED_ANSWER);
-
- doReturn(asList((PropertySource)null)).when(nullReturning).getPropertySources();
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.addPropertySourceProviders(new TestPropertySourceProviderB(),
- nullReturning,
- new TestPropertySourceProvider())
- .build();
-
- assertThat(config.get("tpsp_a"), Matchers.equalTo("A"));
- assertThat(config.get("tpsp_b"), Matchers.equalTo("B"));
- assertThat(config.get("tpsp_x"), Matchers.equalTo("X"));
- assertThat(config.get("tpsp_y"), Matchers.equalTo("Y"));
-
- verify(nullReturning).getPropertySources();
- }
-
- @Test(expected = NullPointerException.class)
- public void cannotAddNullAsPropertyProvider() {
- new ConfigurationBuilder().addPropertySourceProviders((PropertySourceProvider[])null);
- }
-
- @Test
- public void canAddMultipleNonSPIPropertySourceProviders() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.addPropertySourceProviders(new TestPropertySourceProviderB(),
- new TestPropertySourceProvider())
- .build();
-
- assertThat(config.get("tpsp_a"), Matchers.equalTo("A"));
- assertThat(config.get("tpsp_b"), Matchers.equalTo("B"));
- assertThat(config.get("tpsp_x"), Matchers.equalTo("X"));
- assertThat(config.get("tpsp_y"), Matchers.equalTo("Y"));
- }
-
- @Test
- public void canAddMultipleNonSPIPropertySourceProvidersWhileOfOfThemIsNull() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.addPropertySourceProviders(new TestPropertySourceProviderB(), null,
- new TestPropertySourceProvider())
- .build();
-
- assertThat(config.get("tpsp_a"), Matchers.equalTo("A"));
- assertThat(config.get("tpsp_b"), Matchers.equalTo("B"));
- assertThat(config.get("tpsp_x"), Matchers.equalTo("X"));
- assertThat(config.get("tpsp_y"), Matchers.equalTo("Y"));
- }
-
-
- /*
- * Tests for adding
- * P r o p e r t y V a l u e C o m b i n a t i o n P o l i c y
- */
-
- // @todo TAYAMA-60 Write more tests
-
- /*********************************************************************
- * Tests for enabling and disabling of automatic loading of
- * P r o p e r t y S o u r c e s
- */
-
- @Test
- public void enablingOfProvidedPropertySourceServiceProvidersIsOk() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.disableProvidedPropertyConverters()
- .enableProvidedPropertyConverters();
-
- assertThat(builder.isPropertyConverterLoadingEnabled(), is(true));
- }
-
- @Test
- public void disablingOfProvidedPropertySourceServiceProvidersIsOk() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.enableProvidedPropertyConverters()
- .disableProvidedPropertyConverters();
-
- assertThat(builder.isPropertyConverterLoadingEnabled(), is(false));
- }
-
- @Test(expected = ConfigException.class)
- public void loadingOrPropertyConvertersCanBeDisabled() {
- PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("source").when(source).getName();
- doReturn(PropertyValue.of("key","A", "test")).when(source).get("key");
- doReturn(100).when(source).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder().addPropertySources(source)
- .enableProvidedPropertyConverters()
- .disableProvidedPropertyConverters();
-
- Configuration config = builder.build();
-
- config.get("key", CustomTypeC.class);
- }
-
- @Test
- public void loadingOfPropertyConvertersCanBeEnabled() {
- PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("source").when(source).getName();
- doReturn(PropertyValue.of("key","A", "test")).when(source).get("key");
- doReturn(100).when(source).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder().addPropertySources(source)
- .disableProvidedPropertyConverters()
- .enableProvidedPropertyConverters();
-
- Configuration config = builder.build();
-
- CustomTypeC result = config.get("key", CustomTypeC.class);
-
- assertThat(result, notNullValue());
- assertThat(result.getValue(), equalTo("A"));
- }
-
- /*********************************************************************
- * Tests for enabling and disabling of automatic loading of
- * P r o p e r t y S o u r c e s
- */
-
- @Test
- public void enablingOfPropertySourceLoadingIsOk() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.disableProvidedPropertySources()
- .enableProvidedPropertySources();
-
- assertThat(builder.isPropertySourcesLoadingEnabled(), is(true));
- }
-
- @Test
- public void disablingPropertySourceLoadingIsOk() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.enableProvidedPropertySources()
- .disableProvidedPropertySources();
-
- assertThat(builder.isPropertySourcesLoadingEnabled(), is(false));
- }
-
- @Test
- public void loadingOfPropertySourcesCanBeEnabled() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.disableProvidedPropertySources()
- .enableProvidedPropertySources()
- .build();
-
-
- assertThat(builder.isPropertySourcesLoadingEnabled(), is(true));
- assertThat(config.get("tps_a"), Matchers.equalTo("A"));
- }
-
- @Test
- public void loadingOfPropertySourcesCanBeDisabled() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.enableProvidedPropertySources()
- .disableProvidedPropertySources()
- .build();
-
-
- assertThat(builder.isPropertySourcesLoadingEnabled(), is(false));
- assertThat(config.get("tps_c"), Matchers.nullValue());
- }
-
- /*********************************************************************
- * Tests for enabling and disabling of automatic loading of
- * P r o p e r t y F i l t e r s
- */
-
- @Test
- public void enablingOfPropertyFiltersLoadingIsOk() {
- PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("source").when(source).getName();
- doReturn(PropertyValue.of("key","A", "test")).when(source).get("key");
- doReturn(100).when(source).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.disableProvidedPropertyFilters()
- .enabledProvidedPropertyFilters()
- .addPropertySources(source)
- .build();
-
- String property = config.get("key");
-
- assertThat(property, CoreMatchers.notNullValue());
- assertThat(property, Matchers.equalTo("AinBerlin"));
- }
-
- @Test
- public void disablingOfPropertyFiltersLoadingIsOk() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.enabledProvidedPropertyFilters()
- .disableProvidedPropertyFilters();
-
- assertThat(builder.isPropertyFilterLoadingEnabled(), is(false));
- }
-
- @Test
- public void loadingOfPropertyFiltersCanBeDisabled() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.disableProvidedPropertyFilters()
- .enabledProvidedPropertyFilters();
-
- assertThat(builder.isPropertyFilterLoadingEnabled(), is(true));
- }
-
- @Test
- public void loadingOfPropertyFiltersCanBeEnabled() {
- PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
-
- doReturn("source").when(source).getName();
- doReturn(PropertyValue.of("key","A", "test")).when(source).get("key");
- doReturn(100).when(source).getOrdinal();
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.enabledProvidedPropertyFilters()
- .disableProvidedPropertyFilters()
- .addPropertySources(source)
- .build();
-
- String property = config.get("key");
-
- assertThat(property, CoreMatchers.notNullValue());
- assertThat(property, Matchers.equalTo("A"));
- }
-
- /*********************************************************************
- * Tests for enabling and disabling of automatic loading of
- * P r o p e r t y S o u r c e P r o v i d e r s
- */
-
- @Test
- public void disablingOfPropertySourceProvidersIsOk() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.enableProvidedPropertySourceProviders()
- .disableProvidedPropertySourceProviders()
- .build();
-
- assertThat(builder.isPropertySourceProvidersLoadingEnabled(), is(false));
- }
-
- @Test
- public void enablingOfPropertySourceProvidersIsOk() {
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.disableProvidedPropertySourceProviders()
- .enableProvidedPropertySourceProviders()
- .build();
-
- assertThat(builder.isPropertySourceProvidersLoadingEnabled(), is(true));
- }
-
- @Test
- public void loadingOfPropertySourceProvidersCanBeEnabled() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.disableProvidedPropertySourceProviders()
- .enableProvidedPropertySourceProviders()
- .build();
-
- assertThat(builder.isPropertySourceProvidersLoadingEnabled(), is(true));
- assertThat(config.get("tpsp_x"), Matchers.equalTo("X"));
- assertThat(config.get("tpsp_y"), Matchers.equalTo("Y"));
- }
-
- @Test
- public void loadingOfPropertySourceProvidersCanBeDisabled() {
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.enableProvidedPropertySourceProviders()
- .disableProvidedPropertySourceProviders()
- .build();
-
- assertThat(builder.isPropertySourceProvidersLoadingEnabled(), is(false));
- assertThat(config.get("tpsp_x"), nullValue());
- assertThat(config.get("tpsp_x"), nullValue());
- }
-
- @Test(expected = ConfigException.class)
- public void ioExceptionIsTurnedInConfigExceptionWhenLoadingResourceViaURL() throws Exception {
- URL resource = this.getClass().getResource("/configfiles/json/simple.json");
-
- assertThat(resource, CoreMatchers.notNullValue());
-
- ConfigurationBuilder builder = mock(ConfigurationBuilder.class, CALLS_REAL_METHODS);
-
- doThrow(IOException.class).when(builder).getConfigurationDataFromURL(Mockito.eq(resource));
-
- builder.addPropertySource(resource).build();
- }
-
- /*********************************************************************
- * Tests for loading resources via URL (as String)
- */
-
- @Test(expected = ConfigException.class)
- public void tryToLoadOneUnsupportedPropertySourceViaStringURL() {
- URL resource = this.getClass().getResource("/configfiles/other/simple.oml");
-
- assertThat(resource, CoreMatchers.notNullValue());
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- builder.addPropertySources(resource.toString()).build();
- }
-
- @Test
- public void loadOneJSONPropertySourceViaStringURL() {
- URL resource = this.getClass().getResource("/configfiles/json/simple.json");
-
- assertThat(resource, CoreMatchers.notNullValue());
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.addPropertySources(resource.toString())
- .build();
-
- assertThat(config, CoreMatchers.notNullValue());
- assertThat(config.get("a"), equalTo("A"));
- assertThat(config.get("b"), equalTo("B"));
- }
-
- @Test
- public void loadMultipleJSONPropertySourceViaStringURL() {
- URL first = this.getClass().getResource("/configfiles/json/first.json");
- URL second = this.getClass().getResource("/configfiles/json/second.json");
- URL third = this.getClass().getResource("/configfiles/json/third.json");
-
- assertThat(first, CoreMatchers.notNullValue());
- assertThat(second, CoreMatchers.notNullValue());
- assertThat(third, CoreMatchers.notNullValue());
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.addPropertySources(first.toString(), second.toString(),
- null, third.toString())
- .build();
-
- assertThat(config, CoreMatchers.notNullValue());
-
- // from first.json
- assertThat(config.get("d"), equalTo("D"));
- assertThat(config.get("e"), equalTo("E"));
-
- // from second.json
- assertThat(config.get("m"), equalTo("M"));
- assertThat(config.get("n"), equalTo("N"));
-
- // from thrid.json
- assertThat(config.get("p"), equalTo("P"));
- assertThat(config.get("q"), equalTo("Q"));
- }
-
- /**
- * ******************************************************************
- * Tests for loading resources via URL (as URL object)
- */
-
- @Test
- public void loadOneJSONPropertySourceViaURL() {
- URL resource = this.getClass().getResource("/configfiles/json/simple.json");
-
- assertThat(resource, CoreMatchers.notNullValue());
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.addPropertySource(resource)
- .build();
-
- assertThat(config, CoreMatchers.notNullValue());
- assertThat(config.get("a"), equalTo("A"));
- assertThat(config.get("b"), equalTo("B"));
- }
-
- @Test
- public void loadMultipleJSONPropertySourceViaURL() {
- URL first = this.getClass().getResource("/configfiles/json/first.json");
- URL second = this.getClass().getResource("/configfiles/json/second.json");
- URL third = this.getClass().getResource("/configfiles/json/third.json");
-
- assertThat(first, CoreMatchers.notNullValue());
- assertThat(second, CoreMatchers.notNullValue());
- assertThat(third, CoreMatchers.notNullValue());
-
- ConfigurationBuilder builder = new ConfigurationBuilder();
-
- Configuration config = builder.addPropertySources(first, second,
- null, third)
- .build();
-
- assertThat(config, CoreMatchers.notNullValue());
-
- // from first.json
- assertThat(config.get("d"), equalTo("D"));
- assertThat(config.get("e"), equalTo("E"));
-
- // from second.json
- assertThat(config.get("m"), equalTo("M"));
- assertThat(config.get("n"), equalTo("N"));
-
- // from thrid.json
- assertThat(config.get("p"), equalTo("P"));
- assertThat(config.get("q"), equalTo("Q"));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/test/java/org/apache/tamaya/builder/PropertySourceBasedConfigurationBuilderTest.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/test/java/org/apache/tamaya/builder/PropertySourceBasedConfigurationBuilderTest.java b/modules/builder/src/test/java/org/apache/tamaya/builder/PropertySourceBasedConfigurationBuilderTest.java
new file mode 100644
index 0000000..a47638f
--- /dev/null
+++ b/modules/builder/src/test/java/org/apache/tamaya/builder/PropertySourceBasedConfigurationBuilderTest.java
@@ -0,0 +1,899 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.builder;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.builder.spi.*;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Matchers;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+
+import java.io.IOException;
+import java.net.URL;
+
+import static java.util.Arrays.asList;
+import static org.apache.tamaya.builder.util.mockito.NotMockedAnswer.NOT_MOCKED_ANSWER;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+
+public class PropertySourceBasedConfigurationBuilderTest {
+
+ @Test
+ public void buildCanBuildEmptyConfiguration() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.build();
+
+ assertThat(config, notNullValue());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void buildCanBeCalledOnlyOnce() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ builder.build();
+ builder.build();
+ }
+
+ /*********************************************************************
+ * Tests for adding P r o p e r t y S o u r c e s
+ */
+
+ @Test(expected = NullPointerException.class)
+ public void addPropertySourcesDoesNotAcceptNullValue() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ builder.addPropertySources((PropertySource[])null);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void propertySourceCanNotBeAddedAfterBuildingTheConfiguration() {
+ PropertySource first = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn("first").when(first).getName();
+ doReturn(100).when(first).getOrdinal();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder().addPropertySources(first);
+
+ builder.build();
+
+ PropertySource second = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn("second").when(first).getName();
+
+ builder.addPropertySources(second);
+ }
+
+ @Test
+ public void singleAddedPropertySourceIsUsed() {
+ PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn("one").when(source).getName();
+ doReturn(PropertyValue.of("keyOfA","a", "test")).when(source).get("keyOfA");
+ doReturn(100).when(source).getOrdinal();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder().addPropertySources(source);
+
+ Configuration config = builder.build();
+
+ String valueOfA = config.get("keyOfA");
+
+ assertThat(valueOfA, notNullValue());
+ assertThat(valueOfA, equalTo("a"));
+ }
+
+ @Test
+ public void twoAddedPropertySourcesAreUsed() {
+ PropertySource sourceOne = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn("one").when(sourceOne).getName();
+ doReturn(PropertyValue.of("keyOfA","b", "test")).when(sourceOne).get("keyOfA");
+ doReturn(10).when(sourceOne).getOrdinal();
+
+ PropertySource sourceTwo = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+ doReturn("two").when(sourceTwo).getName();
+ doReturn(PropertyValue.of("keyOfA","a", "test")).when(sourceTwo).get("keyOfA");
+ doReturn(10).when(sourceTwo).getOrdinal();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder().addPropertySources(sourceOne)
+ .addPropertySources(sourceTwo);
+
+ Configuration config = builder.build();
+
+ String valueOfA = config.get("keyOfA");
+
+ assertThat(valueOfA, notNullValue());
+ assertThat(valueOfA, equalTo("a"));
+ }
+
+ @Ignore
+ @Test(expected = ConfigException.class)
+ public void twoPropertySourcesSamePrioritySameKey() {
+ PropertySource sourceOne = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn("one").when(sourceOne).getName();
+ doReturn("b").when(sourceOne).get("keyOfA");
+ doReturn(20).when(sourceOne).getOrdinal();
+
+ PropertySource sourceTwo = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+ doReturn("two").when(sourceTwo).getName();
+ doReturn("a").when(sourceTwo).get("keyOfA");
+ doReturn(20).when(sourceTwo).getOrdinal();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder().addPropertySources(sourceOne)
+ .addPropertySources(sourceTwo);
+
+ Configuration config = builder.build();
+
+ config.get("keyOfA");
+ }
+
+ @Test
+ public void twoPropertySourcesDiffPrioritySameKeyLowerAddedFirst() {
+ PropertySource sourceOne = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn("one").when(sourceOne).getName();
+ doReturn(PropertyValue.of("keyOfA","b", "test")).when(sourceOne).get("keyOfA");
+ doReturn(10).when(sourceOne).getOrdinal();
+
+ PropertySource sourceTwo = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+ doReturn("two").when(sourceTwo).getName();
+ doReturn(PropertyValue.of("keyOfA","a", "test")).when(sourceTwo).get("keyOfA");
+ doReturn(20).when(sourceTwo).getOrdinal();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder().addPropertySources(sourceOne)
+ .addPropertySources(sourceTwo);
+
+ Configuration config = builder.build();
+
+ String valueOfA = config.get("keyOfA");
+
+ assertThat(valueOfA, notNullValue());
+ assertThat(valueOfA, equalTo("a"));
+ }
+
+ @Test
+ public void twoPropertySourcesDiffPrioritySameKeyHigherAddedFirst() {
+ PropertySource sourceOne = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn("one").when(sourceOne).getName();
+ doReturn(PropertyValue.of("keyOfA","b", "test")).when(sourceOne).get("keyOfA");
+ doReturn(30).when(sourceOne).getOrdinal();
+
+ PropertySource sourceTwo = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+ doReturn("two").when(sourceTwo).getName();
+ doReturn(PropertyValue.of("keyOfA","a", "test")).when(sourceTwo).get("keyOfA");
+ doReturn(20).when(sourceTwo).getOrdinal();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder().addPropertySources(sourceOne, sourceTwo);
+
+ Configuration config = builder.build();
+
+ String valueOfA = config.get("keyOfA");
+
+ assertThat(valueOfA, notNullValue());
+ assertThat(valueOfA, equalTo("b"));
+ }
+
+ @Test
+ public void consecutiveCallsToAddPropertySourceArePossible() {
+ PropertySource sourceOne = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn("one").when(sourceOne).getName();
+ doReturn(null).when(sourceOne).get(anyString());
+ doReturn(PropertyValue.of("b","b", "test")).when(sourceOne).get("b");
+ doReturn(30).when(sourceOne).getOrdinal();
+
+ PropertySource sourceTwo = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+ doReturn("two").when(sourceTwo).getName();
+ doReturn(null).when(sourceTwo).get(anyString());
+ doReturn(PropertyValue.of("a","a", "test")).when(sourceTwo).get("a");
+ doReturn(30).when(sourceTwo).getOrdinal();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder().addPropertySources(sourceOne)
+ .addPropertySources(sourceTwo);
+
+ Configuration config = builder.build();
+
+ assertThat(config.get("b"), equalTo("b"));
+ assertThat(config.get("a"), equalTo("a"));
+ }
+
+ @Test
+ public void addMultiplePropertySourcesWhereOneIsNull() {
+ PropertySource sourceOne = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn("one").when(sourceOne).getName();
+ doReturn(null).when(sourceOne).get(anyString());
+ doReturn(PropertyValue.of("b","b", "test")).when(sourceOne).get("b");
+ doReturn(30).when(sourceOne).getOrdinal();
+
+ PropertySource sourceTwo = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+ doReturn("two").when(sourceTwo).getName();
+ doReturn(null).when(sourceTwo).get(anyString());
+ doReturn(PropertyValue.of("a","a", "test")).when(sourceTwo).get("a");
+ doReturn(30).when(sourceTwo).getOrdinal();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder().addPropertySources(sourceOne, null, sourceTwo);
+
+ Configuration config = builder.build();
+
+ assertThat(config.get("b"), equalTo("b"));
+ assertThat(config.get("a"), equalTo("a"));
+ }
+
+ /**
+ * ******************************************************************
+ * Tests for adding P r o p e r t y C o n v e r t e r
+ */
+
+// @Test(expected = NullPointerException.class)
+// public void canNotAddNullPropertyConverter() {
+// PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+//
+// builder.addPropertyConverter(TypeLiteral.of(CustomTypeA.class), null);
+// }
+//
+// @Test(expected = NullPointerException.class)
+// public void canNotAddNullTypeLiteralButPropertyConverter() {
+// PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+// builder.addPropertyConverter((TypeLiteral)null,
+// new PropertyConverter() {
+// @Override
+// public CustomTypeA convert(final String prop, ConversionContext context) {
+// return new CustomTypeA(prop, prop);
+// }
+// });
+// }
+//
+// @Test
+// public void addedPropertyConverterWithTypeLiteralIsUsedByConfiguration() {
+// PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+//
+// doReturn("source").when(source).getName();
+// doReturn(PropertyValue.of("key","A", "test")).when(source).get("key");
+// doReturn(100).when(source).getOrdinal();
+//
+// PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+//
+// builder.addPropertyConverter(TypeLiteral.of(CustomTypeA.class),
+// new PropertyConverter() {
+// @Override
+// public CustomTypeA convert(final String prop, ConversionContext context) {
+// return new CustomTypeA(prop, prop);
+// }
+// });
+// builder.addPropertySources(source);
+//
+// Configuration config = builder.build();
+//
+// Object resultRaw = config.get("key", CustomTypeA.class);
+//
+// assertThat(resultRaw, CoreMatchers.notNullValue());
+//
+// CustomTypeA result = (CustomTypeA)resultRaw;
+//
+// assertThat(result.getName(), equalTo("AA"));
+// }
+//
+// @Test
+// public void addedPropertyConverterWithClassIsUsedByConfiguration() {
+// PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+//
+// doReturn("source").when(source).getName();
+// doReturn(PropertyValue.of("key","A", "test")).when(source).get("key");
+// doReturn(100).when(source).getOrdinal();
+//
+// PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+//
+// builder.addPropertyConverter(TypeLiteral.of(CustomTypeA.class),
+// new PropertyConverter() {
+// @Override
+// public CustomTypeA convert(final String prop, ConversionContext context) {
+// return new CustomTypeA(prop, prop);
+// }
+// });
+// builder.addPropertySources(source);
+//
+// Configuration config = builder.build();
+//
+// Object resultRaw = config.get("key", CustomTypeA.class);
+//
+// assertThat(resultRaw, CoreMatchers.notNullValue());
+//
+// CustomTypeA result = (CustomTypeA)resultRaw;
+//
+// assertThat(result.getName(), equalTo("AA"));
+// }
+//
+// @Test
+// public void canGetAndConvertPropertyViaOfMethod() {
+// PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+//
+// doReturn("source").when(source).getName();
+// doReturn(PropertyValue.of("key","A", "test")).when(source).get("key");
+// doReturn(100).when(source).getOrdinal();
+//
+// PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+//
+// builder.addPropertySources(source);
+//
+// Configuration config = builder.build();
+//
+// Object resultRaw = config.get("key", CustomTypeB.class);
+//
+// assertThat(resultRaw, CoreMatchers.notNullValue());
+//
+// CustomTypeB result = (CustomTypeB)resultRaw;
+//
+// assertThat(result.getName(), equalTo("A"));
+// }
+
+ /*********************************************************************
+ * Tests for adding P r o p e r t y F i l t e r
+ */
+
+ @Test(expected = NullPointerException.class)
+ public void canNotAddNullAsPropertyFilter() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+ builder.addPropertyFilters((PropertyFilter[])null);
+ }
+
+ @Test
+ public void canAddNonSPIPropertyFilter() {
+ PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn(PropertyValue.of("key","M", "test")).when(source).get("key");
+ doReturn("source").when(source).getName();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.addPropertySources(source)
+ .addPropertyFilters(new TestANonSPIPropertyFilter())
+ .build();
+
+ String property = config.get("key");
+
+ assertThat(property, CoreMatchers.notNullValue());
+ assertThat(property, CoreMatchers.containsString("ABC"));
+ }
+
+ @Test
+ public void canAddNonSPIPropertyFiltersViaConsecutiveCalls() {
+ PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn(PropertyValue.of("key","M", "test")).when(source).get("key");
+ doReturn("source").when(source).getName();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.addPropertySources(source)
+ .addPropertyFilters(new TestANonSPIPropertyFilter())
+ .addPropertyFilters(new TestBNonSPIPropertyFilter())
+ .build();
+
+ String property = config.get("key");
+
+ assertThat(property, CoreMatchers.notNullValue());
+ assertThat(property, CoreMatchers.containsString("ABC"));
+ assertThat(property, CoreMatchers.containsString("XYZ"));
+ }
+
+ @Test
+ public void canAddMultipleNonSPIPropertyFiltersWhileOneIsNull() {
+ PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn(PropertyValue.of("key","M", "test")).when(source).get("key");
+ doReturn("source").when(source).getName();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.addPropertySources(source)
+ .addPropertyFilters(new TestANonSPIPropertyFilter(),
+ null,
+ new TestBNonSPIPropertyFilter())
+ .build();
+
+ String property = config.get("key");
+
+ assertThat(property, CoreMatchers.notNullValue());
+ assertThat(property, CoreMatchers.containsString("ABC"));
+ assertThat(property, CoreMatchers.containsString("XYZ"));
+ }
+
+ @Test
+ public void overhandedNullPropertyFilterIsSafelyHandled() {
+ PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn(PropertyValue.of("key","M", "test")).when(source).get("key");
+ doReturn("source").when(source).getName();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.addPropertySources(source)
+ .addPropertyFilters((PropertyFilter)null) // The cast is needed!
+ .addPropertyFilters(new TestBNonSPIPropertyFilter())
+ .build();
+
+ String property = config.get("key");
+
+ assertThat(property, CoreMatchers.notNullValue());
+ assertThat(property, CoreMatchers.containsString("XYZ"));
+ }
+
+ @Test
+ public void canAddMultipleNonSPIPropertyFilter() {
+ PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn(PropertyValue.of("key","M", "test")).when(source).get("key");
+ doReturn("source").when(source).getName();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.addPropertySources(source)
+ .addPropertyFilters(new TestANonSPIPropertyFilter(),
+ new TestBNonSPIPropertyFilter())
+ .build();
+
+ String property = config.get("key");
+
+ assertThat(property, CoreMatchers.notNullValue());
+ assertThat(property, CoreMatchers.containsString("ABC"));
+ assertThat(property, CoreMatchers.containsString("XYZ"));
+ }
+
+ /*********************************************************************
+ * Tests for adding
+ * P r o p e r t y S o u r c e P r o v i d e r s
+ */
+
+ @Test
+ public void handlesSafelyPropertyProviderReturningNullInsteadOfPropertySource() {
+ PropertySourceProvider nullReturning = mock(PropertySourceProvider.class, NOT_MOCKED_ANSWER);
+
+ doReturn(asList((PropertySource)null)).when(nullReturning).getPropertySources();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.addPropertySourceProviders(new TestPropertySourceProviderB(),
+ nullReturning,
+ new TestPropertySourceProvider())
+ .build();
+
+ assertThat(config.get("tpsp_a"), Matchers.equalTo("A"));
+ assertThat(config.get("tpsp_b"), Matchers.equalTo("B"));
+ assertThat(config.get("tpsp_x"), Matchers.equalTo("X"));
+ assertThat(config.get("tpsp_y"), Matchers.equalTo("Y"));
+
+ verify(nullReturning).getPropertySources();
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void cannotAddNullAsPropertyProvider() {
+ new PropertySourceBasedConfigurationBuilder().addPropertySourceProviders((PropertySourceProvider[])null);
+ }
+
+ @Test
+ public void canAddMultipleNonSPIPropertySourceProviders() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.addPropertySourceProviders(new TestPropertySourceProviderB(),
+ new TestPropertySourceProvider())
+ .build();
+
+ assertThat(config.get("tpsp_a"), Matchers.equalTo("A"));
+ assertThat(config.get("tpsp_b"), Matchers.equalTo("B"));
+ assertThat(config.get("tpsp_x"), Matchers.equalTo("X"));
+ assertThat(config.get("tpsp_y"), Matchers.equalTo("Y"));
+ }
+
+ @Test
+ public void canAddMultipleNonSPIPropertySourceProvidersWhileOfOfThemIsNull() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.addPropertySourceProviders(new TestPropertySourceProviderB(), null,
+ new TestPropertySourceProvider())
+ .build();
+
+ assertThat(config.get("tpsp_a"), Matchers.equalTo("A"));
+ assertThat(config.get("tpsp_b"), Matchers.equalTo("B"));
+ assertThat(config.get("tpsp_x"), Matchers.equalTo("X"));
+ assertThat(config.get("tpsp_y"), Matchers.equalTo("Y"));
+ }
+
+
+ /*
+ * Tests for adding
+ * P r o p e r t y V a l u e C o m b i n a t i o n P o l i c y
+ */
+
+ // @todo TAYAMA-60 Write more tests
+
+ /*********************************************************************
+ * Tests for enabling and disabling of automatic loading of
+ * P r o p e r t y S o u r c e s
+ */
+
+// @Test
+// public void enablingOfProvidedPropertySourceServiceProvidersIsOk() {
+// PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+//
+// builder.disableProvidedPropertyConverters()
+// .enableProvidedPropertyConverters();
+//
+// assertThat(builder.isPropertyConverterLoadingEnabled(), is(true));
+// }
+//
+// @Test
+// public void disablingOfProvidedPropertySourceServiceProvidersIsOk() {
+// PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+//
+// builder.enableProvidedPropertyConverters()
+// .disableProvidedPropertyConverters();
+//
+// assertThat(builder.isPropertyConverterLoadingEnabled(), is(false));
+// }
+
+ @Test(expected = ConfigException.class)
+ public void loadingOrPropertyConvertersCanBeDisabled() {
+ PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn("source").when(source).getName();
+ doReturn(PropertyValue.of("key","A", "test")).when(source).get("key");
+ doReturn(100).when(source).getOrdinal();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder().addPropertySources(source);
+
+ Configuration config = builder.build();
+
+ config.get("key");
+ }
+
+ @Test
+ public void loadingOfPropertyConvertersCanBeEnabled() {
+ PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn("source").when(source).getName();
+ doReturn(PropertyValue.of("key","A", "test")).when(source).get("key");
+ doReturn(100).when(source).getOrdinal();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder().addPropertySources(source);
+
+ Configuration config = builder.build();
+
+ String result = config.get("key");
+
+ assertThat(result, notNullValue());
+ assertThat(result, equalTo("A"));
+ }
+
+ /*********************************************************************
+ * Tests for enabling and disabling of automatic loading of
+ * P r o p e r t y S o u r c e s
+ */
+
+ @Test
+ public void enablingOfPropertySourceLoadingIsOk() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ builder.disableProvidedPropertySources()
+ .enableProvidedPropertySources();
+
+ assertThat(builder.isPropertySourcesLoadingEnabled(), is(true));
+ }
+
+ @Test
+ public void disablingPropertySourceLoadingIsOk() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ builder.enableProvidedPropertySources()
+ .disableProvidedPropertySources();
+
+ assertThat(builder.isPropertySourcesLoadingEnabled(), is(false));
+ }
+
+ @Test
+ public void loadingOfPropertySourcesCanBeEnabled() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.disableProvidedPropertySources()
+ .enableProvidedPropertySources()
+ .build();
+
+
+ assertThat(builder.isPropertySourcesLoadingEnabled(), is(true));
+ assertThat(config.get("tps_a"), Matchers.equalTo("A"));
+ }
+
+ @Test
+ public void loadingOfPropertySourcesCanBeDisabled() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.enableProvidedPropertySources()
+ .disableProvidedPropertySources()
+ .build();
+
+
+ assertThat(builder.isPropertySourcesLoadingEnabled(), is(false));
+ assertThat(config.get("tps_c"), Matchers.nullValue());
+ }
+
+ /*********************************************************************
+ * Tests for enabling and disabling of automatic loading of
+ * P r o p e r t y F i l t e r s
+ */
+
+ @Test
+ public void enablingOfPropertyFiltersLoadingIsOk() {
+ PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn("source").when(source).getName();
+ doReturn(PropertyValue.of("key","A", "test")).when(source).get("key");
+ doReturn(100).when(source).getOrdinal();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.disableProvidedPropertyFilters()
+ .enabledProvidedPropertyFilters()
+ .addPropertySources(source)
+ .build();
+
+ String property = config.get("key");
+
+ assertThat(property, CoreMatchers.notNullValue());
+ assertThat(property, Matchers.equalTo("AinBerlin"));
+ }
+
+ @Test
+ public void disablingOfPropertyFiltersLoadingIsOk() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ builder.enabledProvidedPropertyFilters()
+ .disableProvidedPropertyFilters();
+
+ assertThat(builder.isPropertyFilterLoadingEnabled(), is(false));
+ }
+
+ @Test
+ public void loadingOfPropertyFiltersCanBeDisabled() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ builder.disableProvidedPropertyFilters()
+ .enabledProvidedPropertyFilters();
+
+ assertThat(builder.isPropertyFilterLoadingEnabled(), is(true));
+ }
+
+ @Test
+ public void loadingOfPropertyFiltersCanBeEnabled() {
+ PropertySource source = mock(PropertySource.class, NOT_MOCKED_ANSWER);
+
+ doReturn("source").when(source).getName();
+ doReturn(PropertyValue.of("key","A", "test")).when(source).get("key");
+ doReturn(100).when(source).getOrdinal();
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.enabledProvidedPropertyFilters()
+ .disableProvidedPropertyFilters()
+ .addPropertySources(source)
+ .build();
+
+ String property = config.get("key");
+
+ assertThat(property, CoreMatchers.notNullValue());
+ assertThat(property, Matchers.equalTo("A"));
+ }
+
+ /*********************************************************************
+ * Tests for enabling and disabling of automatic loading of
+ * P r o p e r t y S o u r c e P r o v i d e r s
+ */
+
+ @Test
+ public void disablingOfPropertySourceProvidersIsOk() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ builder.enableProvidedPropertySourceProviders()
+ .disableProvidedPropertySourceProviders()
+ .build();
+
+ assertThat(builder.isPropertySourceProvidersLoadingEnabled(), is(false));
+ }
+
+ @Test
+ public void enablingOfPropertySourceProvidersIsOk() {
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ builder.disableProvidedPropertySourceProviders()
+ .enableProvidedPropertySourceProviders()
+ .build();
+
+ assertThat(builder.isPropertySourceProvidersLoadingEnabled(), is(true));
+ }
+
+ @Test
+ public void loadingOfPropertySourceProvidersCanBeEnabled() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.disableProvidedPropertySourceProviders()
+ .enableProvidedPropertySourceProviders()
+ .build();
+
+ assertThat(builder.isPropertySourceProvidersLoadingEnabled(), is(true));
+ assertThat(config.get("tpsp_x"), Matchers.equalTo("X"));
+ assertThat(config.get("tpsp_y"), Matchers.equalTo("Y"));
+ }
+
+ @Test
+ public void loadingOfPropertySourceProvidersCanBeDisabled() {
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.enableProvidedPropertySourceProviders()
+ .disableProvidedPropertySourceProviders()
+ .build();
+
+ assertThat(builder.isPropertySourceProvidersLoadingEnabled(), is(false));
+ assertThat(config.get("tpsp_x"), nullValue());
+ assertThat(config.get("tpsp_x"), nullValue());
+ }
+
+ @Test(expected = ConfigException.class)
+ public void ioExceptionIsTurnedInConfigExceptionWhenLoadingResourceViaURL() throws Exception {
+ URL resource = this.getClass().getResource("/configfiles/json/simple.json");
+
+ assertThat(resource, CoreMatchers.notNullValue());
+
+ PropertySourceBasedConfigurationBuilder builder = mock(PropertySourceBasedConfigurationBuilder.class, CALLS_REAL_METHODS);
+
+ doThrow(IOException.class).when(builder).getConfigurationDataFromURL(Mockito.eq(resource));
+
+ builder.addPropertySource(resource).build();
+ }
+
+ /*********************************************************************
+ * Tests for loading resources via URL (as String)
+ */
+
+ @Test(expected = ConfigException.class)
+ public void tryToLoadOneUnsupportedPropertySourceViaStringURL() {
+ URL resource = this.getClass().getResource("/configfiles/other/simple.oml");
+
+ assertThat(resource, CoreMatchers.notNullValue());
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ builder.addPropertySourceURLs(resource.toString()).build();
+ }
+
+ @Test
+ public void loadOneJSONPropertySourceViaStringURL() {
+ URL resource = this.getClass().getResource("/configfiles/json/simple.json");
+
+ assertThat(resource, CoreMatchers.notNullValue());
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.addPropertySourceURLs(resource.toString())
+ .build();
+
+ assertThat(config, CoreMatchers.notNullValue());
+ assertThat(config.get("a"), equalTo("A"));
+ assertThat(config.get("b"), equalTo("B"));
+ }
+
+ @Test
+ public void loadMultipleJSONPropertySourceViaStringURL() {
+ URL first = this.getClass().getResource("/configfiles/json/first.json");
+ URL second = this.getClass().getResource("/configfiles/json/second.json");
+ URL third = this.getClass().getResource("/configfiles/json/third.json");
+
+ assertThat(first, CoreMatchers.notNullValue());
+ assertThat(second, CoreMatchers.notNullValue());
+ assertThat(third, CoreMatchers.notNullValue());
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ PropertySourceBasedConfiguration config = builder.addPropertySourceURLs(first.toString(), second.toString(),
+ null, third.toString())
+ .build();
+
+ assertThat(config, CoreMatchers.notNullValue());
+
+ // from first.json
+ assertThat(config.get("d"), equalTo("D"));
+ assertThat(config.get("e"), equalTo("E"));
+
+ // from second.json
+ assertThat(config.get("m"), equalTo("M"));
+ assertThat(config.get("n"), equalTo("N"));
+
+ // from thrid.json
+ assertThat(config.get("p"), equalTo("P"));
+ assertThat(config.get("q"), equalTo("Q"));
+ }
+
+ /**
+ * ******************************************************************
+ * Tests for loading resources via URL (as URL object)
+ */
+
+ @Test
+ public void loadOneJSONPropertySourceViaURL() {
+ URL resource = this.getClass().getResource("/configfiles/json/simple.json");
+
+ assertThat(resource, CoreMatchers.notNullValue());
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.addPropertySource(resource)
+ .build();
+
+ assertThat(config, CoreMatchers.notNullValue());
+ assertThat(config.get("a"), equalTo("A"));
+ assertThat(config.get("b"), equalTo("B"));
+ }
+
+ @Test
+ public void loadMultipleJSONPropertySourceViaURL() {
+ URL first = this.getClass().getResource("/configfiles/json/first.json");
+ URL second = this.getClass().getResource("/configfiles/json/second.json");
+ URL third = this.getClass().getResource("/configfiles/json/third.json");
+
+ assertThat(first, CoreMatchers.notNullValue());
+ assertThat(second, CoreMatchers.notNullValue());
+ assertThat(third, CoreMatchers.notNullValue());
+
+ PropertySourceBasedConfigurationBuilder builder = new PropertySourceBasedConfigurationBuilder();
+
+ Configuration config = builder.addPropertySourceURLs(first, second,
+ null, third)
+ .build();
+
+ assertThat(config, CoreMatchers.notNullValue());
+
+ // from first.json
+ assertThat(config.get("d"), equalTo("D"));
+ assertThat(config.get("e"), equalTo("E"));
+
+ // from second.json
+ assertThat(config.get("m"), equalTo("M"));
+ assertThat(config.get("n"), equalTo("N"));
+
+ // from thrid.json
+ assertThat(config.get("p"), equalTo("P"));
+ assertThat(config.get("q"), equalTo("Q"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/test/java/org/apache/tamaya/builder/internal/converters/ConverterTestsPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/test/java/org/apache/tamaya/builder/internal/converters/ConverterTestsPropertySource.java b/modules/builder/src/test/java/org/apache/tamaya/builder/internal/converters/ConverterTestsPropertySource.java
index 3f34384..c2fe2d3 100644
--- a/modules/builder/src/test/java/org/apache/tamaya/builder/internal/converters/ConverterTestsPropertySource.java
+++ b/modules/builder/src/test/java/org/apache/tamaya/builder/internal/converters/ConverterTestsPropertySource.java
@@ -18,8 +18,8 @@
*/
package org.apache.tamaya.core.internal.converters;
-import org.apache.tamaya.builder.spi.PropertySource;
-import org.apache.tamaya.builder.spi.PropertyValue;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
import java.util.Collections;
import java.util.Map;
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/builder/src/test/java/org/apache/tamaya/builder/internal/converters/EnumConverterTest.java
----------------------------------------------------------------------
diff --git a/modules/builder/src/test/java/org/apache/tamaya/builder/internal/converters/EnumConverterTest.java b/modules/builder/src/test/java/org/apache/tamaya/builder/internal/converters/EnumConverterTest.java
index 52d643e..9b2c8a7 100644
--- a/modules/builder/src/test/java/org/apache/tamaya/builder/internal/converters/EnumConverterTest.java
+++ b/modules/builder/src/test/java/org/apache/tamaya/builder/internal/converters/EnumConverterTest.java
@@ -19,7 +19,7 @@
package org.apache.tamaya.core.internal.converters;
import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.builder.spi.ConversionContext;
+import org.apache.tamaya.spi.ConversionContext;
import org.junit.Test;
import java.math.RoundingMode;
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/defaultconfig/pom.xml
----------------------------------------------------------------------
diff --git a/modules/defaultconfig/pom.xml b/modules/defaultconfig/pom.xml
new file mode 100644
index 0000000..e21d93a
--- /dev/null
+++ b/modules/defaultconfig/pom.xml
@@ -0,0 +1,62 @@
+<?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.
+-->
+<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>
+ </parent>
+
+ <artifactId>tamaya-defaultconfig</artifactId>
+ <name>Apache Tamaya Modules - Default Configuration</name>
+ <packaging>jar</packaging> <!-- bundle -->
+
+ <inceptionYear>2016</inceptionYear>
+
+ <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-types</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>java-hamcrest</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/ConfigurationWithDefaults.java
----------------------------------------------------------------------
diff --git a/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/ConfigurationWithDefaults.java b/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/ConfigurationWithDefaults.java
new file mode 100644
index 0000000..0ddfbbb
--- /dev/null
+++ b/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/ConfigurationWithDefaults.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.defaults;
+
+
+import org.apache.tamaya.types.TypeLiteral;
+import org.apache.tamaya.types.TypedConfiguration;
+
+/**
+ * Created by atsticks on 19.07.16.
+ */
+public interface ConfigurationWithDefaults extends TypedConfiguration{
+
+ /**
+ * Get the property key as String, return the default value if no matching value was found.
+ *
+ * @param <T> the type of the class modeled by the type parameter
+ * @param key the property's absolute, or relative path, e.g. @code
+ * a/b/c/d.myProperty}.
+ * @param defaultValue value to be used, if no value is present.
+ * @return the property value, never null..
+ * @throws org.apache.tamaya.ConfigException if the keys could not be converted to the required target type.
+ */
+ <T> T getOrDefault(String key, String defaultValue);
+
+ /**
+ * Get the property key as type T. This will implicitly require a corresponding {@link
+ * org.apache.tamaya.types.spi.PropertyConverter} to be available that is capable current providing type T
+ * fromMap the given String keys.
+ *
+ * @param <T> the type of the class modeled by the type parameter
+ * @param key the property's absolute, or relative path, e.g. @code
+ * a/b/c/d.myProperty}.
+ * @param type The target type required, not null.
+ * @param defaultValue value to be used, if no value is present.
+ * @return the property value, never null..
+ * @throws org.apache.tamaya.ConfigException if the keys could not be converted to the required target type.
+ */
+ <T> T getOrDefault(String key, Class<T> type, T defaultValue);
+
+ /**
+ * Get the property key as type T. This will implicitly require a corresponding {@link
+ * org.apache.tamaya.types.spi.PropertyConverter} to be available that is capable current providing type T
+ * fromMap the given String keys.
+ *
+ * @param <T> the type of the class modeled by the type parameter
+ * @param key the property's absolute, or relative path, e.g. @code
+ * a/b/c/d.myProperty}.
+ * @param type The target type required, not null.
+ * @param defaultValue value to be used, if no value is present.
+ * @return the property value, never null..
+ * @throws org.apache.tamaya.ConfigException if the keys could not be converted to the required target type.
+ */
+ <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/internal/ConfigurationWithDefaultsAdapter.java
----------------------------------------------------------------------
diff --git a/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/internal/ConfigurationWithDefaultsAdapter.java b/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/internal/ConfigurationWithDefaultsAdapter.java
new file mode 100644
index 0000000..8101256
--- /dev/null
+++ b/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/internal/ConfigurationWithDefaultsAdapter.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.defaults.internal;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.spi.ConfigurationAdapter;
+import org.apache.tamaya.defaults.ConfigurationWithDefaults;
+
+/**
+ * Adapter for creating an instance of a {@link org.apache.tamaya.types.TypedConfiguration}.
+ */
+public final class ConfigurationWithDefaultsAdapter implements ConfigurationAdapter{
+
+ @Override
+ public <T> T adapt(Configuration configuration, Class<T> targetType) {
+ if(targetType.equals(ConfigurationWithDefaults.class)){
+ return (T)new DefaultConfigurationWithDefaults(configuration);
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7144e3f9/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/internal/DefaultConfigurationWithDefaults.java
----------------------------------------------------------------------
diff --git a/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/internal/DefaultConfigurationWithDefaults.java b/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/internal/DefaultConfigurationWithDefaults.java
new file mode 100644
index 0000000..d9bb4ee
--- /dev/null
+++ b/modules/defaultconfig/src/main/java/org/apache/tamaya/defaults/internal/DefaultConfigurationWithDefaults.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the 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.defaults.internal;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.defaults.ConfigurationWithDefaults;
+import org.apache.tamaya.types.TypeLiteral;
+import org.apache.tamaya.types.TypedConfiguration;
+import org.apache.tamaya.types.internal.adapters.DefaultTypedConfiguration;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of the {@link TypedConfiguration} API.
+ */
+public class DefaultConfigurationWithDefaults implements ConfigurationWithDefaults {
+ /**
+ * The logger.
+ */
+ private static final Logger LOG = Logger.getLogger(DefaultTypedConfiguration.class.getName());
+
+ private TypedConfiguration configuration;
+
+ /**
+ * Constructor.
+ * @param configuration The configuration to be decorated.
+ */
+ public DefaultConfigurationWithDefaults(Configuration configuration){
+ this.configuration = Objects.requireNonNull(configuration).adapt(TypedConfiguration.class);
+ }
+
+ @Override
+ public String get(String key) {
+ return configuration.get(key);
+ }
+
+ @Override
+ public String getOrDefault(String key, String defaultValue) {
+ String value = configuration.get(key);
+ if(value==null){
+ return defaultValue;
+ }
+ return value;
+ }
+
+ @Override
+ public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
+ T val = get(key, type);
+ if(val==null){
+ return defaultValue;
+ }
+ return val;
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return configuration.getProperties();
+ }
+
+ @Override
+ public <T> T adapt(Class<T> type) {
+ if(ConfigurationWithDefaults.class.equals(type)){
+ return (T)this;
+ }
+ return configuration.adapt(type);
+ }
+
+ @Override
+ public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) {
+ T val = get(key, type);
+ if(val==null){
+ return defaultValue;
+ }
+ return val;
+ }
+
+ @Override
+ public <T> T get(String key, Class<T> type) {
+ return configuration.get(key, type);
+ }
+
+ @Override
+ public <T> T get(String key, TypeLiteral<T> type) {
+ return configuration.get(key, type);
+ }
+}