You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by pl...@apache.org on 2015/01/06 22:30:41 UTC

incubator-tamaya git commit: TAMAYA-39 Moved the property source for JSON based configurations to the modules module.

Repository: incubator-tamaya
Updated Branches:
  refs/heads/master 817dca2c8 -> 75c565676


TAMAYA-39 Moved the property source for JSON based configurations to the modules module.


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

Branch: refs/heads/master
Commit: 75c5656768c7cdc7fc262675c4628900daba85c7
Parents: 817dca2
Author: Oliver B. Fischer <pl...@apache.org>
Authored: Tue Jan 6 22:29:19 2015 +0100
Committer: Oliver B. Fischer <pl...@apache.org>
Committed: Tue Jan 6 22:29:19 2015 +0100

----------------------------------------------------------------------
 extras/json/pom.xml                             |  63 ---------
 .../tamaya/extras/json/FileBasedResource.java   |  50 -------
 .../tamaya/extras/json/InputResource.java       |  27 ----
 .../tamaya/extras/json/JSONPropertySource.java  | 104 --------------
 .../apache/tamaya/extras/json/JSONVisitor.java  |  98 -------------
 .../extras/json/JSONPropertySourceTest.java     | 137 -------------------
 .../resources/configs/valid/empty-file.json     |   0
 .../configs/valid/empty-object-config.json      |   2 -
 .../valid/simple-flat-string-only-config.json   |   5 -
 .../simple-nested-string-only-config-1.json     |   9 --
 .../simple-nested-string-only-config-2.json     |   8 --
 extras/pom.xml                                  |   5 +-
 modules/json/pom.xml                            |  63 +++++++++
 .../tamaya/extras/json/FileBasedResource.java   |  50 +++++++
 .../tamaya/extras/json/InputResource.java       |  27 ++++
 .../tamaya/extras/json/JSONPropertySource.java  | 104 ++++++++++++++
 .../apache/tamaya/extras/json/JSONVisitor.java  |  98 +++++++++++++
 .../extras/json/JSONPropertySourceTest.java     | 137 +++++++++++++++++++
 .../resources/configs/valid/empty-file.json     |   0
 .../configs/valid/empty-object-config.json      |   2 +
 .../valid/simple-flat-string-only-config.json   |   5 +
 .../simple-nested-string-only-config-1.json     |   9 ++
 .../simple-nested-string-only-config-2.json     |   8 ++
 modules/pom.xml                                 |   1 +
 24 files changed, 505 insertions(+), 507 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/extras/json/pom.xml
