Repository: incubator-tamaya-sandbox
Updated Branches:
  refs/heads/master f9bafb3b3 -> a829665e0


http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/server/src/test/java/org/apache/tamaya/server/ConfigServiceAppTest.java
----------------------------------------------------------------------
diff --git 
a/server/src/test/java/org/apache/tamaya/server/ConfigServiceAppTest.java 
b/server/src/test/java/org/apache/tamaya/server/ConfigServiceAppTest.java
new file mode 100644
index 0000000..5f7163d
--- /dev/null
+++ b/server/src/test/java/org/apache/tamaya/server/ConfigServiceAppTest.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.server;
+
+//import static org.junit.Assert.*;
+
+/**
+ * Created by atsticks on 22.01.16.
+ */
+public class ConfigServiceAppTest {
+
+//    @org.junit.Test
+//    public void testMain() throws Exception {
+//
+//    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/server/src/test/java/org/apache/tamaya/server/EtcdAccessor.java
----------------------------------------------------------------------
diff --git a/server/src/test/java/org/apache/tamaya/server/EtcdAccessor.java 
b/server/src/test/java/org/apache/tamaya/server/EtcdAccessor.java
new file mode 100644
index 0000000..1c8e94b
--- /dev/null
+++ b/server/src/test/java/org/apache/tamaya/server/EtcdAccessor.java
@@ -0,0 +1,519 @@
+///*
+// * Licensed to the Apache Software Foundation (ASF) under one
+// * or more contributor license agreements.  See the NOTICE file
+// * distributed with this work for additional information
+// * regarding copyright ownership.  The ASF licenses this file
+// * to you under the Apache License, Version 2.0 (the
+// * "License"); you may not use this file except in compliance
+// * with the License.  You may obtain a copy of the License at
+// *
+// *   http://www.apache.org/licenses/LICENSE-2.0
+// *
+// * Unless required by applicable law or agreed to in writing,
+// * software distributed under the License is distributed on an
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// * KIND, either express or implied.  See the License for the
+// * specific language governing permissions and limitations
+// * under the License.
+// */
+//package org.apache.tamaya.etcd;
+//
+//import org.apache.http.HttpEntity;
+//import org.apache.http.HttpStatus;
+//import org.apache.http.NameValuePair;
+//import org.apache.http.client.config.RequestConfig;
+//import org.apache.http.client.entity.UrlEncodedFormEntity;
+//import org.apache.http.client.methods.CloseableHttpResponse;
+//import org.apache.http.client.methods.HttpDelete;
+//import org.apache.http.client.methods.HttpGet;
+//import org.apache.http.client.methods.HttpPut;
+//import org.apache.http.impl.client.CloseableHttpClient;
+//import org.apache.http.impl.client.HttpClients;
+//import org.apache.http.message.BasicNameValuePair;
+//import org.apache.http.util.EntityUtils;
+//
+//import javax.json.Json;
+//import javax.json.JsonArray;
+//import javax.json.JsonObject;
+//import javax.json.JsonReader;
+//import javax.json.JsonReaderFactory;
+//import java.io.IOException;
+//import java.io.StringReader;
+//import java.util.ArrayList;
+//import java.util.HashMap;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.logging.Level;
+//import java.util.logging.Logger;
+//
+///**
+// * Accessor for reading/writing an etcd endpoint.
+// */
+//public class EtcdAccessor {
+//
+//    private static final Logger LOG = 
Logger.getLogger(EtcdAccessor.class.getName());
+//
+//    /** Timeout in seconds. */
+//    private int timeout = 2;
+//    /** Property that make Johnzon accept commentc. */
+//    public static final String JOHNZON_SUPPORTS_COMMENTS_PROP = 
"org.apache.johnzon.supports-comments";
+//    /** The JSON reader factory used. */
+//    private final 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 base server url. */
+//    private final String serverURL;
+//    /** The http client. */
+//    private CloseableHttpClient httpclient = HttpClients.createDefault();
+//
+//    /**
+//     * Creates a new instance with the basic access url.
+//     * @param server server url, e.g. {@code http://127.0.0.1:4001}, not 
null.
+//     */
+//    public EtcdAccessor(String server){
+//        this(server, 2);
+//    }
+//
+//    public EtcdAccessor(String server, int timeout) {
+//        this.timeout = timeout;
+//        if(server.endsWith("/")){
+//            serverURL = server.substring(0, server.length()-1);
+//        } else{
+//            serverURL = server;
+//        }
+//
+//    }
+//
+//    /**
+//     * Get the etcd server version.
+//     * @return the etcd server version, never null.
+//     */
+//    public String getVersion(){
+//        CloseableHttpResponse response = null;
+//        String version = "<ERROR>";
+//        try {
+//            CloseableHttpClient httpclient = HttpClients.createDefault();
+//            HttpGet httpGet = new HttpGet(serverURL + "/version");
+//            
httpGet.setConfig(RequestConfig.copy(RequestConfig.DEFAULT).setSocketTimeout(timeout)
+//                    
.setConnectionRequestTimeout(timeout).setConnectTimeout(timeout).build());
+//            response = httpclient.execute(httpGet);
+//            HttpEntity entity;
+//            if (response.getStatusLine().getStatusCode() == 
HttpStatus.SC_OK) {
+//                entity = response.getEntity();
+//                // and ensure it is fully consumed
+//                version = EntityUtils.toString(entity);
+//                EntityUtils.consume(entity);
+//            }
+//            return version;
+//        } catch(Exception e){
+//            LOG.log(Level.INFO, "Error getting etcd version from: " + 
serverURL, e);
+//        } finally {
+//            if(response!=null){
+//                try {
+//                    response.close();
+//                } catch (IOException e) {
+//                    LOG.log(Level.WARNING, "Failed to close http response", 
e);
+//                }
+//            }
+//        }
+//        return version;
+//    }
+//
+//    /**
+//     * Ask etcd for s aingle key, value pair. Hereby the response returned 
from etcd:
+//     * <pre>
+//     * {
+//         "action": "get",
+//         "node": {
+//         "createdIndex": 2,
+//         "key": "/message",
+//         "modifiedIndex": 2,
+//         "value": "Hello world"
+//         }
+//     * }
+//     * </pre>
+//     * is mapped to:
+//     * <pre>
+//     *     key=value
+//     *     _key.source=[etcd]http://127.0.0.1:4001
+//     *     _key.createdIndex=12
+//     *     _key.modifiedIndex=34
+//     *     _key.ttl=300
+//     *     _key.expiration=...
+//     * </pre>
+//     * @param key the requested key
+//     * @return the mapped result, including meta-entries.
+//     */
+//    public Map<String,String> get(String key){
+//        CloseableHttpResponse response = null;
+//        Map<String,String> result = new HashMap<>();
+//        try {
+//            HttpGet httpGet = new HttpGet(serverURL + "/v2/keys/"+key);
+//            
httpGet.setConfig(RequestConfig.copy(RequestConfig.DEFAULT).setSocketTimeout(timeout)
+//                    
.setConnectionRequestTimeout(timeout).setConnectTimeout(timeout).build());
+//            response = httpclient.execute(httpGet);
+//            if (response.getStatusLine().getStatusCode() == 
HttpStatus.SC_OK) {
+//                HttpEntity entity = response.getEntity();
+//                JsonReader reader = readerFactory.createReader(new 
StringReader(EntityUtils.toString(entity)));
+//                JsonObject o = reader.readObject();
+//                JsonObject node = o.getJsonObject("node");
+//                result.put(key, node.getString("value"));
+//                result.put("_" + key +".source", "[etcd]"+serverURL);
+//                if(node.containsKey("createdIndex")) {
+//                    result.put("_" + key +".createdIndex", 
String.valueOf(node.getInt("createdIndex")));
+//                }
+//                if(node.containsKey("modifiedIndex")) {
+//                    result.put("_" + key +".modifiedIndex", 
String.valueOf(node.getInt("modifiedIndex")));
+//                }
+//                if(node.containsKey("expiration")) {
+//                    result.put("_" + key +".expiration", 
String.valueOf(node.getString("expiration")));
+//                }
+//                if(node.containsKey("ttl")) {
+//                    result.put("_" + key +".ttl", 
String.valueOf(node.getInt("ttl")));
+//                }
+//                EntityUtils.consume(entity);
+//            }else{
+//                result.put("_" + key +".NOT_FOUND.target", 
"[etcd]"+serverURL);
+//            }
+//        } catch(Exception e){
+//            LOG.log(Level.INFO, "Error reading key '"+key+"' from etcd: " + 
serverURL, e);
+//            result.put("_ERROR", "Error reading key '"+key+"' from etcd: " + 
serverURL + ": " + e.toString());
+//        } finally {
+//            if(response!=null){
+//                try {
+//                    response.close();
+//                } catch (IOException e) {
+//                    LOG.log(Level.WARNING, "Failed to close http response", 
e);
+//                }
+//            }
+//        }
+//        return result;
+//    }
+//
+//    /**
+//     * Creates/updates an entry in etcd without any ttl set.
+//     * @see #set(String, String, Integer)
+//     * @param key the property key, not null
+//     * @param value the value to be set
+//     * @return the result map as described above.
+//     */
+//    public Map<String,String> set(String key, String value){
+//        return set(key, value, null);
+//    }
+//
+//    /**
+//     * Creates/updates an entry in etcd. The response as follows:
+//     * <pre>
+//     *     {
+//     "action": "set",
+//     "node": {
+//     "createdIndex": 3,
+//     "key": "/message",
+//     "modifiedIndex": 3,
+//     "value": "Hello etcd"
+//     },
+//     "prevNode": {
+//     "createdIndex": 2,
+//     "key": "/message",
+//     "value": "Hello world",
+//     "modifiedIndex": 2
+//     }
+//     }
+//     * </pre>
+//     * is mapped to:
+//     * <pre>
+//     *     key=value
+//     *     _key.source=[etcd]http://127.0.0.1:4001
+//     *     _key.createdIndex=12
+//     *     _key.modifiedIndex=34
+//     *     _key.ttl=300
+//     *     _key.expiry=...
+//     *      // optional
+//     *     _key.prevNode.createdIndex=12
+//     *     _key.prevNode.modifiedIndex=34
+//     *     _key.prevNode.ttl=300
+//     *     _key.prevNode.expiration=...
+//     * </pre>
+//     * @param key the property key, not null
+//     * @param value the value to be set
+//     * @param ttlSeconds the ttl in seconds (optional)
+//     * @return the result map as described above.
+//     */
+//    public Map<String,String> set(String key, String value, Integer 
ttlSeconds){
+//        CloseableHttpResponse response = null;
+//        Map<String,String> result = new HashMap<>();
+//        try{
+//            HttpPut put = new HttpPut(serverURL + "/v2/keys/"+key);
+//            
put.setConfig(RequestConfig.copy(RequestConfig.DEFAULT).setSocketTimeout(timeout)
+//                    
.setConnectionRequestTimeout(timeout).setConnectTimeout(timeout).build());
+//            List<NameValuePair> nvps = new ArrayList<>();
+//            nvps.add(new BasicNameValuePair("value", value));
+//            if(ttlSeconds!=null){
+//                nvps.add(new BasicNameValuePair("ttl", 
ttlSeconds.toString()));
+//            }
+//            put.setEntity(new UrlEncodedFormEntity(nvps));
+//            response = httpclient.execute(put);
+//            if (response.getStatusLine().getStatusCode() == 
HttpStatus.SC_CREATED ||
+//                    response.getStatusLine().getStatusCode() == 
HttpStatus.SC_OK) {
+//                HttpEntity entity = response.getEntity();
+//                JsonReader reader = readerFactory.createReader(new 
StringReader(EntityUtils.toString(entity)));
+//                JsonObject o = reader.readObject();
+//                JsonObject node = o.getJsonObject("node");
+//                if(node.containsKey("createdIndex")) {
+//                    result.put("_" + key +".createdIndex", 
String.valueOf(node.getInt("createdIndex")));
+//                }
+//                if(node.containsKey("modifiedIndex")) {
+//                    result.put("_" + key +".modifiedIndex", 
String.valueOf(node.getInt("modifiedIndex")));
+//                }
+//                if(node.containsKey("expiration")) {
+//                    result.put("_" + key +".expiration", 
String.valueOf(node.getString("expiration")));
+//                }
+//                if(node.containsKey("ttl")) {
+//                    result.put("_" + key +".ttl", 
String.valueOf(node.getInt("ttl")));
+//                }
+//                result.put(key, node.getString("value"));
+//                result.put("_" + key +".source", "[etcd]"+serverURL);
+//                if(node.containsKey("prevNode")){
+//                    JsonObject prevNode = node.getJsonObject("prevNode");
+//                    if (prevNode.containsKey("createdIndex")) {
+//                        result.put("_" + key +".prevNode.createdIndex", 
String.valueOf(prevNode.getInt("createdIndex")));
+//                    }
+//                    if (prevNode.containsKey("modifiedIndex")) {
+//                        result.put("_" + key +".prevNode.modifiedIndex", 
String.valueOf(prevNode.getInt("modifiedIndex")));
+//                    }
+//                    if(prevNode.containsKey("expiration")) {
+//                        result.put("_" + key +".prevNode.expiration", 
String.valueOf(prevNode.getString("expiration")));
+//                    }
+//                    if(prevNode.containsKey("ttl")) {
+//                        result.put("_" + key +".prevNode.ttl", 
String.valueOf(prevNode.getInt("ttl")));
+//                    }
+//                    result.put("_" + key +".prevNode.value", 
prevNode.getString("value"));
+//                }
+//                EntityUtils.consume(entity);
+//            }
+//        } catch(Exception e){
+//            LOG.log(Level.INFO, "Error writing to etcd: " + serverURL, e);
+//            result.put("_ERROR", "Error writing '"+key+"' to etcd: " + 
serverURL + ": " + e.toString());
+//        } finally {
+//            if(response!=null){
+//                try {
+//                    response.close();
+//                } catch (IOException e) {
+//                    LOG.log(Level.WARNING, "Failed to close http response", 
e);
+//                }
+//            }
+//        }
+//        return result;
+//    }
+//
+//
+//    /**
+//     * Deletes a given key. The response is as follows:
+//     * <pre>
+//     *     _key.source=[etcd]http://127.0.0.1:4001
+//     *     _key.createdIndex=12
+//     *     _key.modifiedIndex=34
+//     *     _key.ttl=300
+//     *     _key.expiry=...
+//     *      // optional
+//     *     _key.prevNode.createdIndex=12
+//     *     _key.prevNode.modifiedIndex=34
+//     *     _key.prevNode.ttl=300
+//     *     _key.prevNode.expiration=...
+//     *     _key.prevNode.value=...
+//     * </pre>
+//     * @param key the key to be deleted.
+//     * @return the response mpas as described above.
+//     */
+//    public Map<String,String> delete(String key){
+//        CloseableHttpResponse response = null;
+//        Map<String,String> result = new HashMap<>();
+//        try{
+//            HttpDelete delete = new HttpDelete(serverURL + "/v2/keys/"+key);
+//            
delete.setConfig(RequestConfig.copy(RequestConfig.DEFAULT).setSocketTimeout(timeout)
+//                    
.setConnectionRequestTimeout(timeout).setConnectTimeout(timeout).build());
+//            response = httpclient.execute(delete);
+//            if (response.getStatusLine().getStatusCode() == 
HttpStatus.SC_OK) {
+//                HttpEntity entity = response.getEntity();
+//                JsonReader reader = readerFactory.createReader(new 
StringReader(EntityUtils.toString(entity)));
+//                JsonObject o = reader.readObject();
+//                JsonObject node = o.getJsonObject("node");
+//                if(node.containsKey("createdIndex")) {
+//                    result.put("_" + key +".createdIndex", 
String.valueOf(node.getInt("createdIndex")));
+//                }
+//                if(node.containsKey("modifiedIndex")) {
+//                    result.put("_" + key +".modifiedIndex", 
String.valueOf(node.getInt("modifiedIndex")));
+//                }
+//                if(node.containsKey("expiration")) {
+//                    result.put("_" + key +".expiration", 
String.valueOf(node.getString("expiration")));
+//                }
+//                if(node.containsKey("ttl")) {
+//                    result.put("_" + key +".ttl", 
String.valueOf(node.getInt("ttl")));
+//                }
+//                if(o.containsKey("prevNode")){
+//                    JsonObject prevNode = o.getJsonObject("prevNode");
+//                    if (prevNode.containsKey("createdIndex")) {
+//                        result.put("_" + key +".prevNode.createdIndex", 
String.valueOf(prevNode.getInt("createdIndex")));
+//                    }
+//                    if (prevNode.containsKey("modifiedIndex")) {
+//                        result.put("_" + key +".prevNode.modifiedIndex", 
String.valueOf(prevNode.getInt("modifiedIndex")));
+//                    }
+//                    if(prevNode.containsKey("expiration")) {
+//                        result.put("_" + key +".prevNode.expiration", 
String.valueOf(prevNode.getString("expiration")));
+//                    }
+//                    if(prevNode.containsKey("ttl")) {
+//                        result.put("_" + key +".prevNode.ttl", 
String.valueOf(prevNode.getInt("ttl")));
+//                    }
+//                    result.put("_" + key +".prevNode.value", 
prevNode.getString("value"));
+//                }
+//                EntityUtils.consume(entity);
+//            }
+//        } catch(Exception e){
+//            LOG.log(Level.INFO, "Error deleting key '"+key+"' from etcd: " + 
serverURL, e);
+//            result.put("_ERROR", "Error deleting '"+key+"' from etcd: " + 
serverURL + ": " + e.toString());
+//        } finally {
+//            if(response!=null){
+//                try {
+//                    response.close();
+//                } catch (IOException e) {
+//                    LOG.log(Level.WARNING, "Failed to close http response", 
e);
+//                }
+//            }
+//        }
+//        return result;
+//    }
+//
+//    /**
+//     * Get all properties for the given directory key recursively.
+//     * @see #getProperties(String, boolean)
+//     * @param directory the directory entry
+//     * @return the properties and its metadata
+//     */
+//    public Map<String,String> getProperties(String directory){
+//        return getProperties(directory, true);
+//    }
+//
+//    /**
+//     * Access all properties.
+//     * The response of:
+//     * <pre>
+//    {
+//    "action": "get",
+//    "node": {
+//        "key": "/",
+//        "dir": true,
+//        "nodes": [
+//            {
+//                "key": "/foo_dir",
+//                "dir": true,
+//                "modifiedIndex": 2,
+//                "createdIndex": 2
+//            },
+//            {
+//                "key": "/foo",
+//                "value": "two",
+//                "modifiedIndex": 1,
+//                "createdIndex": 1
+//            }
+//        ]
+//    }
+//}
+//     </pre>
+//     is mapped to a regular Tamaya properties map as follows:
+//     <pre>
+//     *    key1=myvalue
+//     *     _key1.source=[etcd]http://127.0.0.1:4001
+//     *     _key1.createdIndex=12
+//     *     _key1.modifiedIndex=34
+//     *     _key1.ttl=300
+//     *     _key1.expiration=...
+//     *
+//     *      key2=myvaluexxx
+//     *     _key2.source=[etcd]http://127.0.0.1:4001
+//     *     _key2.createdIndex=12
+//     *
+//     *      key3=val3
+//     *     _key3.source=[etcd]http://127.0.0.1:4001
+//     *     _key3.createdIndex=12
+//     *     _key3.modifiedIndex=2
+//     * </pre>
+//     */
+//    public Map<String,String> getProperties(String directory, boolean 
recursive){
+//        CloseableHttpResponse response = null;
+//        Map<String,String> result = new HashMap<>();
+//        try{
+//            HttpGet get = new HttpGet(serverURL + 
"/v2/keys/"+directory+"?recursive="+recursive);
+//            
get.setConfig(RequestConfig.copy(RequestConfig.DEFAULT).setSocketTimeout(timeout)
+//                    
.setConnectionRequestTimeout(timeout).setConnectTimeout(timeout).build());
+//            response = httpclient.execute(get);
+//            if (response.getStatusLine().getStatusCode() == 
HttpStatus.SC_OK) {
+//                HttpEntity entity = response.getEntity();
+//                JsonReader reader = readerFactory.createReader(new 
StringReader(EntityUtils.toString(entity)));
+//                JsonObject o = reader.readObject();
+//                JsonObject node = o.getJsonObject("node");
+//                if(node!=null){
+//                    addNodes(result, node);
+//                }
+//                EntityUtils.consume(entity);
+//            }
+//        } catch(Exception e){
+//            LOG.log(Level.INFO, "Error reading properties for 
'"+directory+"' from etcd: " + serverURL, e);
+//            result.put("_ERROR", "Error reading properties for 
'"+directory+"' from etcd: " + serverURL + ": " + e.toString());
+//        } finally {
+//            if(response!=null){
+//                try {
+//                    response.close();
+//                } catch (IOException e) {
+//                    LOG.log(Level.WARNING, "Failed to close http response", 
e);
+//                }
+//            }
+//        }
+//        return result;
+//    }
+//
+//    /**
+//     * Recursively read out all key/values from this etcd JSON array.
+//     * @param result map with key, values and metadata.
+//     * @param node the node to parse.
+//     */
+//    private void addNodes(Map<String, String> result, JsonObject node) {
+//        if(!node.containsKey("dir") || 
"false".equals(node.get("dir").toString())) {
+//            String key = node.getString("key").substring(1);
+//            result.put(key, node.getString("value"));
+//            if (node.containsKey("createdIndex")) {
+//                result.put("_" + key + ".createdIndex", 
String.valueOf(node.getInt("createdIndex")));
+//            }
+//            if (node.containsKey("modifiedIndex")) {
+//                result.put("_" + key + ".modifiedIndex", 
String.valueOf(node.getInt("modifiedIndex")));
+//            }
+//            if (node.containsKey("expiration")) {
+//                result.put("_" + key + ".expiration", 
String.valueOf(node.getString("expiration")));
+//            }
+//            if (node.containsKey("ttl")) {
+//                result.put("_" + key + ".ttl", 
String.valueOf(node.getInt("ttl")));
+//            }
+//            result.put("_" + key +".source", "[etcd]"+serverURL);
+//        } else {
+//            JsonArray nodes = node.getJsonArray("nodes");
+//            if (nodes != null) {
+//                for (int i = 0; i < nodes.size(); i++) {
+//                    addNodes(result, nodes.getJsonObject(i));
+//                }
+//            }
+//        }
+//    }
+//
+//    /**
+//     * Access the server root URL used by this accessor.
+//     * @return
+//     */
+//    public String getUrl() {
+//        return serverURL;
+//    }
+//}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/server/src/test/java/org/apache/tamaya/server/VersionPropertiesTest.java
----------------------------------------------------------------------
diff --git 
a/server/src/test/java/org/apache/tamaya/server/VersionPropertiesTest.java 
b/server/src/test/java/org/apache/tamaya/server/VersionPropertiesTest.java
new file mode 100644
index 0000000..18bc0ba
--- /dev/null
+++ b/server/src/test/java/org/apache/tamaya/server/VersionPropertiesTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.server;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.*;
+
+public class VersionPropertiesTest {
+
+    @Test
+    public void correctVersionPropertiesAreReadAndSet() throws IOException {
+        InputStream resource = 
VersionProperties.class.getResourceAsStream("/META-INF/tamaya-server-version.properties");
+
+        Properties properties = new Properties();
+        properties.load(resource);
+
+        assertThat(VersionProperties.getVersion(), 
not(Matchers.isEmptyOrNullString()));
+        assertThat(VersionProperties.getVersion(), 
equalTo(properties.get("server.version")));
+        assertThat(VersionProperties.getProduct(), 
not(Matchers.isEmptyOrNullString()));
+        assertThat(VersionProperties.getProduct(), 
equalTo(properties.get("server.product")));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/ui/base/src/main/main5.iml
----------------------------------------------------------------------
diff --git a/ui/base/src/main/main5.iml b/ui/base/src/main/main5.iml
new file mode 100644
index 0000000..908ad4f
--- /dev/null
+++ b/ui/base/src/main/main5.iml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/java" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/ui/events/pom.xml
----------------------------------------------------------------------
diff --git a/ui/events/pom.xml b/ui/events/pom.xml
new file mode 100644
index 0000000..1c8d7c0
--- /dev/null
+++ b/ui/events/pom.xml
@@ -0,0 +1,36 @@
+<?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";>
+
+    <parent>
+        <groupId>org.apache.tamaya.ext</groupId>
+        <artifactId>tamaya-ui-parent</artifactId>
+        <version>0.3-incubating-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <packaging>jar</packaging>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>tamaya-ui-events</artifactId>
+    <name>Apache Tamaya Modules - UI (Events)</name>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/ui/events/src/main/main7.iml
----------------------------------------------------------------------
diff --git a/ui/events/src/main/main7.iml b/ui/events/src/main/main7.iml
new file mode 100644
index 0000000..5d62ea9
--- /dev/null
+++ b/ui/events/src/main/main7.iml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/java" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="main5" />
+  </component>
+</module>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/ui/mutableconfig/src/main/main8.iml
----------------------------------------------------------------------
diff --git a/ui/mutableconfig/src/main/main8.iml 
b/ui/mutableconfig/src/main/main8.iml
new file mode 100644
index 0000000..5d62ea9
--- /dev/null
+++ b/ui/mutableconfig/src/main/main8.iml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/java" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="main5" />
+  </component>
+</module>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/ui/pom.xml
----------------------------------------------------------------------
diff --git a/ui/pom.xml b/ui/pom.xml
new file mode 100644
index 0000000..9e5f340
--- /dev/null
+++ b/ui/pom.xml
@@ -0,0 +1,46 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~  or more contributor license agreements.  See the NOTICE file
+  ~  distributed with this work for additional information
+  ~  regarding copyright ownership.  The ASF licenses this file
+  ~  to you under the Apache License, Version 2.0 (the
+  ~  "License"); you may not use this file except in compliance
+  ~  with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied.  See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+<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-sandbox</artifactId>
+        <version>0.3-incubating-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <artifactId>tamaya-ui-parent</artifactId>
+    <name>Apache Tamaya Modules - UI (parent)</name>
+    <description>Parent of the UI modules, which implement a servlet 
application
+        for accessing and changing of configuration.
+    </description>
+    <packaging>pom</packaging>
+
+    <properties>
+        <jdkVersion>1.7</jdkVersion>
+    </properties>
+
+    <modules>
+        <module>base</module>
+        <module>events</module>
+        <module>mutableconfig</module>
+    </modules>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/validation/pom.xml
----------------------------------------------------------------------
diff --git a/validation/pom.xml b/validation/pom.xml
new file mode 100644
index 0000000..e190257
--- /dev/null
+++ b/validation/pom.xml
@@ -0,0 +1,112 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~  or more contributor license agreements.  See the NOTICE file
+  ~  distributed with this work for additional information
+  ~  regarding copyright ownership.  The ASF licenses this file
+  ~  to you under the Apache License, Version 2.0 (the
+  ~  "License"); you may not use this file except in compliance
+  ~  with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied.  See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+<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-sandbox</artifactId>
+        <version>0.3-incubating-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <artifactId>tamaya-validation</artifactId>
+    <name>Apache Tamaya Modules - Validation</name>
+    <description>This extension module provides functionality to validate 
configuration.
+    </description>
+    <packaging>bundle</packaging>
+
+    <properties>
+        <jdkVersion>1.7</jdkVersion>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-core</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-injection-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-events</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-json</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.johnzon</groupId>
+            <artifactId>johnzon-core</artifactId>
+            <version>0.9-incubating</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-json_1.0_spec</artifactId>
+            <version>1.0-alpha-1</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>java-hamcrest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Export-Package>
+                            org.apache.tamaya.model,
+                            org.apache.tamaya.model.spi
+                        </Export-Package>
+                        <Private-Package>
+                            org.apache.tamaya.model.internal
+                        </Private-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/validation/src/main/resources/META-INF/configmodel.properties
----------------------------------------------------------------------
diff --git a/validation/src/main/resources/META-INF/configmodel.properties 
b/validation/src/main/resources/META-INF/configmodel.properties
new file mode 100644
index 0000000..3381a09
--- /dev/null
+++ b/validation/src/main/resources/META-INF/configmodel.properties
@@ -0,0 +1,35 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Contains definitions for default system property areas.
+_awt.model.target=Section
+_awt.model.transitive=true
+_file.model.target=Section
+_file.model.transitive=true
+_java.model.target=Section
+_java.model.transitive=true
+_line.model.target=Section
+_line.model.transitive=true
+_os.model.target=Section
+_os.model.transitive=true
+_path.model.target=Section
+_path.model.transitive=true
+_sun.model.target=Section
+_sun.model.transitive=true
+_user.model.target=Section
+_user.model.transitive=true

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/validation/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
----------------------------------------------------------------------
diff --git 
a/validation/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
 
b/validation/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
new file mode 100644
index 0000000..e8b12e9
--- /dev/null
+++ 
b/validation/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
@@ -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.model.internal.ConfiguredTypeEventsModelPopulator
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/validation/src/test/java/test/model/TestConfigAccessor.java
----------------------------------------------------------------------
diff --git a/validation/src/test/java/test/model/TestConfigAccessor.java 
b/validation/src/test/java/test/model/TestConfigAccessor.java
new file mode 100644
index 0000000..498d2b6
--- /dev/null
+++ b/validation/src/test/java/test/model/TestConfigAccessor.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package test.model;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+
+import java.util.Map;
+
+/**
+ * Created by atsticks on 30.04.16.
+ */
+public final class TestConfigAccessor {
+
+    private TestConfigAccessor(){}
+
+    public static Map<String,String> readAllProperties(){
+        return ConfigurationProvider.getConfiguration()
+                .getProperties();
+    }
+
+    public static Configuration readConfiguration(){
+        return ConfigurationProvider.getConfiguration();
+    }
+
+    public static String readProperty(Configuration config, String key){
+        return config.get(key);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/validation/src/test/resources/META-INF/configmodel.properties
----------------------------------------------------------------------
diff --git a/validation/src/test/resources/META-INF/configmodel.properties 
b/validation/src/test/resources/META-INF/configmodel.properties
new file mode 100644
index 0000000..a7956dc
--- /dev/null
+++ b/validation/src/test/resources/META-INF/configmodel.properties
@@ -0,0 +1,96 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the 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.
+#
+
+###################################################################################
+# Example of a configuration metamodel expressed via properties.
+####################################################################################
+
+# Metamodel information
+_model.provider=ConfigModel Extension
+
+# reusable parameter definition, referenceable as MyNumber
+_MyNumber.model.target=Parameter
+_MyNumber.model.type=Integer
+_MyNumber.model.description=a (reusable) number type parameter (optional)
+
+####################################################################################
+# Description of Configuration Sections (minimal, can be extended by other 
modules).
+# By default its interpreted as a section !
+####################################################################################
+
+# a (section)
+_a.model.target=Section
+_a.params2.model.target=Parameter
+_a.params2.model.type=String
+_a.params2.model.required=true
+_a.params2.model.description=a required parameter
+
+_a.paramInt.model.target=Parameter
+_a.paramInt.model.type=ref:MyNumber
+_a.paramInt.model.description=an optional parameter (default)
+
+_a._number.model.target=Parameter
+_a._number.model.type=Integer
+_a._number.model.deprecated=true
+_a._number.model.mappedTo=a.paramInt
+
+# a.b.c (section)
+_a.b.c.model.target=Section
+_a.b.c.model.description=Just a test section
+
+# a.b.c.aRequiredSection (section)
+_a.b.c.aRequiredSection.model.target=Section
+_a.b.c.aRequiredSection.model.required=true
+_a.b.c.aRequiredSection.model.description=A section containing required 
parameters is called a required section.\
+         Sections can also explicitly be defined to be required, but without\
+         specifying the paramteres to be contained.,
+
+# a.b.c.aRequiredSection.subsection (section)
+_a.b.c.aRequiredSection.subsection.model.target=Section
+
+_a.b.c.aRequiredSection.subsection.param0.model.model.target=Parameter
+_a.b.c.aRequiredSection.subsection.param0.type=String
+_a.b.c.aRequiredSection.subsection.param0.model.description=a minmally 
documented String parameter
+# A minmal String parameter
+_a.b.c.aRequiredSection.subsection.param00.model.target=Parameter
+_a.b.c.aRequiredSection.subsection.param00.model.type=String
+
+# a.b.c.aRequiredSection.subsection (section)
+_a.b.c.aRequiredSection.subsection.param1.model.target=Parameter
+_a.b.c.aRequiredSection.subsection.param1.model.type = String
+_a.b.c.aRequiredSection.subsection.param1.model.required = true
+_a.b.c.aRequiredSection.subsection.intParam.model.target=Parameter
+_a.b.c.aRequiredSection.subsection.intParam.model.type = Integer
+_a.b.c.aRequiredSection.subsection.intParam.model.description=an optional 
parameter (default)
+
+# a.b.c.aRequiredSection.nonempty-subsection (section)
+_a.b.c.aRequiredSection.nonempty-subsection.model.target=Section
+_a.b.c.aRequiredSection.nonempty-subsection.model.required=true
+
+# a.b.c.aRequiredSection.optional-subsection (section)
+_a.b.c.aRequiredSection.optional-subsection.model.target=Section
+
+# a.b.c.aValidatedSection (section)
+_a.b.c.aValidatedSection.model.target=Section
+_a.b.c.aValidatedSection.model.description=A validated section.
+_a.b.c.aValidatedSection.model.validator=org.apache.tamaya.model.TestValidator
+
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/validation/src/test/resources/META-INF/javaconfiguration.properties
----------------------------------------------------------------------
diff --git 
a/validation/src/test/resources/META-INF/javaconfiguration.properties 
b/validation/src/test/resources/META-INF/javaconfiguration.properties
new file mode 100644
index 0000000..b0b8c22
--- /dev/null
+++ b/validation/src/test/resources/META-INF/javaconfiguration.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy 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.
+#
+a.test.existing.aParam=existingValue
+a.test.existing.optionalParam=optionalValue
+a.test.existing.aABCParam=ABCparam
+a.test.existing.aABCParam2=MMM

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/validation/src/test/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi
----------------------------------------------------------------------
diff --git 
a/validation/src/test/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi
 
b/validation/src/test/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi
new file mode 100644
index 0000000..9b29fda
--- /dev/null
+++ 
b/validation/src/test/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi
@@ -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.model.ConfigModelProviderTest
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/validation/src/test/resources/examples/configmodel.ini
----------------------------------------------------------------------
diff --git a/validation/src/test/resources/examples/configmodel.ini 
b/validation/src/test/resources/examples/configmodel.ini
new file mode 100644
index 0000000..0e10cc1
--- /dev/null
+++ b/validation/src/test/resources/examples/configmodel.ini
@@ -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 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.
+#
+
+###################################################################################
+# Example of a configuration metamodel expressed via ini(tm).
+####################################################################################
+
+####################################################################################
+# Description of Configuration Sections (minimal, can be extended by other 
modules).
+# By default its interpreted as a section !
+####################################################################################
+[_a.model]
+class = Section
+params2.type = String
+params2.required = true
+params2.description = "a required parameter"
+paramInt.ref = MyNumber
+paramInt.description = "an optional parameter (default)"
+_number.type = Integer
+_number.deprecated = true
+_number.mappedTo = "a.paramInt"
+
+[_a.b.c.model]
+class = Section
+description = Just a test section
+
+[_a.b.c.aRequiredSection.model]
+class = Section
+required = true
+description = A section containing required parameters is called a required 
section.\
+         Sections can also explicitly be defined to be required, but without\
+         specifying the paramteres to be contained.,
+
+[_a.b.c.aRequiredSection.subsection.model]
+class = Section
+param0.type = String
+param0.description = "a minmally documented String parameter"
+# A minmal String parameter
+param00.type = String
+# description is optional
+param1.type = String
+param1.required = true
+intParam.type = Integer
+intParam.description = "an optional parameter (default)"
+
+[_a.b.c.aRequiredSection.nonempty-subsection.model]
+class = Section
+required = true
+
+[_a.b.c.aRequiredSection.optional-subsection.model]
+class = Section
+
+[_a.b.c.aValidatedSection.model]
+class = Section
+description = "A configModel section."
+configModels = org.apache.tamaya.model.TestValidator?max=3
+
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/validation/src/test/resources/examples/configmodel.json
----------------------------------------------------------------------
diff --git a/validation/src/test/resources/examples/configmodel.json 
b/validation/src/test/resources/examples/configmodel.json
new file mode 100644
index 0000000..529f26e
--- /dev/null
+++ b/validation/src/test/resources/examples/configmodel.json
@@ -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 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.
+*/
+
+//##################################################################################
+// Example of a configuration metamodel expressed via YAML(tm).
+//  Structure is shown through indentation (one or more spaces).
+//  Sequence items are denoted by a dash,
+//  key value pairs within a map are separated by a colon.
+//##################################################################################
+
+//##################################################################################
+// Metamodel information
+//##################################################################################
+{
+  "_model": {
+    "provider": "ConfigModel Extension",
+    // reusable parameter definition
+  },
+  "_MyNumber.model": {
+      "class": "Parameter",
+      "type": "Integer",
+      "template": true,
+      "description": "an (reusable) number type parameter (optional)"
+    },
+    
//##################################################################################
+    // Description of Configuration Sections (minimal, can be extended by 
other modules).
+    
//##################################################################################
+    "_a.model": {
+      "class": "Section",
+      // required, default is parameter!
+    },
+    "_a.params2.model": {
+        "required": true,
+        "description": "a required parameter"
+    },
+    "_a.paramInt.model": {
+        // references a shared parameter definition.
+        "ref": "MyNumber",
+        "description": "an optional parameter (default)"
+    },
+    "_a.number.model": {
+        "type": "Integer",
+        "deprecated": true,
+        // references a deprecated parameter, now mapped to 'a.paramInt'.
+        "mappedto": "a.paramInt"
+    },
+    "_a.b.c.model": {
+      "class": "Section",
+      "description": "Just a test section."
+      // a subsection, directly configured as child element.
+    },
+    "_a.b.c.aRequiredSection.model": {
+        "class": "Section",
+        "required": true,
+        "description": "A section containing required parameters is called a 
required section."
+    },
+    // a subsection, configured in its own section.
+    "_a.b.c.aRequiredSection.subsection.model": {
+      "class": "Section"
+    }
+    "_a.b.c.param0-model": {
+        "type": "String",
+        "description": "a minimally documented String parameter"
+    },
+      // A minimally defined String parameter
+    "_a.b.c.param00": {},
+    "_a.b.c.param1": {
+        "type": "String",
+        "required": true,
+        "description": "a required parameter"
+      },
+     "_a.b.c.intParam": {
+        "type": "Integer",
+        "required": true,
+        "description": "an optional parameter (default)"
+    },
+    "_a.b.c.aRequiredSection.nonempty-subsection.model": {
+      "class": "Section",
+      "required": true
+    },
+    "_a.b.c.aRequiredSection.optional-subsection.model": {
+      "class": "Section"
+    },
+    "_a.b.c.aRequiredSection.aValidatedSection.model": {
+      "class": "Section",
+      "description": "A validated section.",
+      "validations": 
"org.apache.tamaya.model.validation.MaxItemValidator?max=3"
+    }
+  }
+}
+
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/validation/src/test/resources/examples/configmodel.properties
----------------------------------------------------------------------
diff --git a/validation/src/test/resources/examples/configmodel.properties 
b/validation/src/test/resources/examples/configmodel.properties
new file mode 100644
index 0000000..b61695b
--- /dev/null
+++ b/validation/src/test/resources/examples/configmodel.properties
@@ -0,0 +1,96 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the 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.
+#
+
+###################################################################################
+# Example of a configuration metamodel expressed via properties.
+####################################################################################
+
+# Metamodel information
+_model.provider=ConfigModel Extension
+
+# reusable parameter definition, referenceable as MyNumber
+_MyNumber.model.class=Parameter
+_MyNumber.model.type=Integer
+_MyNumber.model.description=a (reusable) number type parameter (optional)
+
+####################################################################################
+# Description of Configuration Sections (minimal, can be extended by other 
modules).
+# By default its interpreted as a section !
+####################################################################################
+
+# a (section)
+_a.model.class=Section
+_a.params2.model.class=Parameter
+_a.params2.model.type=String
+_a.params2.model.required=true
+_a.params2.model.description=a required parameter
+
+_a.paramInt.model.class=Parameter
+_a.paramInt.model.type=ref:MyNumber
+_a.paramInt.model.description=an optional parameter (default)
+
+_a._number.model.class=Parameter
+_a._number.model.type=Integer
+_a._number.model.deprecated=true
+_a._number.model.mappedTo=a.paramInt
+
+# a.b.c (section)
+_a.b.c.class=Section
+_a.b.c.description=Just a test section
+
+# a.b.c.aRequiredSection (section)
+_a.b.c.aRequiredSection.model.class=Section
+_a.b.c.aRequiredSection.model.required=true
+_a.b.c.aRequiredSection.model.description=A section containing required 
parameters is called a required section.\
+         Sections can also explicitly be defined to be required, but without\
+         specifying the paramteres to be contained.,
+
+# a.b.c.aRequiredSection.subsection (section)
+_a.b.c.aRequiredSection.model.subsection.class=Section
+
+_a.b.c.aRequiredSection.subsection.param0.model.class=Parameter
+_a.b.c.aRequiredSection.subsection.param0.model.type=String
+_a.b.c.aRequiredSection.subsection.param0.model.description=a minmally 
documented String parameter
+# A minmal String parameter
+_a.b.c.aRequiredSection.subsection.param00.model.class=Parameter
+_a.b.c.aRequiredSection.subsection.param00.model.type=String
+
+# a.b.c.aRequiredSection.subsection (section)
+_a.b.c.aRequiredSection.subsection.param1.model.class=Parameter
+_a.b.c.aRequiredSection.subsection.param1.model.type = String
+_a.b.c.aRequiredSection.subsection.param1.model.required = true
+_a.b.c.aRequiredSection.subsection.intParam.model.class=Parameter
+_a.b.c.aRequiredSection.subsection.intParam.model.type = Integer
+_a.b.c.aRequiredSection.subsection.intParam.model.description=an optional 
parameter (default)
+
+# a.b.c.aRequiredSection.nonempty-subsection (section)
+_a.b.c.aRequiredSection.nonempty-subsection.model.class=Section
+_a.b.c.aRequiredSection.nonempty-subsection.model.required=true
+
+# a.b.c.aRequiredSection.optional-subsection (section)
+_a.b.c.aRequiredSection.optional-subsection.model.class=Section
+
+# a.b.c.aValidatedSection (section)
+_a.b.c.aValidatedSection.model.class=Section
+_a.b.c.aValidatedSection.model.description=A validated section.
+_a.b.c.aValidatedSection.model.configModels=org.apache.tamaya.model.TestValidator
+
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/validation/src/test/resources/examples/configmodel.xml
----------------------------------------------------------------------
diff --git a/validation/src/test/resources/examples/configmodel.xml 
b/validation/src/test/resources/examples/configmodel.xml
new file mode 100644
index 0000000..f23f783
--- /dev/null
+++ b/validation/src/test/resources/examples/configmodel.xml
@@ -0,0 +1,97 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!--################################################################################
+# Example of a configuration metamodel expressed via YAML(tm).
+#   Structure is shown through indentation (one or more spaces).
+#   Sequence items are denoted by a dash,
+#   key value pairs within a map are separated by a colon.
+#################################################################################-->
+
+<!--################################################################################
+# Metamodel information
+#################################################################################-->
+
+<configuration>
+    <section name="{model}" __provider="ConfigModel Extension" version="1.0" 
__release-date="2001-01-23"
+            author="Anatole Tresch">
+        <!-- model-format>alternate format reader type</model-format -->
+        <__description>Late afternoon is best.
+            Backup contact is Nancy.
+        </__description>
+
+        
<!--################################################################################
+        # Description of Configuration Sections (minimal, can be extended by 
other modules).
+        
#################################################################################-->
+        <section name="a">
+            <param name="params">
+                <type>String</type>
+                <required>true</required>
+                <description>a required parameter</description>
+            </param>
+            <param name="paramInt">
+                <ref>MyNumber</ref>
+                <required>true</required>
+                <description>an optional parameter (default)</description>
+            </param>
+            <param name="_number">
+                <type>Integer</type>
+                <deprecated>true</deprecated>
+                <mappedto>a.paramInt</mappedto>
+            </param>
+            <section name="b.c">
+                <description>Just a test section.</description>
+                <section name="aRequiredSection">
+                    <description>A section containing required parameters is 
called a required section.
+                        Sections can also explicitly be defined to be 
required, but without
+                        specifying the paramteres to be contained.
+                    </description>
+                </section>
+            </section>
+        </section>
+
+        <section name="a.b.c.aRequiredSection.subsection">
+            <param name="param0" type="String">a minmally documented String 
parameter</param>
+            <!-- # A minmally defined String parameter -->
+            <param name="param00">
+                <type>String</type>
+            </param>
+            <param name="param1">
+                <type>String</type>
+                <required>true</required>
+                <description>a required parameter</description>description>
+            </param>
+            <param name="intParam">
+                <type>Integer</type>
+                <description>an optional parameter (default)</description>
+            </param>
+            <section name="b.c">
+                <description>Just a test section.</description>
+            </section>
+        </section>
+        <section name="a.b.c.aRequiredSection.nonempty-subsection">
+            <required>true</required>
+        </section>
+        <section name="a.b.c.aRequiredSection.optional-subsection"/>
+        <section name="a.b.c.aRequiredSection.aValidatedSection">
+            
<configModels>org.apache.tamaya.model.configModel.MaxItemValidator?max=3"</configModels>
+            <description>A configModel section.</description>
+        </section>
+    </section>
+</configuration>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/validation/src/test/resources/examples/configmodel.yaml
----------------------------------------------------------------------
diff --git a/validation/src/test/resources/examples/configmodel.yaml 
b/validation/src/test/resources/examples/configmodel.yaml
new file mode 100644
index 0000000..041c801
--- /dev/null
+++ b/validation/src/test/resources/examples/configmodel.yaml
@@ -0,0 +1,106 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy 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.
+#
+
+##################################################################################
+# Example of a configuration metamodel expressed via YAML(tm).
+#   Structure is shown through indentation (one or more spaces).
+#   Sequence items are denoted by a dash,
+#   key value pairs within a map are separated by a colon.
+####################################################################################
+
+####################################################################################
+# Metamodel information
+####################################################################################
+{model}: {
+  __name           :  'testmodel',
+  __provider       :  'ValidationProviderSpi Extension',
+  __version        :  '1.0',
+  __release-date   :  2001-01-23,
+  __author         :  'Anatole Tresch',
+  # model-format: 'alternate format reader type'
+  __description: >
+    Late afternoon is best.
+    Backup contact is Nancy.
+}
+
+####################################################################################
+# Description of Configuration Sections (minimal, can be extended by other 
modules).
+####################################################################################
+---
+{model}.a.params2: {
+  type          : 'String',
+  required      : true,
+  description   : 'a required parameter',
+  paramInt: 'Integer',                 'an optional parameter (default)',
+}
+---
+{model}.a.paramInt: {
+  type          : 'Integer',
+  description   : 'an optional parameter (default)',
+}
+---
+{model}.a.b.c: {
+  description:  'Just a test section.'
+}
+---
+{model}.a.b.c.aRequiredSection: {
+  required: true,
+  description: |
+             A section containing required parameters is called a required 
section.
+             Sections can also explicitly be defined to be required, but 
without
+             specifying the paramteres to be contained.,
+}
+---
+{model}.a.b.c.aRequiredSection.subsection: {
+  param0: {
+    type: 'String',
+    description: 'a minmally documented String parameter}'
+  },                 ,
+  param00:{
+    type: 'String'        # A minmally defined String parameter
+  },
+  param1: {
+    tpye: 'String',
+    required: true,
+    description: 'a required parameter'
+  },
+  intParam: {
+    type: 'Integer',
+    description: 'an optional parameter (default)'
+  }
+}
+...
+
+---
+{model}.a.b.c.aRequiredSection.nonempty-subsection: {
+  required: true
+}
+...
+
+---
+{model}.a.b.c.aRequiredSection.optional-subsection: {}
+...
+
+---
+{model}.a.b.c.aRequiredSection.aValidatedSection: {
+  description: 'A configModel section.',
+  configModels: 'org.apache.tamaya.model.configModel.MaxItemValidator?max=3'
+}
+
+

Reply via email to