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/02/27 22:02:22 UTC

[03/10] incubator-tamaya git commit: TAMAYA-71: Finished yaml support, including tests.

TAMAYA-71: Finished yaml support, including tests.


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

Branch: refs/heads/master
Commit: 60e8827f2b332da68bbab26f1d325f44456d195d
Parents: 264a5f4
Author: anatole <an...@apache.org>
Authored: Sat Feb 27 21:53:31 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Sat Feb 27 21:53:31 2016 +0100

----------------------------------------------------------------------
 .../java/org/apache/tamaya/json/YAMLFormat.java | 122 +++++++++++++++----
 .../apache/tamaya/json/YAMLPropertySource.java  |  63 ++--------
 .../org/apache/tamaya/json/YAMLFormatTest.java  |  54 ++++----
 .../tamaya/json/YAMLPropertySourceTest.java     |  24 ++--
 .../test/resources/configs/valid/contact.yaml   |  19 ++-
 .../resources/configs/valid/test-with-prio.yaml |   4 +
 6 files changed, 162 insertions(+), 124 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/60e8827f/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLFormat.java
----------------------------------------------------------------------
diff --git a/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLFormat.java b/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLFormat.java
index 8bdd414..20d52d1 100644
--- a/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLFormat.java
+++ b/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLFormat.java
@@ -22,19 +22,19 @@ import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.format.ConfigurationData;
 import org.apache.tamaya.format.ConfigurationDataBuilder;
 import org.apache.tamaya.format.ConfigurationFormat;
+import org.yaml.snakeyaml.Yaml;
 
 import java.io.InputStream;
 import java.net.URL;
-import java.nio.charset.Charset;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static java.lang.String.format;
 
-import javax.json.Json;
-import javax.json.JsonException;
-import javax.json.JsonObject;
-import javax.json.JsonReader;
-import javax.json.JsonReaderFactory;
 
 /**
  * Implementation of the {@link org.apache.tamaya.format.ConfigurationFormat}
@@ -42,44 +42,114 @@ import javax.json.JsonReaderFactory;
  *
  * @see <a href="http://www.json.org">JSON format specification</a>
  */