----------------------------------------------------------------------
diff --git a/extras/json/pom.xml b/extras/json/pom.xml
deleted file mode 100644
index 7dd3298..0000000
--- a/extras/json/pom.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.tamaya</groupId>
-        <artifactId>extras</artifactId>
-        <version>0.2-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>json</artifactId>
-    <name>Apache Tamaya JSON Support</name>
-    <inceptionYear>2015</inceptionYear>
-
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.tamaya</groupId>
-            <artifactId>tamaya-api</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-databind</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-core</artifactId>
-        </dependency>
-
-
-    </dependencies>
-    
-</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/extras/json/src/main/java/org/apache/tamaya/extras/json/FileBasedResource.java
----------------------------------------------------------------------
diff --git a/extras/json/src/main/java/org/apache/tamaya/extras/json/FileBasedResource.java b/extras/json/src/main/java/org/apache/tamaya/extras/json/FileBasedResource.java
deleted file mode 100644
index 1ba1306..0000000
--- a/extras/json/src/main/java/org/apache/tamaya/extras/json/FileBasedResource.java
+++ /dev/null
@@ -1,50 +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.extras.json;
-
-import org.apache.tamaya.ConfigException;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-public class FileBasedResource implements InputResource {
-    private final File sourceFile;
-
-    public FileBasedResource(File file) {
-        sourceFile = file;
-    }
-
-
-    @Override
-    public InputStream getInputStream() {
-        try {
-            return new FileInputStream(sourceFile);
-        } catch (IOException ioe) {
-            String msg = String.format("Failed to open file %s", getDescription());
-            throw new ConfigException(msg, ioe);
-        }
-    }
-
-    @Override
-    public CharSequence getDescription() {
-        return sourceFile.toURI().toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/extras/json/src/main/java/org/apache/tamaya/extras/json/InputResource.java
----------------------------------------------------------------------
diff --git a/extras/json/src/main/java/org/apache/tamaya/extras/json/InputResource.java b/extras/json/src/main/java/org/apache/tamaya/extras/json/InputResource.java
deleted file mode 100644
index 4868689..0000000
--- a/extras/json/src/main/java/org/apache/tamaya/extras/json/InputResource.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.extras.json;
-
-import java.io.InputStream;
-
-public interface InputResource {
-    InputStream getInputStream();
-
-    CharSequence getDescription();
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/extras/json/src/main/java/org/apache/tamaya/extras/json/JSONPropertySource.java
----------------------------------------------------------------------
diff --git a/extras/json/src/main/java/org/apache/tamaya/extras/json/JSONPropertySource.java b/extras/json/src/main/java/org/apache/tamaya/extras/json/JSONPropertySource.java
deleted file mode 100644
index 7e6487c..0000000
--- a/extras/json/src/main/java/org/apache/tamaya/extras/json/JSONPropertySource.java
+++ /dev/null
@@ -1,104 +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.extras.json;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.spi.PropertySource;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-
-import static java.lang.String.format;
-
-public class JSONPropertySource
-    implements PropertySource {
-    private int priority = 0;
-    private InputResource source;
-    private HashMap<String, String> values;
-
-    public JSONPropertySource(File file, int priority) {
-        this.priority = priority;
-        source = new FileBasedResource(file);
-    }
-
-    @Override
-    public int getOrdinal() {
-        return priority;
-    }
-
-    @Override
-    public String getName() {
-        // @todo Implement me
-        throw new RuntimeException("Not implemented yet.");
-    }
-
-    @Override
-    public Optional<String> get(String key) {
-        Objects.requireNonNull(key, "Key must not be null");
-
-        return Optional.ofNullable(getProperties().get(key));
-    }
-
-    @Override
-    public Map<String, String> getProperties() {
-        synchronized (this) {
-            if (values == null) {
-                readSource();
-            }
-        }
-
-        return Collections.unmodifiableMap(values);
-    }
-
-    protected void readSource() {
-        try (InputStream is = source.getInputStream()) {
-            ObjectMapper mapper = new ObjectMapper();
-            JsonNode root = mapper.readTree(is);
-
-            // @todo Add test for this. Oliver B. Fischer, 5. Jan. 2015
-            if (!(root instanceof ObjectNode)) {
-                throw new ConfigException("Currently only JSON objects are supported");
-            }
-
-            HashMap<String, String> values = new HashMap<>();
-            JSONVisitor visitor = new JSONVisitor((ObjectNode) root, values);
-            visitor.run();
-
-            this.values = values;
-        }
-        catch (Throwable t) {
-            throw new ConfigException(format("Failed to read properties from %s", source.getDescription()), t);
-        }
-
-    }
-
-    @Override
-    public boolean isScannable() {
-        // @todo Implement me
-        throw new RuntimeException("Not implemented yet.");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/extras/json/src/main/java/org/apache/tamaya/extras/json/JSONVisitor.java
----------------------------------------------------------------------
diff --git a/extras/json/src/main/java/org/apache/tamaya/extras/json/JSONVisitor.java b/extras/json/src/main/java/org/apache/tamaya/extras/json/JSONVisitor.java
deleted file mode 100644
index 15bf16b..0000000
--- a/extras/json/src/main/java/org/apache/tamaya/extras/json/JSONVisitor.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.extras.json;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fasterxml.jackson.databind.node.ValueNode;
-import org.apache.tamaya.ConfigException;
-
-import java.util.*;
-
-public class JSONVisitor {
-    private final ObjectNode rootNode;
-    private final HashMap<String, String> targetStore;
-
-    public JSONVisitor(ObjectNode startNode, HashMap<String, String> target) {
-        rootNode = startNode;
-        targetStore = target;
-    }
-
-    public void run() {
-        Deque<VisitingContext> stack = new ArrayDeque<>();
-
-        stack.add(new VisitingContext(rootNode));
-        boolean goOn = stack.peek().hasNext();
-
-        if (goOn) {
-            do {
-                Map.Entry<String, JsonNode> current = stack.peek().nextElement();
-
-                if (current.getValue() instanceof ValueNode) {
-                    String key = stack.peek().getNSPrefix() + current.getKey();
-                    String value = current.getValue().asText();
-                    targetStore.put(key, value);
-                } else if (current.getValue() instanceof ObjectNode) {
-                    String key = stack.peek().getNSPrefix() + current.getKey();
-                    ObjectNode node = (ObjectNode) current.getValue();
-                    stack.push(new VisitingContext(node, key));
-                } else {
-                    throw new ConfigException("Internal failure while processing JSON document.");
-                }
-
-                goOn = stack.peek().hasNext();
-
-                while (!goOn && stack.size() > 0) {
-                    stack.remove();
-                    goOn = stack.size() > 0 ? stack.peek().hasNext() : false;
-                }
-            } while (goOn);
-        }
-    }
-
-    private class VisitingContext {
-        private String namespace;
-        private final ObjectNode node;
-        private final Iterator<Map.Entry<String, JsonNode>> elements;
-
-        public VisitingContext(ObjectNode node) {
-            this(node, "");
-        }
-
-        public VisitingContext(ObjectNode rootNode, String currentNamespace) {
-            namespace = currentNamespace;
-            node = rootNode;
-            elements = node.fields();
-        }
-
-        public Map.Entry<String, JsonNode> nextElement() {
-            return elements.next();
-        }
-
-
-        public boolean hasNext() {
-            boolean hasNext = elements.hasNext();
-            return hasNext;
-        }
-
-        public String getNSPrefix() {
-            return namespace.isEmpty() ? namespace : namespace + ".";
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/extras/json/src/test/java/org/apache/tamaya/extras/json/JSONPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/extras/json/src/test/java/org/apache/tamaya/extras/json/JSONPropertySourceTest.java b/extras/json/src/test/java/org/apache/tamaya/extras/json/JSONPropertySourceTest.java
deleted file mode 100644
index 65c709f..0000000
--- a/extras/json/src/test/java/org/apache/tamaya/extras/json/JSONPropertySourceTest.java
+++ /dev/null
@@ -1,137 +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.extras.json;
-
-import org.apache.tamaya.ConfigException;
-import org.hamcrest.CoreMatchers;
-import org.junit.Test;
-
-import java.io.File;
-import java.net.URL;
-import java.util.Optional;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.hasSize;
-
-public class JSONPropertySourceTest {
-
-    @Test(expected = ConfigException.class)
-    public void emptyJSONFileResultsInConfigException() throws Exception {
-        URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/empty-file.json");
-
-        assertThat(configURL, CoreMatchers.notNullValue());
-
-        File configFile = new File(configURL.toURI());
-
-        JSONPropertySource source = new JSONPropertySource(configFile, 10);
-
-        source.getProperties();
-    }
-
-    @Test
-    public void canHandleEmptyJSONObject() throws Exception {
-        URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/empty-object-config.json");
-
-        assertThat(configURL, CoreMatchers.notNullValue());
-
-        File configFile = new File(configURL.toURI());
-
-        JSONPropertySource source = new JSONPropertySource(configFile, 10);
-
-        assertThat(source.getProperties().keySet(), hasSize(0));
-    }
-
-    @Test
-    public void canReadFlatStringOnlyJSONConfigFile() throws Exception {
-        URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/simple-flat-string-only-config.json");
-
-        assertThat(configURL, CoreMatchers.notNullValue());
-
-        File configFile = new File(configURL.toURI());
-
-        JSONPropertySource source = new JSONPropertySource(configFile, 10);
-
-        assertThat(source.getProperties().keySet(), hasSize(3));
-
-        Optional<String> keyA = source.get("a");
-        Optional<String> keyB = source.get("b");
-        Optional<String> keyC = source.get("c");
-
-        assertThat(keyA.isPresent(), is(true));
-        assertThat(keyA.get(), equalTo("A"));
-        assertThat(keyB.isPresent(), is(true));
-        assertThat(keyB.get(), is("B"));
-        assertThat(keyC.isPresent(), is(true));
-        assertThat(keyC.get(), is("C"));
-    }
-
-    @Test
-    public void canReadNestedStringOnlyJSONConfigFile() throws Exception {
-        URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/simple-nested-string-only-config-1.json");
-
-        assertThat(configURL, CoreMatchers.notNullValue());
-
-        File configFile = new File(configURL.toURI());
-
-        JSONPropertySource source = new JSONPropertySource(configFile, 10);
-
-        assertThat(source.getProperties().keySet(), hasSize(5));
-
-        Optional<String> keyb = source.get("b");
-        Optional<String> keyDO = source.get("d.o");
-        Optional<String> keyDP = source.get("d.p");
-
-        assertThat(keyb.isPresent(), is(true));
-        assertThat(keyb.get(), equalTo("B"));
-        assertThat(keyDO.isPresent(), is(true));
-        assertThat(keyDO.get(), equalTo("O"));
-        assertThat(keyDP.isPresent(), is(true));
-        assertThat(keyDP.get(), is("P"));
-    }
-
-    @Test
-    public void canReadNestedStringOnlyJSONConfigFileWithObjectInTheMiddle()
-            throws Exception {
-        URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/simple-nested-string-only-config-2.json");
-
-        assertThat(configURL, CoreMatchers.notNullValue());
-
-        File configFile = new File(configURL.toURI());
-
-        JSONPropertySource source = new JSONPropertySource(configFile, 10);
-
-        assertThat(source.getProperties().keySet(), hasSize(4));
-
-        Optional<String> keyA = source.get("a");
-        Optional<String> keyDO = source.get("b.o");
-        Optional<String> keyDP = source.get("b.p");
-        Optional<String> keyC = source.get("c");
-
-        assertThat(keyA.isPresent(), is(true));
-        assertThat(keyA.get(), is("A"));
-        assertThat(keyC.isPresent(), is(true));
-        assertThat(keyC.get(), equalTo("C"));
-        assertThat(keyDO.isPresent(), is(true));
-        assertThat(keyDO.get(), equalTo("O"));
-        assertThat(keyDP.isPresent(), is(true));
-        assertThat(keyDP.get(), is("P"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/extras/json/src/test/resources/configs/valid/empty-file.json
----------------------------------------------------------------------
diff --git a/extras/json/src/test/resources/configs/valid/empty-file.json b/extras/json/src/test/resources/configs/valid/empty-file.json
deleted file mode 100644
index e69de29..0000000

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/extras/json/src/test/resources/configs/valid/empty-object-config.json
----------------------------------------------------------------------
diff --git a/extras/json/src/test/resources/configs/valid/empty-object-config.json b/extras/json/src/test/resources/configs/valid/empty-object-config.json
deleted file mode 100644
index 7a73a41..0000000
--- a/extras/json/src/test/resources/configs/valid/empty-object-config.json
+++ /dev/null
@@ -1,2 +0,0 @@
-{
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/extras/json/src/test/resources/configs/valid/simple-flat-string-only-config.json
----------------------------------------------------------------------
diff --git a/extras/json/src/test/resources/configs/valid/simple-flat-string-only-config.json b/extras/json/src/test/resources/configs/valid/simple-flat-string-only-config.json
deleted file mode 100644
index c8ea179..0000000
--- a/extras/json/src/test/resources/configs/valid/simple-flat-string-only-config.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "a" : "A",
-  "b" : "B",
-  "c" : "C"
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/extras/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json
----------------------------------------------------------------------
diff --git a/extras/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json b/extras/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json
deleted file mode 100644
index 89df957..0000000
--- a/extras/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "a" : "A",
-  "b" : "B",
-  "c" : "C",
-  "d" : {
-    "o" : "O",
-    "p" : "P"
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/extras/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json
----------------------------------------------------------------------
diff --git a/extras/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json b/extras/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json
deleted file mode 100644
index c275153..0000000
--- a/extras/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "a" : "A",
-  "b" : {
-    "o" : "O",
-    "p" : "P"
-  },
-  "c" : "C"
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/extras/pom.xml
----------------------------------------------------------------------
diff --git a/extras/pom.xml b/extras/pom.xml
index ff81857..91e16dc 100644
--- a/extras/pom.xml
+++ b/extras/pom.xml
@@ -34,8 +34,5 @@ under the License.
     <packaging>pom</packaging>
     <inceptionYear>2015</inceptionYear>
 
-    <modules>
-        <module>json</module>
-    </modules>
-    
+
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/modules/json/pom.xml
----------------------------------------------------------------------
diff --git a/modules/json/pom.xml b/modules/json/pom.xml
new file mode 100644
index 0000000..f40fcb5
--- /dev/null
+++ b/modules/json/pom.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>tamaya-extensions</artifactId>
+        <groupId>org.apache.tamaya.ext</groupId>
+        <version>0.2-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>json</artifactId>
+    <name>Apache Tamaya JSON Support</name>
+    <inceptionYear>2015</inceptionYear>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-library</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-core</artifactId>
+        </dependency>
+
+
+    </dependencies>
+    
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/modules/json/src/main/java/org/apache/tamaya/extras/json/FileBasedResource.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/tamaya/extras/json/FileBasedResource.java b/modules/json/src/main/java/org/apache/tamaya/extras/json/FileBasedResource.java
new file mode 100644
index 0000000..1ba1306
--- /dev/null
+++ b/modules/json/src/main/java/org/apache/tamaya/extras/json/FileBasedResource.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.extras.json;
+
+import org.apache.tamaya.ConfigException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class FileBasedResource implements InputResource {
+    private final File sourceFile;
+
+    public FileBasedResource(File file) {
+        sourceFile = file;
+    }
+
+
+    @Override
+    public InputStream getInputStream() {
+        try {
+            return new FileInputStream(sourceFile);
+        } catch (IOException ioe) {
+            String msg = String.format("Failed to open file %s", getDescription());
+            throw new ConfigException(msg, ioe);
+        }
+    }
+
+    @Override
+    public CharSequence getDescription() {
+        return sourceFile.toURI().toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/modules/json/src/main/java/org/apache/tamaya/extras/json/InputResource.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/tamaya/extras/json/InputResource.java b/modules/json/src/main/java/org/apache/tamaya/extras/json/InputResource.java
new file mode 100644
index 0000000..4868689
--- /dev/null
+++ b/modules/json/src/main/java/org/apache/tamaya/extras/json/InputResource.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.
+ */
+package org.apache.tamaya.extras.json;
+
+import java.io.InputStream;
+
+public interface InputResource {
+    InputStream getInputStream();
+
+    CharSequence getDescription();
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/modules/json/src/main/java/org/apache/tamaya/extras/json/JSONPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/tamaya/extras/json/JSONPropertySource.java b/modules/json/src/main/java/org/apache/tamaya/extras/json/JSONPropertySource.java
new file mode 100644
index 0000000..7e6487c
--- /dev/null
+++ b/modules/json/src/main/java/org/apache/tamaya/extras/json/JSONPropertySource.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.extras.json;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertySource;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+import static java.lang.String.format;
+
+public class JSONPropertySource
+    implements PropertySource {
+    private int priority = 0;
+    private InputResource source;
+    private HashMap<String, String> values;
+
+    public JSONPropertySource(File file, int priority) {
+        this.priority = priority;
+        source = new FileBasedResource(file);
+    }
+
+    @Override
+    public int getOrdinal() {
+        return priority;
+    }
+
+    @Override
+    public String getName() {
+        // @todo Implement me
+        throw new RuntimeException("Not implemented yet.");
+    }
+
+    @Override
+    public Optional<String> get(String key) {
+        Objects.requireNonNull(key, "Key must not be null");
+
+        return Optional.ofNullable(getProperties().get(key));
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        synchronized (this) {
+            if (values == null) {
+                readSource();
+            }
+        }
+
+        return Collections.unmodifiableMap(values);
+    }
+
+    protected void readSource() {
+        try (InputStream is = source.getInputStream()) {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode root = mapper.readTree(is);
+
+            // @todo Add test for this. Oliver B. Fischer, 5. Jan. 2015
+            if (!(root instanceof ObjectNode)) {
+                throw new ConfigException("Currently only JSON objects are supported");
+            }
+
+            HashMap<String, String> values = new HashMap<>();
+            JSONVisitor visitor = new JSONVisitor((ObjectNode) root, values);
+            visitor.run();
+
+            this.values = values;
+        }
+        catch (Throwable t) {
+            throw new ConfigException(format("Failed to read properties from %s", source.getDescription()), t);
+        }
+
+    }
+
+    @Override
+    public boolean isScannable() {
+        // @todo Implement me
+        throw new RuntimeException("Not implemented yet.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/modules/json/src/main/java/org/apache/tamaya/extras/json/JSONVisitor.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/tamaya/extras/json/JSONVisitor.java b/modules/json/src/main/java/org/apache/tamaya/extras/json/JSONVisitor.java
new file mode 100644
index 0000000..15bf16b
--- /dev/null
+++ b/modules/json/src/main/java/org/apache/tamaya/extras/json/JSONVisitor.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.extras.json;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.node.ValueNode;
+import org.apache.tamaya.ConfigException;
+
+import java.util.*;
+
+public class JSONVisitor {
+    private final ObjectNode rootNode;
+    private final HashMap<String, String> targetStore;
+
+    public JSONVisitor(ObjectNode startNode, HashMap<String, String> target) {
+        rootNode = startNode;
+        targetStore = target;
+    }
+
+    public void run() {
+        Deque<VisitingContext> stack = new ArrayDeque<>();
+
+        stack.add(new VisitingContext(rootNode));
+        boolean goOn = stack.peek().hasNext();
+
+        if (goOn) {
+            do {
+                Map.Entry<String, JsonNode> current = stack.peek().nextElement();
+
+                if (current.getValue() instanceof ValueNode) {
+                    String key = stack.peek().getNSPrefix() + current.getKey();
+                    String value = current.getValue().asText();
+                    targetStore.put(key, value);
+                } else if (current.getValue() instanceof ObjectNode) {
+                    String key = stack.peek().getNSPrefix() + current.getKey();
+                    ObjectNode node = (ObjectNode) current.getValue();
+                    stack.push(new VisitingContext(node, key));
+                } else {
+                    throw new ConfigException("Internal failure while processing JSON document.");
+                }
+
+                goOn = stack.peek().hasNext();
+
+                while (!goOn && stack.size() > 0) {
+                    stack.remove();
+                    goOn = stack.size() > 0 ? stack.peek().hasNext() : false;
+                }
+            } while (goOn);
+        }
+    }
+
+    private class VisitingContext {
+        private String namespace;
+        private final ObjectNode node;
+        private final Iterator<Map.Entry<String, JsonNode>> elements;
+
+        public VisitingContext(ObjectNode node) {
+            this(node, "");
+        }
+
+        public VisitingContext(ObjectNode rootNode, String currentNamespace) {
+            namespace = currentNamespace;
+            node = rootNode;
+            elements = node.fields();
+        }
+
+        public Map.Entry<String, JsonNode> nextElement() {
+            return elements.next();
+        }
+
+
+        public boolean hasNext() {
+            boolean hasNext = elements.hasNext();
+            return hasNext;
+        }
+
+        public String getNSPrefix() {
+            return namespace.isEmpty() ? namespace : namespace + ".";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/modules/json/src/test/java/org/apache/tamaya/extras/json/JSONPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/modules/json/src/test/java/org/apache/tamaya/extras/json/JSONPropertySourceTest.java b/modules/json/src/test/java/org/apache/tamaya/extras/json/JSONPropertySourceTest.java
new file mode 100644
index 0000000..65c709f
--- /dev/null
+++ b/modules/json/src/test/java/org/apache/tamaya/extras/json/JSONPropertySourceTest.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.extras.json;
+
+import org.apache.tamaya.ConfigException;
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+
+import java.io.File;
+import java.net.URL;
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+
+public class JSONPropertySourceTest {
+
+    @Test(expected = ConfigException.class)
+    public void emptyJSONFileResultsInConfigException() throws Exception {
+        URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/empty-file.json");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        File configFile = new File(configURL.toURI());
+
+        JSONPropertySource source = new JSONPropertySource(configFile, 10);
+
+        source.getProperties();
+    }
+
+    @Test
+    public void canHandleEmptyJSONObject() throws Exception {
+        URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/empty-object-config.json");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        File configFile = new File(configURL.toURI());
+
+        JSONPropertySource source = new JSONPropertySource(configFile, 10);
+
+        assertThat(source.getProperties().keySet(), hasSize(0));
+    }
+
+    @Test
+    public void canReadFlatStringOnlyJSONConfigFile() throws Exception {
+        URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/simple-flat-string-only-config.json");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        File configFile = new File(configURL.toURI());
+
+        JSONPropertySource source = new JSONPropertySource(configFile, 10);
+
+        assertThat(source.getProperties().keySet(), hasSize(3));
+
+        Optional<String> keyA = source.get("a");
+        Optional<String> keyB = source.get("b");
+        Optional<String> keyC = source.get("c");
+
+        assertThat(keyA.isPresent(), is(true));
+        assertThat(keyA.get(), equalTo("A"));
+        assertThat(keyB.isPresent(), is(true));
+        assertThat(keyB.get(), is("B"));
+        assertThat(keyC.isPresent(), is(true));
+        assertThat(keyC.get(), is("C"));
+    }
+
+    @Test
+    public void canReadNestedStringOnlyJSONConfigFile() throws Exception {
+        URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/simple-nested-string-only-config-1.json");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        File configFile = new File(configURL.toURI());
+
+        JSONPropertySource source = new JSONPropertySource(configFile, 10);
+
+        assertThat(source.getProperties().keySet(), hasSize(5));
+
+        Optional<String> keyb = source.get("b");
+        Optional<String> keyDO = source.get("d.o");
+        Optional<String> keyDP = source.get("d.p");
+
+        assertThat(keyb.isPresent(), is(true));
+        assertThat(keyb.get(), equalTo("B"));
+        assertThat(keyDO.isPresent(), is(true));
+        assertThat(keyDO.get(), equalTo("O"));
+        assertThat(keyDP.isPresent(), is(true));
+        assertThat(keyDP.get(), is("P"));
+    }
+
+    @Test
+    public void canReadNestedStringOnlyJSONConfigFileWithObjectInTheMiddle()
+            throws Exception {
+        URL configURL = JSONPropertySourceTest.class.getResource("/configs/valid/simple-nested-string-only-config-2.json");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        File configFile = new File(configURL.toURI());
+
+        JSONPropertySource source = new JSONPropertySource(configFile, 10);
+
+        assertThat(source.getProperties().keySet(), hasSize(4));
+
+        Optional<String> keyA = source.get("a");
+        Optional<String> keyDO = source.get("b.o");
+        Optional<String> keyDP = source.get("b.p");
+        Optional<String> keyC = source.get("c");
+
+        assertThat(keyA.isPresent(), is(true));
+        assertThat(keyA.get(), is("A"));
+        assertThat(keyC.isPresent(), is(true));
+        assertThat(keyC.get(), equalTo("C"));
+        assertThat(keyDO.isPresent(), is(true));
+        assertThat(keyDO.get(), equalTo("O"));
+        assertThat(keyDP.isPresent(), is(true));
+        assertThat(keyDP.get(), is("P"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/modules/json/src/test/resources/configs/valid/empty-file.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/valid/empty-file.json b/modules/json/src/test/resources/configs/valid/empty-file.json
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/modules/json/src/test/resources/configs/valid/empty-object-config.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/valid/empty-object-config.json b/modules/json/src/test/resources/configs/valid/empty-object-config.json
new file mode 100644
index 0000000..7a73a41
--- /dev/null
+++ b/modules/json/src/test/resources/configs/valid/empty-object-config.json
@@ -0,0 +1,2 @@
+{
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/modules/json/src/test/resources/configs/valid/simple-flat-string-only-config.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/valid/simple-flat-string-only-config.json b/modules/json/src/test/resources/configs/valid/simple-flat-string-only-config.json
new file mode 100644
index 0000000..c8ea179
--- /dev/null
+++ b/modules/json/src/test/resources/configs/valid/simple-flat-string-only-config.json
@@ -0,0 +1,5 @@
+{
+  "a" : "A",
+  "b" : "B",
+  "c" : "C"
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json b/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json
new file mode 100644
index 0000000..89df957
--- /dev/null
+++ b/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-1.json
@@ -0,0 +1,9 @@
+{
+  "a" : "A",
+  "b" : "B",
+  "c" : "C",
+  "d" : {
+    "o" : "O",
+    "p" : "P"
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json
----------------------------------------------------------------------
diff --git a/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json b/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json
new file mode 100644
index 0000000..c275153
--- /dev/null
+++ b/modules/json/src/test/resources/configs/valid/simple-nested-string-only-config-2.json
@@ -0,0 +1,8 @@
+{
+  "a" : "A",
+  "b" : {
+    "o" : "O",
+    "p" : "P"
+  },
+  "c" : "C"
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/75c56567/modules/pom.xml
----------------------------------------------------------------------
diff --git a/modules/pom.xml b/modules/pom.xml
index a7e31e3..0f19d8b 100644
--- a/modules/pom.xml
+++ b/modules/pom.xml
@@ -35,6 +35,7 @@ under the License.
     <modules>
         <!-- module>injection</module -->
         <module>formats</module>
+        <module>json</module>
         <module>resolver</module>
         <module>resources</module>
         <!-- module>metamodels</module -->