-public class JSONFormat implements ConfigurationFormat {
-    /** Property that make Johnzon accept commentc. */
-    public static final String JOHNZON_SUPPORTS_COMMENTS_PROP = "org.apache.johnzon.supports-comments";
-    /** The reader factory used. */
-    private final JsonReaderFactory readerFactory;
+public class YAMLFormat implements ConfigurationFormat {
+    /**
+     * THe logger.
+     */
+    private static final Logger LOG = Logger.getLogger(YAMLFormat.class.getName());
 
     /**
      * Constructor, itniaitlizing zhe JSON reader factory.
      */
-    public JSONFormat(){
-        Map<String, Object> config = new HashMap<>();
-        config.put(JOHNZON_SUPPORTS_COMMENTS_PROP, true);
-        this.readerFactory = Json.createReaderFactory(config);
+    public YAMLFormat(){
     }
 
     @Override
     public String getName() {
-        return "json";
+        return "yaml";
     }
 
     @Override
     public boolean accepts(URL url) {
-        return Objects.requireNonNull(url).getPath().endsWith(".json");
+        return Objects.requireNonNull(url).getPath().endsWith(".yaml");
     }
 
     @Override
     public ConfigurationData readConfiguration(String resource, InputStream inputStream) {
-
-        try {
-            final JsonReader reader = this.readerFactory.createReader(inputStream, Charset.forName("UTF-8"));
-            JsonObject root = reader.readObject();
-            HashMap<String, String> values = new HashMap<>();
-            JSONVisitor visitor = new JSONVisitor(root, values);
-            visitor.run();
+        try( InputStream in = inputStream;) {
+            Map<String, String> values = readConfig(resource, inputStream);
             return ConfigurationDataBuilder.of(resource, this).addProperties(values)
-                                           .build();
-        } catch (JsonException e) {
+                .build();
+        } catch (Exception e) {
             throw new ConfigException("Failed to read data from " + resource, e);
         }
     }
+
+    /**
+     * Reads the configuration.
+     * @param inputStream the input stream, not null.
+     * @return the configuration read from the given resource URL.
+     * @throws ConfigException if resource URL cannot be read.
+     */
+    protected Map<String, String> readConfig(String resource, InputStream inputStream) {
+        try{
+            Yaml yaml = new Yaml();
+            HashMap<String, String> values = new HashMap<>();
+            Object config = yaml.load(inputStream);
+            mapYamlIntoProperties(config, values);
+            if(LOG.isLoggable(Level.FINEST)){
+                LOG.finest("Read data from " + resource + " : " + values);
+            }
+            return values;
+        }catch (Throwable t) {
+            throw new ConfigException(format("Failed to read properties from %s", resource), t);
+        }
+    }
+    /**
+     * Reads the configuration.
+     * @param urlResource soure of the configuration.
+     * @return the configuration read from the given resource URL.
+     * @throws ConfigException if resource URL cannot be read.
+     */
+    protected Map<String, String> readConfig(URL urlResource) {
+        try (InputStream is = urlResource.openStream()) {
+            return readConfig(urlResource.toExternalForm(), is);
+        }
+        catch (Throwable t) {
+            throw new ConfigException(format("Failed to read properties from %s", urlResource.toExternalForm()), t);
+        }
+    }
+
+    private void mapYamlIntoProperties(Object config, HashMap<String, String> values) {
+        mapYamlIntoProperties("", config, values);
+    }
+
+    /**
+     * Maps the given config item (could be a String, a collection type or something else returned by the yaml parser
+     * to a key/value pair and adds it to {@code values} (hereby honoring the prefix as a key to be used.).
+     * Collection types are recursively to remapped hereby extending the given prefix as needed and recursively
+     * delegate mapping of values contained.
+     * @param prefix the prefix or key evaluated so far, never null (but can be empty for root entries).
+     * @param config the config value. Could be a single value or a collection type.
+     * @param values the properties where items identified must be written into. These properties are going to be
+     *               returned as result of the format reading operation ans integrated into the overall configuration
+     *               map.
+     */
+    protected void mapYamlIntoProperties(String prefix, Object config, HashMap<String, String> values) {
+        // add further data types supported by yaml, e.g. date, ...
+        if(config instanceof List){
+            StringBuilder b = new StringBuilder();
+            for(Object val:((List<Object>)config)){
+                b.append(mapValueToString(val));
+                b.append(",");
+            }
+            if(b.length()>0){
+                b.setLength(b.length()-1);
+            }
+            values.put(prefix, b.toString());
+            values.put("_"+prefix+".collection-type", "List");
+        } else if(config instanceof Map){
+            for(Map.Entry<String,Object> en:((Map<String,Object>)config).entrySet()){
+                String newPrefix = prefix.isEmpty()?en.getKey():prefix +"."+en.getKey();
+                mapYamlIntoProperties(newPrefix, en.getValue(), values);
+            }
+        } else{
+            values.put(prefix, mapValueToString(config));
+        }
+    }
+
+    protected String mapValueToString(Object val) {
+        return String.valueOf(val);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/60e8827f/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLPropertySource.java b/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLPropertySource.java
index 43cfa73..e29d2e7 100644
--- a/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLPropertySource.java
+++ b/modules/yaml/src/main/java/org/apache/tamaya/json/YAMLPropertySource.java
@@ -18,55 +18,34 @@
  */
 package org.apache.tamaya.json;
 
-import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.spi.PropertySource;
 import org.apache.tamaya.spi.PropertyValue;
 
-import java.io.InputStream;
 import java.net.URL;
-import java.nio.charset.Charset;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import javax.json.Json;
-import javax.json.JsonObject;
-import javax.json.JsonReaderFactory;
-import javax.json.JsonStructure;
 
-import static java.lang.String.format;
 
 /**
  * Property source based on a JSON file.
  */
-public class JSONPropertySource implements PropertySource {
-    /** Constant for enabling comments in Johnzon. */
-    public static final String JOHNZON_SUPPORTS_COMMENTS_PROP = "org.apache.johnzon.supports-comments";
-
+public class YAMLPropertySource implements PropertySource {
     /** The underlying resource. */
     private final URL urlResource;
     /** The values read. */
     private final Map<String, String> values;
     /** The evaluated ordinal. */
     private int ordinal;
-    /** The JSON reader factory used. */
-    private JsonReaderFactory readerFactory = initReaderFactory();
-
-    /** Initializes the factory to be used for creating readers. */
-    private JsonReaderFactory initReaderFactory() {
-        Map<String, Object> config = new HashMap<>();
-        config.put(JOHNZON_SUPPORTS_COMMENTS_PROP, true);
-       return Json.createReaderFactory(config);
-    }
+    /** The format implementation used for parsing. */
+    private YAMLFormat format = new YAMLFormat();
 
     /**
      * Constructor, hereby using 0 as the default ordinal.
      * @param resource the resource modelled as URL, not null.
      */
-    public JSONPropertySource(URL resource) {
+    public YAMLPropertySource(URL resource) {
         this(resource, 0);
     }
 
@@ -75,19 +54,15 @@ public class JSONPropertySource implements PropertySource {
      * @param resource the resource modelled as URL, not null.
      * @param defaultOrdinal the defaultOrdinal to be used.
      */
-    public JSONPropertySource(URL resource, int defaultOrdinal) {
+    public YAMLPropertySource(URL resource, int defaultOrdinal) {
         urlResource = Objects.requireNonNull(resource);
         this.ordinal = defaultOrdinal; // may be overriden by read...
-        this.values = readConfig(urlResource);
+        this.values = format.readConfig(urlResource);
         if (this.values.containsKey(TAMAYA_ORDINAL)) {
             this.ordinal = Integer.parseInt(this.values.get(TAMAYA_ORDINAL));
         }
-        Map<String, Object> config = new HashMap<>();
-        config.put(JOHNZON_SUPPORTS_COMMENTS_PROP, true);
-        this.readerFactory = Json.createReaderFactory(config);
     }
 
-
     @Override
     public int getOrdinal() {
         PropertyValue configuredOrdinal = get(TAMAYA_ORDINAL);
@@ -117,30 +92,6 @@ public class JSONPropertySource implements PropertySource {
         return Collections.unmodifiableMap(values);
     }
 
-    /**
-     * Reads the configuration.
-     * @param urlResource soure of the configuration.
-     * @return the configuration read from the given resource URL.
-     * @throws ConfigException if resource URL cannot be read.
-     */
-    protected Map<String, String> readConfig(URL urlResource) {
-        try (InputStream is = urlResource.openStream()) {
-            JsonStructure root = this.readerFactory.createReader(is, Charset.forName("UTF-8")).read();
-
-            // Test added. H. Saly, 15. Aug. 2015
-            if (!(root instanceof JsonObject)) {
-                throw new ConfigException("Currently only JSON objects are supported");
-            }
-
-            Map<String, String> values = new HashMap<>();
-            JSONVisitor visitor = new JSONVisitor((JsonObject)root, values);
-            visitor.run();
-            return values;
-        }
-        catch (Throwable t) {
-            throw new ConfigException(format("Failed to read properties from %s", urlResource.toExternalForm()), t);
-        }
-    }
 
     @Override
     public boolean isScannable() {

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/60e8827f/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLFormatTest.java
----------------------------------------------------------------------
diff --git a/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLFormatTest.java b/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLFormatTest.java
index dc24048..0f0e589 100644
--- a/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLFormatTest.java
+++ b/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLFormatTest.java
@@ -24,52 +24,50 @@ import org.apache.tamaya.format.FlattenedDefaultPropertySource;
 import org.apache.tamaya.spi.PropertySource;
 import org.junit.Test;
 
+import java.io.IOException;
 import java.io.InputStream;
+import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.Map;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
-public class YAMLFormatTest extends CommonJSONTestCaseCollection {
-    private final JSONFormat format = new JSONFormat();
-
-    @Test(expected = NullPointerException.class)
-    public void acceptsNeedsNonNullParameter() throws Exception {
-        format.accepts(null);
-    }
+public class YAMLFormatTest {
+    private final YAMLFormat format = new YAMLFormat();
 
     @Test
-    public void aNonJSONFileBasedURLIsNotAccepted() throws Exception {
-        URL url = new URL("file:///etc/service/conf.conf");
-
-        assertThat(format.accepts(url), is(false));
+    public void testAcceptURL() throws MalformedURLException {
+        assertTrue(format.accepts(new URL("http://127.0.0.1/anyfile.yaml")));
     }
 
     @Test
-    public void aJSONFileBasedURLIsAccepted() throws Exception {
-        URL url = new URL("file:///etc/service/conf.json");
-
-        assertThat(format.accepts(url), is(true));
+    public void testAcceptURL_BC1() throws MalformedURLException {
+        assertFalse(format.accepts(new URL("http://127.0.0.1/anyfile.YAML")));
     }
 
-    @Test
-    public void aHTTPBasedURLIsNotAccepted() throws Exception {
-        URL url = new URL("http://nowhere.somewhere/conf.json");
-        assertThat(format.accepts(url), is(true));
+    @Test(expected = NullPointerException.class)
+    public void testAcceptURL_BC2() throws MalformedURLException {
+        assertFalse(format.accepts(null));
     }
 
     @Test
-    public void aFTPBasedURLIsNotAccepted() throws Exception {
-        URL url = new URL("ftp://nowhere.somewhere/a/b/c/d/conf.json");
-
-        assertThat(format.accepts(url), is(true));
+    public void testAcceptURL_BC3() throws MalformedURLException {
+        assertFalse(format.accepts(new URL("http://127.0.0.1/anyfile.docx")));
     }
 
-    @Override
-    PropertySource getPropertiesFrom(URL source) throws Exception {
-        try (InputStream is = source.openStream()) {
-            ConfigurationData data = format.readConfiguration(source.toString(), is);
-            return new FlattenedDefaultPropertySource(data);
+    @Test
+    public void testRead() throws IOException {
+        URL configURL = YAMLPropertySourceTest.class.getResource("/configs/valid/contact.yaml");
+        assertTrue(format.accepts(configURL));
+        ConfigurationData data = format.readConfiguration(configURL.toString(), configURL.openStream());
+        assertNotNull(data);
+        for(Map.Entry<String,String> en:data.getDefaultProperties().entrySet()) {
+            System.out.println(en.getKey() + " -> " + en.getValue());
         }
     }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/60e8827f/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLPropertySourceTest.java b/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLPropertySourceTest.java
index a15f553..7f1c7a3 100644
--- a/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLPropertySourceTest.java
+++ b/modules/yaml/src/test/java/org/apache/tamaya/json/YAMLPropertySourceTest.java
@@ -28,29 +28,27 @@ import java.net.URL;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
-public class YAMLPropertySourceTest extends CommonJSONTestCaseCollection {
+public class YAMLPropertySourceTest {
 
     @Test
-    public void tamayaOrdinalKeywordIsNotPropagatedAsNormalProperty() throws Exception {
-        URL configURL = YAMLPropertySourceTest.class.getResource("/configs/valid/with-explicit-priority.json");
+    public void testYamlWithOrdinal() throws Exception {
+        URL configURL = YAMLPropertySourceTest.class.getResource("/configs/valid/test-with-prio.yaml");
 
         assertThat(configURL, CoreMatchers.notNullValue());
 
-        JSONPropertySource source = new JSONPropertySource(configURL, 4);
-        assertEquals(source.get(PropertySource.TAMAYA_ORDINAL).getValue(), "16784");
+        YAMLPropertySource source = new YAMLPropertySource(configURL, 4);
+        assertEquals(source.getOrdinal(), 16784);
     }
     
-    @Test(expected=ConfigException.class)
-    public void testDoNotAcceptJsonArrays() throws Exception {
-        URL configURL = YAMLPropertySourceTest.class.getResource("/configs/invalid/array.json");
+    @Test
+    public void testYamlDefaultOrdinal() throws Exception {
+        URL configURL = YAMLPropertySourceTest.class.getResource("/configs/valid/test.yaml");
 
         assertThat(configURL, CoreMatchers.notNullValue());
 
-        new JSONPropertySource(configURL);
+        YAMLPropertySource source = new YAMLPropertySource(configURL, 4);
+        assertEquals(source.getOrdinal(), 4);
     }
 
-    @Override
-    PropertySource getPropertiesFrom(URL source) throws Exception {
-        return new JSONPropertySource(source);
-    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/60e8827f/modules/yaml/src/test/resources/configs/valid/contact.yaml
----------------------------------------------------------------------
diff --git a/modules/yaml/src/test/resources/configs/valid/contact.yaml b/modules/yaml/src/test/resources/configs/valid/contact.yaml
index 32eca23..95d5a03 100644
--- a/modules/yaml/src/test/resources/configs/valid/contact.yaml
+++ b/modules/yaml/src/test/resources/configs/valid/contact.yaml
@@ -1,4 +1,21 @@
--- !clarkevans.com/^invoice
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
 invoice: 34843
 date   : 2001-01-23
 bill-to: &id001

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/60e8827f/modules/yaml/src/test/resources/configs/valid/test-with-prio.yaml
----------------------------------------------------------------------
diff --git a/modules/yaml/src/test/resources/configs/valid/test-with-prio.yaml b/modules/yaml/src/test/resources/configs/valid/test-with-prio.yaml
index 697e9f3..05b5dbf 100644
--- a/modules/yaml/src/test/resources/configs/valid/test-with-prio.yaml
+++ b/modules/yaml/src/test/resources/configs/valid/test-with-prio.yaml
@@ -19,6 +19,10 @@
 version: 1.0
 released: 2012-11-30
 
+# tamaya specifics...
+tamaya:
+    ordinal: 16784
+
 # Connection parameters
 connection:
     url: jdbc:mysql://localhost:3306/db