You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:56:03 UTC

[sling-org-apache-sling-nosql-generic] annotated tag org.apache.sling.nosql.generic-1.0.0 created (now 7a6e9fd)

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a change to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git.


      at 7a6e9fd  (tag)
 tagging 7a67728e73179ed360958dbe26555fc0e6f5ee83 (commit)
      by Stefan Seifert
      on Thu Sep 17 21:27:19 2015 +0000

- Log -----------------------------------------------------------------
org.apache.sling.nosql.generic-1.0.0
-----------------------------------------------------------------------

This annotated tag includes the following new commits:

     new c0cfaf5  SLING-4381 generic nosql resource provider
     new 33067de  SLING-4381 couchbase client
     new d611ecf  SLING-4381 fix problem with deleted resources; define profile for integration tests
     new 5a39f50  SLING-4381 add READMEs, make factory configuration
     new a75ba5e  SLING-4381 add special handling for root resource
     new 97f137a  SLING-4381 disallow storing data in root resource
     new 1254cfe  SLING-4381 fix logic error for buckets with password; update readme
     new 330fa60  SLING-4381 allow null map when creating a resource
     new 6bace0b  SLING-4381 enable metrics logging for nosql adapter and disable event distribution
     new 3f2b8af  SLING-4381 metrics logging
     new 7233de3  SLING-4381 introduce AbstractNoSqlAdapter
     new 9083d70  update to released mock versions
     new f2ba0f2  SLING-4381 keep Calendar and byte[] types in ValueMap, and convert it from and back when passing over to NoSql adapter
     new b8a97cb  Update contrib modules to Parent 23
     new ef63139  set parent version to 24 and add empty relativePath where missing
     new 0e42677  SLING-4881 NoSQL Generic Resource Provider: Preserve order of changed resources (patch contributed by Levente Santha)
     new e5ad3dd  Added Eclipse files to svn:ignore in the new contrib bundles
     new a125fa9  SLING-5024 Sling NoSQL Resource Provider for MongoDB (based on nosql.generic)
     new 1c42a40  SLING-4381/SLING-5024 fix root node child listing
     new f3a77c7  cosmetic: fix javadoc errors
     new 3a6aa25  prepare 1.0.0 release
     new 72c4eb4  [maven-release-plugin] prepare release org.apache.sling.nosql.generic-1.0.0
     new 7a67728  [maven-release-plugin] copy for tag org.apache.sling.nosql.generic-1.0.0

The 23 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@sling.apache.org" <co...@sling.apache.org>'].

[sling-org-apache-sling-nosql-generic] 02/23: SLING-4381 couchbase client

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit 33067de483dd77b16bd684da9831e07a8c45bba9
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Wed May 20 13:48:32 2015 +0000

    SLING-4381 couchbase client
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1680570 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/pom.xml b/pom.xml
index 5781f27..ec6cdb2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
+<?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
@@ -17,25 +17,27 @@
   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/maven-v4_0_0.xsd">
+<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.sling</groupId>
         <artifactId>sling</artifactId>
         <version>22</version>
+        <relativePath/>
     </parent>
 
     <artifactId>org.apache.sling.nosql.generic</artifactId>
     <version>0.5.0-SNAPSHOT</version>
     <packaging>bundle</packaging>
 
-    <name>Apache Sling Generic NoSQL Resource Provider</name>
+    <name>Apache Sling NoSQL Generic Resource Provider</name>
 
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/nosql-generic</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/nosql-generic</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/nosql-generic</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/trunk/contrib/nosql/generic</url>
     </scm>
     
     <properties>
@@ -44,10 +46,12 @@
 
     <build>
         <plugins>
+
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-scr-plugin</artifactId>
             </plugin>
+
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 21/23: prepare 1.0.0 release

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit 3a6aa25ba93a25a694f47f5755a09ae2f78d0f9b
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Thu Sep 17 21:26:33 2015 +0000

    prepare 1.0.0 release
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1703694 13f79535-47bb-0310-9956-ffa450edef68
---
 src/main/java/org/apache/sling/nosql/generic/adapter/package-info.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/nosql/generic/adapter/package-info.java b/src/main/java/org/apache/sling/nosql/generic/adapter/package-info.java
index 3a4287a..aed682e 100644
--- a/src/main/java/org/apache/sling/nosql/generic/adapter/package-info.java
+++ b/src/main/java/org/apache/sling/nosql/generic/adapter/package-info.java
@@ -19,5 +19,5 @@
 /**
  * Adapter for NoSQL resource provider implementation.
  */
-@aQute.bnd.annotation.Version("0.5")
+@aQute.bnd.annotation.Version("1.0.0")
 package org.apache.sling.nosql.generic.adapter;

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 15/23: set parent version to 24 and add empty relativePath where missing

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit ef63139ae3f4485880201bf61d1c8fb5667bf86f
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Tue Jul 7 07:36:29 2015 +0000

    set parent version to 24 and add empty relativePath where missing
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1689588 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 291fd3f..a0fdc71 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>23</version>
+        <version>24</version>
         <relativePath/>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 10/23: SLING-4381 metrics logging

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit 3f2b8af0c1f462cb31ba0304677aa72ad186d297
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Thu May 21 14:15:53 2015 +0000

    SLING-4381 metrics logging
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1680880 13f79535-47bb-0310-9956-ffa450edef68
---
 .../apache/sling/nosql/generic/adapter/MetricsNoSqlAdapterWrapper.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/nosql/generic/adapter/MetricsNoSqlAdapterWrapper.java b/src/main/java/org/apache/sling/nosql/generic/adapter/MetricsNoSqlAdapterWrapper.java
index eaebf1d..dfcf7a7 100644
--- a/src/main/java/org/apache/sling/nosql/generic/adapter/MetricsNoSqlAdapterWrapper.java
+++ b/src/main/java/org/apache/sling/nosql/generic/adapter/MetricsNoSqlAdapterWrapper.java
@@ -102,7 +102,7 @@ public final class MetricsNoSqlAdapterWrapper implements NoSqlAdapter {
         public void finish(String message, Object... data) {
             if (logger.isDebugEnabled()) {
                 long duration = System.currentTimeMillis() - startTime;
-                logger.debug(message + " (" + duration + "ms)", data);
+                logger.debug(message + " - " + duration + "ms", data);
             }
         }
         

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 03/23: SLING-4381 fix problem with deleted resources; define profile for integration tests

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit d611ecfd51859480a68d46e8f4768b7478091c36
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Wed May 20 15:46:51 2015 +0000

    SLING-4381 fix problem with deleted resources; define profile for integration tests
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1680609 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/nosql/generic/resource/impl/NoSqlResourceProvider.java      | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
index 384a8e3..6a52315 100644
--- a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
@@ -116,7 +116,9 @@ public class NoSqlResourceProvider implements ResourceProvider, ModifyingResourc
 
     private boolean isDeleted(String path) {
         for (String deletedPath : deletedResources) {
-            return path.equals(deletedPath) || path.equals(deletedPath + "/");
+            if (path.equals(deletedPath) || path.equals(deletedPath + "/")) {
+                return true;
+            }
         }
         return false;
     }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 22/23: [maven-release-plugin] prepare release org.apache.sling.nosql.generic-1.0.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit 72c4eb41ace3a8ec29c3008ed6310b49229c6ea1
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Thu Sep 17 21:27:06 2015 +0000

    [maven-release-plugin] prepare release org.apache.sling.nosql.generic-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1703695 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/pom.xml b/pom.xml
index 4e82433..77a6bbd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,27 +17,26 @@
   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">
+<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.sling</groupId>
         <artifactId>sling</artifactId>
         <version>24</version>
-        <relativePath/>
+        <relativePath />
     </parent>
 
     <artifactId>org.apache.sling.nosql.generic</artifactId>
-    <version>0.5.0-SNAPSHOT</version>
+    <version>1.0.0</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling NoSQL Generic Resource Provider</name>
 
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/contrib/nosql/generic</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.nosql.generic-1.0.0</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.nosql.generic-1.0.0</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.nosql.generic-1.0.0</url>
     </scm>
     
     <properties>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 05/23: SLING-4381 add special handling for root resource

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit a75ba5e44fcae9b3f33b8e207eda3e0b9a16a9ca
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Wed May 20 23:28:04 2015 +0000

    SLING-4381 add special handling for root resource
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1680700 13f79535-47bb-0310-9956-ffa450edef68
---
 .../resource/impl/NoSqlResourceProvider.java       | 12 +++-
 .../AbstractNoSqlResourceProviderRootTest.java     | 79 ++++++++++++++++++++++
 .../SimpleNoSqlResourceProviderRootTest.java       | 39 +++++++++++
 3 files changed, 128 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
index 6a52315..5621566 100644
--- a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
@@ -18,6 +18,7 @@
  */
 package org.apache.sling.nosql.generic.resource.impl;
 
+import java.util.Collections;
 import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -50,6 +51,9 @@ import org.osgi.service.event.EventAdmin;
  */
 public class NoSqlResourceProvider implements ResourceProvider, ModifyingResourceProvider, QueriableResourceProvider {
     
+    private static final String ROOT_PATH = "/";
+    private static final NoSqlData ROOT_DATA = new NoSqlData(ROOT_PATH, Collections.<String, Object>emptyMap());
+    
     private final NoSqlAdapter adapter;
     private final EventAdmin eventAdmin;
     private final Map<String, NoSqlData> changedResources = new HashMap<String, NoSqlData>();
@@ -64,6 +68,10 @@ public class NoSqlResourceProvider implements ResourceProvider, ModifyingResourc
     // ### READONLY ACCESS ###
     
     public Resource getResource(ResourceResolver resourceResolver, String path) {
+        if (ROOT_PATH.equals(path)) {
+            return new NoSqlResource(ROOT_DATA, resourceResolver, this);
+        }
+        
         if (!adapter.validPath(path)) {
             return null;
         }
@@ -128,7 +136,7 @@ public class NoSqlResourceProvider implements ResourceProvider, ModifyingResourc
     
     public Resource create(ResourceResolver resolver, String path, Map<String, Object> properties)
             throws PersistenceException {
-        if (!adapter.validPath(path)) {
+        if (ROOT_PATH.equals(path) || !adapter.validPath(path)) {
             throw new PersistenceException("Illegal path - unable to create resource at " + path, null, path, null);
         }
 
@@ -146,7 +154,7 @@ public class NoSqlResourceProvider implements ResourceProvider, ModifyingResourc
     }
     
     public void delete(ResourceResolver resolver, String path) throws PersistenceException {
-        if (!adapter.validPath(path)) {
+        if (ROOT_PATH.equals(path) || !adapter.validPath(path)) {
             throw new PersistenceException("Unable to delete resource at {}" + path, null, path, null);
         }
 
diff --git a/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderRootTest.java b/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderRootTest.java
new file mode 100644
index 0000000..b346aa6
--- /dev/null
+++ b/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderRootTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.resource.impl;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Test monting NoSqlResourceProvider as root resource provider.
+ */
+public abstract class AbstractNoSqlResourceProviderRootTest {
+    
+    @Rule
+    public SlingContext context = new SlingContext(ResourceResolverType.NONE);
+    
+    protected abstract void registerResourceProviderFactoryAsRoot();
+
+    @Before
+    public void setUp() throws Exception {
+        registerResourceProviderFactoryAsRoot();
+    }
+    
+    @After
+    public void tearDown() {
+        context.resourceResolver().revert();
+    }
+    
+    @Test
+    public void testRoot() {
+        Resource root = context.resourceResolver().getResource("/");
+        assertNotNull(root);
+        assertTrue(root instanceof NoSqlResource);
+    }
+
+    @Test
+    public void testCreatePath() throws PersistenceException {
+        ResourceUtil.getOrCreateResource(context.resourceResolver(), "/test/test1",
+                ImmutableMap.<String, Object>of(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED),
+                JcrConstants.NT_UNSTRUCTURED, true);
+        
+        Resource test = context.resourceResolver().getResource("/test");
+        assertNotNull(test);
+        
+        Resource test1 = context.resourceResolver().getResource("/test/test1");
+        assertNotNull(test1);
+        
+        context.resourceResolver().delete(test);
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/nosql/generic/simple/SimpleNoSqlResourceProviderRootTest.java b/src/test/java/org/apache/sling/nosql/generic/simple/SimpleNoSqlResourceProviderRootTest.java
new file mode 100644
index 0000000..61cf09a
--- /dev/null
+++ b/src/test/java/org/apache/sling/nosql/generic/simple/SimpleNoSqlResourceProviderRootTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.simple;
+
+import org.apache.sling.api.resource.ResourceProvider;
+import org.apache.sling.nosql.generic.resource.impl.AbstractNoSqlResourceProviderRootTest;
+import org.apache.sling.nosql.generic.simple.provider.SimpleNoSqlResourceProviderFactory;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Test basic ResourceResolver and ValueMap with different data types.
+ */
+public class SimpleNoSqlResourceProviderRootTest extends AbstractNoSqlResourceProviderRootTest {
+    
+    @Override
+    protected void registerResourceProviderFactoryAsRoot() {
+        context.registerInjectActivateService(new SimpleNoSqlResourceProviderFactory(), ImmutableMap.<String, Object>builder()
+                .put(ResourceProvider.ROOTS, "/")
+                .build());
+    }
+
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 19/23: SLING-4381/SLING-5024 fix root node child listing

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit 1c42a400988b29aff807abb88f52bfb5dbb03ff6
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Wed Sep 16 19:25:11 2015 +0000

    SLING-4381/SLING-5024 fix root node child listing
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1703453 13f79535-47bb-0310-9956-ffa450edef68
---
 .../nosql/generic/resource/impl/PathUtil.java      |  4 ++-
 .../AbstractNoSqlResourceProviderRootTest.java     | 34 ++++++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/impl/PathUtil.java b/src/main/java/org/apache/sling/nosql/generic/resource/impl/PathUtil.java
index a4a59b0..8af73e6 100644
--- a/src/main/java/org/apache/sling/nosql/generic/resource/impl/PathUtil.java
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/impl/PathUtil.java
@@ -20,6 +20,8 @@ package org.apache.sling.nosql.generic.resource.impl;
 
 import java.util.regex.Pattern;
 
+import org.apache.commons.lang3.StringUtils;
+
 /**
  * Helper functions for handling paths.
  */
@@ -35,7 +37,7 @@ public final class PathUtil {
      * @return Regex pattern
      */
     public static Pattern getChildPathPattern(String parentPath) {
-        return Pattern.compile("^" + Pattern.quote(parentPath) + "/[^/]+$");
+        return Pattern.compile("^" + Pattern.quote(StringUtils.removeEnd(parentPath,  "/")) + "/[^/]+$");
     }
     
     /**
diff --git a/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderRootTest.java b/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderRootTest.java
index 3b4966f..82d88f0 100644
--- a/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderRootTest.java
+++ b/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderRootTest.java
@@ -18,9 +18,14 @@
  */
 package org.apache.sling.nosql.generic.resource.impl;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.sling.api.resource.ModifiableValueMap;
 import org.apache.sling.api.resource.PersistenceException;
@@ -34,6 +39,7 @@ import org.junit.Rule;
 import org.junit.Test;
 
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
 
 /**
  * Test monting NoSqlResourceProvider as root resource provider.
@@ -77,6 +83,34 @@ public abstract class AbstractNoSqlResourceProviderRootTest {
         context.resourceResolver().delete(test);
     }
     
+    @Test
+    public void testListChildren_RootNode() throws IOException {
+        Resource testResource = ResourceUtil.getOrCreateResource(context.resourceResolver(), "/test",
+                ImmutableMap.<String, Object>of(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED),
+                JcrConstants.NT_UNSTRUCTURED, true);
+
+        Resource root = context.resourceResolver().getResource("/");
+
+        List<Resource> children = Lists.newArrayList(root.listChildren());
+        assertFalse(children.isEmpty());
+        assertTrue(containsResource(children, testResource));
+
+        children = Lists.newArrayList(root.getChildren());
+        assertFalse(children.isEmpty());
+        assertTrue(containsResource(children, testResource));
+
+        context.resourceResolver().delete(testResource);
+    }
+
+    private boolean containsResource(List<Resource> children, Resource resource) {
+        for (Resource child : children) {
+            if (StringUtils.equals(child.getPath(), resource.getPath())) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
     @Test(expected = PersistenceException.class)
     public void testDeleteRootPath() throws PersistenceException {
         Resource root = context.resourceResolver().getResource("/");

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 14/23: Update contrib modules to Parent 23

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit b8a97cb0e98c2875042ffb3d44242a4e95283e11
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu Jun 25 13:10:59 2015 +0000

    Update contrib modules to Parent 23
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1687503 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index e0c5045..291fd3f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>22</version>
+        <version>23</version>
         <relativePath/>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 06/23: SLING-4381 disallow storing data in root resource

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit 97f137aa9a3d95f059fbc80e2987bfa4c4303114
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Thu May 21 07:02:40 2015 +0000

    SLING-4381 disallow storing data in root resource
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1680744 13f79535-47bb-0310-9956-ffa450edef68
---
 .../generic/resource/impl/NoSqlResourceProvider.java      |  3 +++
 .../impl/AbstractNoSqlResourceProviderRootTest.java       | 15 +++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
index 5621566..a1bc13f 100644
--- a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
@@ -194,6 +194,9 @@ public class NoSqlResourceProvider implements ResourceProvider, ModifyingResourc
                notifyRemoved(path);
             }
             for (NoSqlData item : changedResources.values()) {
+                if (ROOT_PATH.equals(item.getPath())) {
+                    throw new PersistenceException("Unable to store resource at {}" + item.getPath(), null, item.getPath(), null);
+                }
                 boolean created = adapter.store(item);
                 if (created) {
                     notifyAdded(item.getPath());
diff --git a/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderRootTest.java b/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderRootTest.java
index b346aa6..3b4966f 100644
--- a/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderRootTest.java
+++ b/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderRootTest.java
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import org.apache.jackrabbit.JcrConstants;
+import org.apache.sling.api.resource.ModifiableValueMap;
 import org.apache.sling.api.resource.PersistenceException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceUtil;
@@ -75,5 +76,19 @@ public abstract class AbstractNoSqlResourceProviderRootTest {
         
         context.resourceResolver().delete(test);
     }
+    
+    @Test(expected = PersistenceException.class)
+    public void testDeleteRootPath() throws PersistenceException {
+        Resource root = context.resourceResolver().getResource("/");
+        context.resourceResolver().delete(root);
+    }
+
+    @Test(expected = Throwable.class)
+    public void testUpdateRootPath() throws PersistenceException {
+        Resource root = context.resourceResolver().getResource("/");
+        ModifiableValueMap props = root.adaptTo(ModifiableValueMap.class);
+        props.put("prop1", "value1");
+        context.resourceResolver().commit();
+    }
 
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 13/23: SLING-4381 keep Calendar and byte[] types in ValueMap, and convert it from and back when passing over to NoSql adapter

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit f2ba0f2a354e868b499203b86f31526b35762e4d
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Tue Jun 2 16:17:06 2015 +0000

    SLING-4381 keep Calendar and byte[] types in ValueMap, and convert it from and back when passing over to NoSql adapter
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1683132 13f79535-47bb-0310-9956-ffa450edef68
---
 .../resource/impl/NoSqlResourceProvider.java       |   2 +-
 .../nosql/generic/resource/impl/NoSqlValueMap.java |  63 ++------
 .../impl/ValueMapConvertingNoSqlAdapter.java       | 170 +++++++++++++++++++++
 .../impl/AbstractNoSqlResourceProviderTest.java    |   2 +-
 4 files changed, 188 insertions(+), 49 deletions(-)

diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
index acad8b4..056c03e 100644
--- a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
@@ -60,7 +60,7 @@ public class NoSqlResourceProvider implements ResourceProvider, ModifyingResourc
     private final Set<String> deletedResources = new HashSet<String>();
     
     public NoSqlResourceProvider(NoSqlAdapter adapter, EventAdmin eventAdmin) {
-        this.adapter = adapter;
+        this.adapter = new ValueMapConvertingNoSqlAdapter(adapter);
         this.eventAdmin = eventAdmin;
     }
 
diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlValueMap.java b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlValueMap.java
index 42e07f9..6f7fcf4 100644
--- a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlValueMap.java
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlValueMap.java
@@ -21,16 +21,10 @@ package org.apache.sling.nosql.generic.resource.impl;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
-import java.util.Locale;
 import java.util.Map;
 
-import javax.xml.bind.DatatypeConverter;
-
 import org.apache.commons.io.IOUtils;
 import org.apache.sling.api.resource.ModifiableValueMap;
 import org.apache.sling.api.resource.Resource;
@@ -56,25 +50,10 @@ class NoSqlValueMap extends ValueMapDecorator implements ModifiableValueMap {
     @Override
     public <T> T get(String name, Class<T> type) {
         
-        if (type == Calendar.class) {
-            Date date = get(name, Date.class);
-            if (date != null) {
-                Calendar calendar = Calendar.getInstance();
-                calendar.setTime(date);
-                return (T)calendar;
-            }
-            else {
-                return null;
-            }
-        }
-        else if (type == Date.class) {
-            Object value = get(name);
-            if (value instanceof String) {
-                try {
-                    return (T)getISO8601Format().parse((String)value);
-                } catch (ParseException e) {
-                    return null;
-                }
+        if (type == Date.class) {
+            Calendar value = get(name, Calendar.class);
+            if (value != null) {
+                return (T)value.getTime();
             }
         }
         else if (type == InputStream.class) {
@@ -87,13 +66,6 @@ class NoSqlValueMap extends ValueMapDecorator implements ModifiableValueMap {
                 return null;
             }
         }
-        else if (type == byte[].class) {
-            // Support conversion from base64 string to byte array
-            Object value = get(name);
-            if (value instanceof String) {
-                return (T)DatatypeConverter.parseBase64Binary((String)value);
-            }
-        }
         else if ( type == null ) {
             return (T) super.get(name);
         }
@@ -128,11 +100,10 @@ class NoSqlValueMap extends ValueMapDecorator implements ModifiableValueMap {
     }
 
     private static Object convertForWrite(Object value) {
-        if (value instanceof Calendar) {
-            value = getISO8601Format().format(((Calendar)value).getTime());
-        }
         if (value instanceof Date) {
-            value = getISO8601Format().format((Date)value);
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime((Date)value);
+            value = calendar;
         }
         else if (value instanceof InputStream) {
             // Store InputStream values as byte array
@@ -142,25 +113,27 @@ class NoSqlValueMap extends ValueMapDecorator implements ModifiableValueMap {
                 throw new RuntimeException("Unable to convert input stream to byte array.");
             }
         }
-        else if (value instanceof byte[]) {
-            value = DatatypeConverter.printBase64Binary((byte[])value);
-        }
-        else if (value != null && !isValidPrimitveType(value.getClass())) {
+        else if (value != null && !isValidType(value.getClass())) {
             throw new IllegalArgumentException("Data type not supported for NoSqlValueMap: " + value.getClass());
         }
         return value;
     }
     
-    static boolean isValidPrimitveType(Class clazz) {
+    static boolean isValidType(Class clazz) {
         if (clazz.isArray()) {
-            return isValidPrimitveType(clazz.getComponentType());
+            if (clazz.getComponentType() == byte.class) {
+                // byte only supported as array
+                return true;
+            }
+            return isValidType(clazz.getComponentType());
         }
         else {
             return clazz == String.class
                     || clazz == Integer.class
                     || clazz == Long.class
                     || clazz == Double.class
-                    || clazz == Boolean.class;
+                    || clazz == Boolean.class
+                    || Calendar.class.isAssignableFrom(clazz);
         }
     }
     
@@ -171,8 +144,4 @@ class NoSqlValueMap extends ValueMapDecorator implements ModifiableValueMap {
         return map;
     }
 
-    private static DateFormat getISO8601Format() {
-        return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
-    }
-
 }
diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/impl/ValueMapConvertingNoSqlAdapter.java b/src/main/java/org/apache/sling/nosql/generic/resource/impl/ValueMapConvertingNoSqlAdapter.java
new file mode 100644
index 0000000..62974f0
--- /dev/null
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/impl/ValueMapConvertingNoSqlAdapter.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.resource.impl;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.sling.nosql.generic.adapter.NoSqlAdapter;
+import org.apache.sling.nosql.generic.adapter.NoSqlData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Special adapter wrapper that converts all Calendar and byte[] values in ValueMap to String values
+ * when passing to the underlying NoSql adapter and back to typed values when reading from it.
+ * This is required because too many implementations access ValueMap without type specifier so
+ * we cannot only rely on the type conversion in the typed get methods of a ValueMap.
+ */
+class ValueMapConvertingNoSqlAdapter implements NoSqlAdapter {
+    
+    private static final String PREFIX_CALENDAR = "{{calendar}}";
+    private static final String PREFIX_BYTE_ARRAY = "{{bytes}}";
+
+    private final NoSqlAdapter delegate;
+    
+    private static final Logger log = LoggerFactory.getLogger(ValueMapConvertingNoSqlAdapter.class);
+
+    public ValueMapConvertingNoSqlAdapter(NoSqlAdapter delegate) {
+        this.delegate = delegate;
+    }
+
+    public boolean validPath(String path) {
+        return delegate.validPath(path);
+    }
+
+    public NoSqlData get(String path) {
+        return deserializeUnsupportedTypes(delegate.get(path));
+    }
+
+    public Iterator<NoSqlData> getChildren(String parentPath) {
+        return deserializeUnsupportedTypes(delegate.getChildren(parentPath));
+    }
+
+    public boolean store(NoSqlData data) {
+        return delegate.store(serializeUnsupportedTypes(data));
+    }
+
+    public boolean deleteRecursive(String path) {
+        return delegate.deleteRecursive(path);
+    }
+
+    public Iterator<NoSqlData> query(String query, String language) {
+        return deserializeUnsupportedTypes(delegate.query(query, language));
+    }
+    
+    private Iterator<NoSqlData> deserializeUnsupportedTypes(final Iterator<NoSqlData> source) {
+        if (source == null) {
+            return null;
+        }
+        return new Iterator<NoSqlData>() {
+            @Override
+            public boolean hasNext() {
+                return source.hasNext();
+            }
+            @Override
+            public NoSqlData next() {
+                return deserializeUnsupportedTypes(source.next());
+            }
+            @Override
+            public void remove() {
+                source.remove();
+            }
+        };
+    }
+    
+    private NoSqlData serializeUnsupportedTypes(NoSqlData data) {
+        if (data == null) {
+            return null;
+        }
+        
+        Map<String,Object> serializedMap = new HashMap<String, Object>();
+        
+        for (Map.Entry<String, Object> entry : data.getProperties().entrySet()) {
+            Object serializedValue = entry.getValue();
+            
+            // Calendar.class
+            if (entry.getValue() instanceof Calendar) {
+                serializedValue = PREFIX_CALENDAR + getISO8601Format().format(((Calendar)entry.getValue()).getTime());
+            }
+            
+            // byte[].class
+            else if (entry.getValue() instanceof byte[]) {
+                serializedValue = PREFIX_BYTE_ARRAY + DatatypeConverter.printBase64Binary((byte[])entry.getValue());
+            }
+            
+            serializedMap.put(entry.getKey(), serializedValue);
+        }
+        
+        return new NoSqlData(data.getPath(), serializedMap);
+    }
+    
+    private NoSqlData deserializeUnsupportedTypes(NoSqlData data) {
+        if (data == null) {
+            return null;
+        }
+        
+        Map<String,Object> deserializedMap = new HashMap<String, Object>();
+
+        for (Map.Entry<String, Object> entry : data.getProperties().entrySet()) {
+            Object deserializedValue = entry.getValue();
+            if (entry.getValue() instanceof String) {
+                String value = (String)entry.getValue();
+                
+                // Calendar.class
+                if (value.indexOf(PREFIX_CALENDAR) == 0) {
+                    String calendarValue = value.substring(PREFIX_CALENDAR.length());
+                    try {
+                        Date date = getISO8601Format().parse((String)calendarValue);
+                        Calendar calendar = Calendar.getInstance();
+                        calendar.setTime(date);
+                        deserializedValue = calendar;
+                    }
+                    catch (ParseException ex) {
+                        log.warn("Unable to parse serialized calendar value: " + entry.getValue(), ex);
+                    }
+                }
+                
+                // byte[].class
+                else if (value.indexOf(PREFIX_BYTE_ARRAY) == 0) {
+                    String byteArrayValue = value.substring(PREFIX_BYTE_ARRAY.length());
+                    deserializedValue = DatatypeConverter.parseBase64Binary(byteArrayValue);
+                }
+                
+            }
+            deserializedMap.put(entry.getKey(), deserializedValue);
+        }
+        
+        return new NoSqlData(data.getPath(), deserializedMap);
+    }
+    
+    private static DateFormat getISO8601Format() {
+        return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderTest.java b/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderTest.java
index fde5152..fa3a82e 100644
--- a/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderTest.java
+++ b/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderTest.java
@@ -198,7 +198,7 @@ public abstract class AbstractNoSqlResourceProviderTest {
         // ensure that value map has only supported primitive types (all other supported types converted to string)
         ValueMap valueMap = resource1.getValueMap();
         for (Map.Entry<String, Object> entry : valueMap.entrySet()) {
-            assertTrue(NoSqlValueMap.isValidPrimitveType(entry.getValue().getClass()));
+            assertTrue(NoSqlValueMap.isValidType(entry.getValue().getClass()));
         }
     }
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 07/23: SLING-4381 fix logic error for buckets with password; update readme

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit 1254cfef095b9e25f44768b008f143cae8e6c398
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Thu May 21 07:12:11 2015 +0000

    SLING-4381 fix logic error for buckets with password; update readme
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1680746 13f79535-47bb-0310-9956-ffa450edef68
---
 README.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index fccf34f..3c2efba 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,7 @@ Features:
 * Defines a simplified "NoSqlAdapter" concept that is implemented for each NoSQL database. It boils down to simple get/put/list operations. Query support is optional.
 * Complete implementation of Resource, ResourceProvider, ResourceProviderFactory and ValueMap based on the NoSqlAdapter
 * "Transaction management" of Sling CRUD (commit/revert methods) is implemented
-* ValueMap supports String, Integer, Long, Double, Date, Calendar and InputStream/byte[] (binary data) and arrays of them. Date/Calendar and binary data is serialized to a string before storing, so the NoSQL databases have not to support them directly.
+* ValueMap supports String, Integer, Long, Double, Date, Calendar and InputStream/byte\[\] (binary data) and arrays of them. Date/Calendar and binary data is serialized to a string before storing, so the NoSQL databases have not to support them directly.
 * Sends resource notifications via OSGi EventAdmin
 * Provides a "tests" JAR that can be used for integration tests with NoSQL databases to test the own adapter implementation
+* Can be mounted as root provider without any JCR at all

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 20/23: cosmetic: fix javadoc errors

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit f3a77c78616bfdda5e3ac62e4939c6c4b09a770a
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Thu Sep 17 21:23:52 2015 +0000

    cosmetic: fix javadoc errors
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1703693 13f79535-47bb-0310-9956-ffa450edef68
---
 .../java/org/apache/sling/nosql/generic/adapter/MultiValueMode.java     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/nosql/generic/adapter/MultiValueMode.java b/src/main/java/org/apache/sling/nosql/generic/adapter/MultiValueMode.java
index 770c93a..c0d966d 100644
--- a/src/main/java/org/apache/sling/nosql/generic/adapter/MultiValueMode.java
+++ b/src/main/java/org/apache/sling/nosql/generic/adapter/MultiValueMode.java
@@ -19,7 +19,7 @@
 package org.apache.sling.nosql.generic.adapter;
 
 /**
- * Mode for multi-valued field data in {@link NoSqlData properties).
+ * Mode for multi-valued field data in {@link NoSqlData} properties.
  */
 public enum MultiValueMode {
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 11/23: SLING-4381 introduce AbstractNoSqlAdapter

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit 7233de3c8cd4ec56a18a4734f35a46fc5752cd2b
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Fri May 22 08:55:34 2015 +0000

    SLING-4381 introduce AbstractNoSqlAdapter
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1681048 13f79535-47bb-0310-9956-ffa450edef68
---
 .../generic/adapter/AbstractNoSqlAdapter.java      | 43 ++++++++++++++++++++++
 .../sling/nosql/generic/adapter/NoSqlAdapter.java  |  1 +
 2 files changed, 44 insertions(+)

diff --git a/src/main/java/org/apache/sling/nosql/generic/adapter/AbstractNoSqlAdapter.java b/src/main/java/org/apache/sling/nosql/generic/adapter/AbstractNoSqlAdapter.java
new file mode 100644
index 0000000..38eff2b
--- /dev/null
+++ b/src/main/java/org/apache/sling/nosql/generic/adapter/AbstractNoSqlAdapter.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.adapter;
+
+import java.util.Iterator;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * Default implementation of {@link NoSqlAdapter}.
+ */
+@ConsumerType
+public abstract class AbstractNoSqlAdapter implements NoSqlAdapter {
+
+    @Override
+    public boolean validPath(String path) {
+        // by default all paths are accepted
+        return true;
+    }
+
+    @Override
+    public Iterator<NoSqlData> query(String query, String language) {
+        // not supported unless it is overwritten explicitly
+        return null;
+    }
+    
+}
diff --git a/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlAdapter.java b/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlAdapter.java
index 0359796..ab3d823 100644
--- a/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlAdapter.java
+++ b/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlAdapter.java
@@ -24,6 +24,7 @@ import aQute.bnd.annotation.ConsumerType;
 
 /**
  * Adapter for NoSQL databases to be hooked into the Generic NoSQL resource provider.
+ * All implementors should should extend {@link AbstractNoSqlAdapter} to be compatible for future extensions.
  */
 @ConsumerType
 public interface NoSqlAdapter {

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 04/23: SLING-4381 add READMEs, make factory configuration

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit 5a39f5032453c4725396b1d3f7709793ab19c171
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Wed May 20 16:11:14 2015 +0000

    SLING-4381 add READMEs, make factory configuration
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1680622 13f79535-47bb-0310-9956-ffa450edef68
---
 README.md | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..fccf34f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+Apache Sling NoSQL Generic Resource Provider
+============================================
+
+Generic implementation of a Sling ResourceProvider that helps writing ResourceProviders using NoSQL databases as persistence.
+
+The generic implementation helps mapping the resource data to document-oriented key-value NoSQL databases like MongoDB or Couchbase.
+
+Features:
+
+* Defines a simplified "NoSqlAdapter" concept that is implemented for each NoSQL database. It boils down to simple get/put/list operations. Query support is optional.
+* Complete implementation of Resource, ResourceProvider, ResourceProviderFactory and ValueMap based on the NoSqlAdapter
+* "Transaction management" of Sling CRUD (commit/revert methods) is implemented
+* ValueMap supports String, Integer, Long, Double, Date, Calendar and InputStream/byte[] (binary data) and arrays of them. Date/Calendar and binary data is serialized to a string before storing, so the NoSQL databases have not to support them directly.
+* Sends resource notifications via OSGi EventAdmin
+* Provides a "tests" JAR that can be used for integration tests with NoSQL databases to test the own adapter implementation

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 18/23: SLING-5024 Sling NoSQL Resource Provider for MongoDB (based on nosql.generic)

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit a125fa96deb797da42a1146f8273cd77d2604059
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Mon Sep 14 21:19:29 2015 +0000

    SLING-5024 Sling NoSQL Resource Provider for MongoDB (based on nosql.generic)
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1703061 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |  8 +-
 .../sling/nosql/generic/adapter/MapConverter.java  | 87 ++++++++++++++++++++++
 .../{NoSqlData.java => MultiValueMode.java}        | 31 +++-----
 .../sling/nosql/generic/adapter/NoSqlData.java     | 28 ++++++-
 .../nosql/generic/adapter/MapConverterTest.java    | 79 ++++++++++++++++++++
 5 files changed, 209 insertions(+), 24 deletions(-)

diff --git a/pom.xml b/pom.xml
index a0fdc71..4e82433 100644
--- a/pom.xml
+++ b/pom.xml
@@ -88,6 +88,12 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.3.2</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.compendium</artifactId>
             <scope>provided</scope>
@@ -128,7 +134,7 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.testing.sling-mock</artifactId>
-            <version>1.3.0</version>
+            <version>1.5.0</version>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/src/main/java/org/apache/sling/nosql/generic/adapter/MapConverter.java b/src/main/java/org/apache/sling/nosql/generic/adapter/MapConverter.java
new file mode 100644
index 0000000..a04c8f6
--- /dev/null
+++ b/src/main/java/org/apache/sling/nosql/generic/adapter/MapConverter.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.adapter;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.ArrayUtils;
+
+/**
+ * Transforms NoSqlData maps to a valid form for couchbase JSON document.
+ * All arrays have to be transformed to lists.
+ */
+final class MapConverter {
+
+    private MapConverter() {
+        // static methods only
+    }
+
+    /**
+     * @param map Map with multi-valued arrays
+     * @return Map with multi-valued lists
+     */
+    public static Map<String, Object> mapArrayToList(Map<String, Object> map) {
+        for (Map.Entry<String, Object> entry : map.entrySet()) {
+            if (entry.getValue().getClass().isArray()) {
+                Class componentType = entry.getValue().getClass().getComponentType();
+                if (componentType == int.class) {
+                    entry.setValue(Arrays.asList(ArrayUtils.toObject((int[]) entry.getValue())));
+                }
+                else if (componentType == long.class) {
+                    entry.setValue(Arrays.asList(ArrayUtils.toObject((long[]) entry.getValue())));
+                }
+                else if (componentType == double.class) {
+                    entry.setValue(Arrays.asList(ArrayUtils.toObject((double[]) entry.getValue())));
+                }
+                else if (componentType == boolean.class) {
+                    entry.setValue(Arrays.asList(ArrayUtils.toObject((boolean[]) entry.getValue())));
+                }
+                else {
+                    entry.setValue(Arrays.asList((Object[]) entry.getValue()));
+                }
+            }
+        }
+        return map;
+    }
+
+    /**
+     * @param map Map with multi-valued lists
+     * @return Map with multi-valued arrays
+     */
+    @SuppressWarnings("unchecked")
+    public static Map<String, Object> mapListToArray(Map<String, Object> map) {
+        for (Map.Entry<String, Object> entry : map.entrySet()) {
+            if (entry.getValue() instanceof List) {
+                List list = (List) entry.getValue();
+                if (list.size() == 0) {
+                    entry.setValue(null);
+                }
+                else {
+                    Class type = list.get(0).getClass();
+                    entry.setValue(list.toArray((Object[]) Array.newInstance(type, list.size())));
+                }
+            }
+        }
+        return map;
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlData.java b/src/main/java/org/apache/sling/nosql/generic/adapter/MultiValueMode.java
similarity index 62%
copy from src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlData.java
copy to src/main/java/org/apache/sling/nosql/generic/adapter/MultiValueMode.java
index 2aef8b4..770c93a 100644
--- a/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlData.java
+++ b/src/main/java/org/apache/sling/nosql/generic/adapter/MultiValueMode.java
@@ -18,30 +18,19 @@
  */
 package org.apache.sling.nosql.generic.adapter;
 
-import java.util.Map;
-
-import aQute.bnd.annotation.ProviderType;
-
 /**
- * Wrapper for properties of a NoSQL document for a given path.
+ * Mode for multi-valued field data in {@link NoSqlData properties).
  */
-@ProviderType
-public final class NoSqlData {
-
-    private final String path;
-    private final Map<String,Object> properties;
-    
-    public NoSqlData(String path, Map<String, Object> properties) {
-        this.path = path;
-        this.properties = properties;
-    }
+public enum MultiValueMode {
 
-    public String getPath() {
-        return path;
-    }
+    /**
+     * Return multi-valued field values as array (default).
+     */
+    ARRAYS,
     
-    public Map<String, Object> getProperties() {
-        return properties;
-    }
+    /**
+     * Return multi-valued field values as lists.
+     */
+    LISTS
     
 }
diff --git a/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlData.java b/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlData.java
index 2aef8b4..0b52038 100644
--- a/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlData.java
+++ b/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlData.java
@@ -32,8 +32,21 @@ public final class NoSqlData {
     private final Map<String,Object> properties;
     
     public NoSqlData(String path, Map<String, Object> properties) {
+        this(path, properties, MultiValueMode.ARRAYS);
+    }
+
+    public NoSqlData(String path, Map<String, Object> properties, MultiValueMode multiValueMode) {
         this.path = path;
-        this.properties = properties;
+        switch (multiValueMode) {
+            case ARRAYS:
+                this.properties = properties;
+                break;
+            case LISTS:
+                this.properties = MapConverter.mapListToArray(properties);
+                break;
+            default:
+                throw new IllegalArgumentException("Multi value mode not supported: " + multiValueMode);
+        }
     }
 
     public String getPath() {
@@ -41,7 +54,18 @@ public final class NoSqlData {
     }
     
     public Map<String, Object> getProperties() {
-        return properties;
+        return getProperties(MultiValueMode.ARRAYS);
+    }
+    
+    public Map<String, Object> getProperties(MultiValueMode multiValueMode) {
+        switch (multiValueMode) {
+            case ARRAYS:
+                return properties;
+            case LISTS:
+                return MapConverter.mapArrayToList(properties);
+            default:
+                throw new IllegalArgumentException("Multi value mode not supported: " + multiValueMode);
+        }
     }
     
 }
diff --git a/src/test/java/org/apache/sling/nosql/generic/adapter/MapConverterTest.java b/src/test/java/org/apache/sling/nosql/generic/adapter/MapConverterTest.java
new file mode 100644
index 0000000..32aa7cd
--- /dev/null
+++ b/src/test/java/org/apache/sling/nosql/generic/adapter/MapConverterTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.adapter;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.apache.sling.nosql.generic.adapter.MapConverter;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+public class MapConverterTest {
+
+    @Test
+    public void testMapArrayToList() throws Exception {
+        Map<String, Object> result = MapConverter.mapArrayToList(Maps.newHashMap(ImmutableMap.<String, Object>builder()
+                .put("prop1", "value1")
+                .put("prop2", 2)
+                .put("stringArray", new String[] { "value1", "value2" })
+                .put("integerArray", new Integer[] { 1, 2, 3 })
+                .put("integerArray2", new int[] { 1, 2, 3 })
+                .put("longArray", new long[] { 1L, 2L })
+                .put("doubleArray", new double[] { 1.1d, 1.2d })
+                .put("booleanArray", new boolean[] { true, false })
+                .build()));
+
+        assertEquals("prop1", "value1", result.get("prop1"));
+        assertEquals("prop2", 2, result.get("prop2"));
+        assertEquals("stringArray", ImmutableList.of("value1", "value2"), result.get("stringArray"));
+        assertEquals("integerArray", ImmutableList.of(1, 2, 3), result.get("integerArray"));
+        assertEquals("integerArray2", ImmutableList.of(1, 2, 3), result.get("integerArray2"));
+        assertEquals("longArray", ImmutableList.of(1L, 2L), result.get("longArray"));
+        assertEquals("doubleArray", ImmutableList.of(1.1d, 1.2d), result.get("doubleArray"));
+        assertEquals("booleanArray", ImmutableList.of(true, false), result.get("booleanArray"));
+    }
+
+    @Test
+    public void testMapListToArray() throws Exception {
+        Map<String, Object> result = MapConverter.mapListToArray(Maps.newHashMap(ImmutableMap.<String, Object>builder()
+                .put("prop1", "value1")
+                .put("prop2", 2)
+                .put("stringArray", ImmutableList.of("value1", "value2"))
+                .put("integerArray", ImmutableList.of(1, 2, 3))
+                .put("longArray", ImmutableList.of(1L, 2L))
+                .put("doubleArray", ImmutableList.of(1.1d, 1.2d))
+                .put("booleanArray", ImmutableList.of(true, false))
+                .build()));
+
+        assertEquals("prop1", "value1", result.get("prop1"));
+        assertEquals("prop2", 2, result.get("prop2"));
+        assertArrayEquals("stringArray", new String[] { "value1", "value2" }, (String[]) result.get("stringArray"));
+        assertArrayEquals("integerArray", new Integer[] { 1, 2, 3 }, (Integer[]) result.get("integerArray"));
+        assertArrayEquals("longArray", new Long[] { 1L, 2L }, (Long[]) result.get("longArray"));
+        assertArrayEquals("doubleArray", new Double[] { 1.1d, 1.2d }, (Double[]) result.get("doubleArray"));
+        assertArrayEquals("booleanArray", new Boolean[] { true, false }, (Boolean[]) result.get("booleanArray"));
+    }
+
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 09/23: SLING-4381 enable metrics logging for nosql adapter and disable event distribution

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit 6bace0b4972c059c4c35374a3c870513850a7b74
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Thu May 21 14:09:21 2015 +0000

    SLING-4381 enable metrics logging for nosql adapter and disable event distribution
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1680879 13f79535-47bb-0310-9956-ffa450edef68
---
 .../adapter/MetricsNoSqlAdapterWrapper.java        | 111 +++++++++++++++++++++
 .../resource/impl/NoSqlResourceProvider.java       |   3 -
 2 files changed, 111 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/apache/sling/nosql/generic/adapter/MetricsNoSqlAdapterWrapper.java b/src/main/java/org/apache/sling/nosql/generic/adapter/MetricsNoSqlAdapterWrapper.java
new file mode 100644
index 0000000..eaebf1d
--- /dev/null
+++ b/src/main/java/org/apache/sling/nosql/generic/adapter/MetricsNoSqlAdapterWrapper.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.adapter;
+
+import java.util.Iterator;
+
+import org.slf4j.Logger;
+
+/**
+ * Wrapper for {@link NoSqlAdapter} that enables logging and time counting for each call.
+ */
+public final class MetricsNoSqlAdapterWrapper implements NoSqlAdapter {
+
+    private final NoSqlAdapter delegate;
+    private final Logger logger;
+
+    public MetricsNoSqlAdapterWrapper(NoSqlAdapter delegate, Logger logger) {
+        this.delegate = delegate;
+        this.logger = logger;
+    }
+
+    public boolean validPath(String path) {
+        return delegate.validPath(path);
+    }
+
+    public NoSqlData get(String path) {
+        Metrics metrics = new Metrics();
+        try {
+            return delegate.get(path);
+        }
+        finally {
+            metrics.finish("get({})", path);
+        }
+    }
+
+    public Iterator<NoSqlData> getChildren(String parentPath) {
+        Metrics metrics = new Metrics();
+        try {
+            return delegate.getChildren(parentPath);
+        }
+        finally {
+            metrics.finish("getChildren({})", parentPath);
+        }
+    }
+
+    public boolean store(NoSqlData data) {
+        Metrics metrics = new Metrics();
+        try {
+            return delegate.store(data);
+        }
+        finally {
+            metrics.finish("store({})", data.getPath());
+        }
+    }
+
+    public boolean deleteRecursive(String path) {
+        Metrics metrics = new Metrics();
+        try {
+            return delegate.deleteRecursive(path);
+        }
+        finally {
+            metrics.finish("deleteRecursive({})", path);
+        }
+    }
+
+    public Iterator<NoSqlData> query(String query, String language) {
+        Metrics metrics = new Metrics();
+        try {
+            return delegate.query(query, language);
+        }
+        finally {
+            metrics.finish("query({})", query);
+        }
+    }
+    
+    private class Metrics {
+        
+        private long startTime;
+        
+        public Metrics() {
+            if (logger.isDebugEnabled()) {
+                startTime = System.currentTimeMillis();
+            }
+        }
+        
+        public void finish(String message, Object... data) {
+            if (logger.isDebugEnabled()) {
+                long duration = System.currentTimeMillis() - startTime;
+                logger.debug(message + " (" + duration + "ms)", data);
+            }
+        }
+        
+    }
+    
+}
diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
index 1df45cb..acad8b4 100644
--- a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
@@ -223,7 +223,6 @@ public class NoSqlResourceProvider implements ResourceProvider, ModifyingResourc
     private void notifyAdded(String path) {
         final Dictionary<String, Object> props = new Hashtable<String, Object>();
         props.put(SlingConstants.PROPERTY_PATH, path);
-        props.put("event.distribute", "");
         final Event event = new Event(SlingConstants.TOPIC_RESOURCE_ADDED, props);
         this.eventAdmin.postEvent(event);
     }
@@ -231,7 +230,6 @@ public class NoSqlResourceProvider implements ResourceProvider, ModifyingResourc
     private void notifyUpdated(String path) {
         final Dictionary<String, Object> props = new Hashtable<String, Object>();
         props.put(SlingConstants.PROPERTY_PATH, path);
-        props.put("event.distribute", "");
         final Event event = new Event(SlingConstants.TOPIC_RESOURCE_CHANGED, props);
         this.eventAdmin.postEvent(event);
     }    
@@ -239,7 +237,6 @@ public class NoSqlResourceProvider implements ResourceProvider, ModifyingResourc
     private void notifyRemoved(String path) {
         final Dictionary<String, Object> props = new Hashtable<String, Object>();
         props.put(SlingConstants.PROPERTY_PATH, path);
-        props.put("event.distribute", "");
         final Event event = new Event(SlingConstants.TOPIC_RESOURCE_REMOVED, props);
         this.eventAdmin.postEvent(event);
     }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 01/23: SLING-4381 generic nosql resource provider

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit c0cfaf51d9208f356f37090ec95491699029f045
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Wed May 20 12:53:50 2015 +0000

    SLING-4381 generic nosql resource provider
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1680549 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            | 139 +++++++++++
 .../sling/nosql/generic/adapter/NoSqlAdapter.java  |  76 ++++++
 .../sling/nosql/generic/adapter/NoSqlData.java     |  47 ++++
 .../sling/nosql/generic/adapter/package-info.java  |  23 ++
 .../AbstractNoSqlResourceProviderFactory.java      |  51 ++++
 .../nosql/generic/resource/impl/NoSqlResource.java |  90 +++++++
 .../resource/impl/NoSqlResourceProvider.java       | 272 +++++++++++++++++++++
 .../nosql/generic/resource/impl/NoSqlValueMap.java | 178 ++++++++++++++
 .../nosql/generic/resource/impl/PathUtil.java      |  50 ++++
 .../sling/nosql/generic/resource/package-info.java |  23 ++
 .../impl/AbstractNoSqlResourceProviderTest.java    | 211 ++++++++++++++++
 ...ractNoSqlResourceProviderTransactionalTest.java | 227 +++++++++++++++++
 .../nosql/generic/resource/impl/PathUtilTest.java  |  56 +++++
 .../SimpleNoSqlResourceProviderQueryTest.java      | 102 ++++++++
 .../simple/SimpleNoSqlResourceProviderTest.java    |  64 +++++
 ...mpleNoSqlResourceProviderTransactionalTest.java |  73 ++++++
 .../simple/provider/SimpleNoSqlAdapter.java        | 117 +++++++++
 .../SimpleNoSqlResourceProviderFactory.java        |  77 ++++++
 ...provider.SimpleNoSqlResourceProviderFactory.xml |  32 +++
 19 files changed, 1908 insertions(+)

diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..5781f27
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT 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/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>22</version>
+    </parent>
+
+    <artifactId>org.apache.sling.nosql.generic</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>Apache Sling Generic NoSQL Resource Provider</name>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/nosql-generic</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/nosql-generic</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/nosql-generic</url>
+    </scm>
+    
+    <properties>
+        <sling.java.version>7</sling.java.version>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+            </plugin>
+
+            <!-- Publish test artifact -->
+            <plugin>
+              <groupId>org.apache.maven.plugins</groupId>
+              <artifactId>maven-jar-plugin</artifactId>
+              <executions>
+                <execution>
+                  <goals>
+                    <goal>test-jar</goal>
+                  </goals>
+                </execution>
+              </executions>
+            </plugin>
+  
+        </plugins>
+    </build>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.9.0</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.osgi</artifactId>
+            <version>2.2.2</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.4</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <version>1.10.19</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.sling-mock</artifactId>
+            <version>1.2.1-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.jcr</groupId>
+            <artifactId>jcr</artifactId>
+            <version>2.0</version>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+</project>
diff --git a/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlAdapter.java b/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlAdapter.java
new file mode 100644
index 0000000..0359796
--- /dev/null
+++ b/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlAdapter.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.adapter;
+
+import java.util.Iterator;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * Adapter for NoSQL databases to be hooked into the Generic NoSQL resource provider.
+ */
+@ConsumerType
+public interface NoSqlAdapter {
+    
+    /**
+     * True if the given path is valid and supported by the NoSQL database.
+     * @param path Path
+     * @return true if valid, false if invalid
+     */
+    boolean validPath(String path);
+
+    /**
+     * Get data for a single resource from NoSQL database.
+     * @param path Path
+     * @return Data or null if non exists
+     */
+    NoSqlData get(String path);
+
+    /**
+     * Get data for all children of a resource from NoSQL database.
+     * @param parentPath Parent path
+     * @return List if child data or empty iterator
+     */
+    Iterator<NoSqlData> getChildren(String parentPath);
+    
+    /**
+     * Store data with the given path in NoSQL database.
+     * It is guaranteed that the map of the NoSqlData object does only contain primitive
+     * value types String, Integer, Long, Double, Boolean or arrays of them.
+     * @param data Data with path
+     * @return true if a new entry was created, false if an existing was overridden.
+     */
+    boolean store(NoSqlData data);
+    
+    /**
+     * Remove data including all path-related children from NoSQL database.
+     * @param path Path to remove
+     * @return true if anything was removed
+     */
+    boolean deleteRecursive(String path);
+
+    /**
+     * Query for data.
+     * @param query Query
+     * @param language Query language
+     * @return Query result or null if query not supported
+     */
+    Iterator<NoSqlData> query(String query, String language);
+        
+}
diff --git a/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlData.java b/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlData.java
new file mode 100644
index 0000000..2aef8b4
--- /dev/null
+++ b/src/main/java/org/apache/sling/nosql/generic/adapter/NoSqlData.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.adapter;
+
+import java.util.Map;
+
+import aQute.bnd.annotation.ProviderType;
+
+/**
+ * Wrapper for properties of a NoSQL document for a given path.
+ */
+@ProviderType
+public final class NoSqlData {
+
+    private final String path;
+    private final Map<String,Object> properties;
+    
+    public NoSqlData(String path, Map<String, Object> properties) {
+        this.path = path;
+        this.properties = properties;
+    }
+
+    public String getPath() {
+        return path;
+    }
+    
+    public Map<String, Object> getProperties() {
+        return properties;
+    }
+    
+}
diff --git a/src/main/java/org/apache/sling/nosql/generic/adapter/package-info.java b/src/main/java/org/apache/sling/nosql/generic/adapter/package-info.java
new file mode 100644
index 0000000..3a4287a
--- /dev/null
+++ b/src/main/java/org/apache/sling/nosql/generic/adapter/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * Adapter for NoSQL resource provider implementation.
+ */
+@aQute.bnd.annotation.Version("0.5")
+package org.apache.sling.nosql.generic.adapter;
diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/AbstractNoSqlResourceProviderFactory.java b/src/main/java/org/apache/sling/nosql/generic/resource/AbstractNoSqlResourceProviderFactory.java
new file mode 100644
index 0000000..2e56b2b
--- /dev/null
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/AbstractNoSqlResourceProviderFactory.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.resource;
+
+import java.util.Map;
+
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.ResourceProvider;
+import org.apache.sling.api.resource.ResourceProviderFactory;
+import org.apache.sling.nosql.generic.adapter.NoSqlAdapter;
+import org.apache.sling.nosql.generic.resource.impl.NoSqlResourceProvider;
+import org.osgi.service.event.EventAdmin;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * Abstract implementation of resource provider factory.
+ * NoSQL resource providers implement this, add their own configuration support and and provide the matching NoSQL adapter implementation.
+ */
+@ConsumerType
+public abstract class AbstractNoSqlResourceProviderFactory implements ResourceProviderFactory {
+
+    public final ResourceProvider getResourceProvider(Map<String, Object> authenticationInfo) throws LoginException {
+        return new NoSqlResourceProvider(getNoSqlAdapter(), getEventAdmin());
+    }
+
+    public final ResourceProvider getAdministrativeResourceProvider(Map<String, Object> authenticationInfo) throws LoginException {
+        return getResourceProvider(authenticationInfo);
+    }
+    
+    protected abstract NoSqlAdapter getNoSqlAdapter();
+
+    protected abstract EventAdmin getEventAdmin();
+
+}
diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResource.java b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResource.java
new file mode 100644
index 0000000..5431cc1
--- /dev/null
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResource.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.resource.impl;
+
+import java.util.Map;
+
+import org.apache.sling.api.SlingConstants;
+import org.apache.sling.api.resource.AbstractResource;
+import org.apache.sling.api.resource.ModifiableValueMap;
+import org.apache.sling.api.resource.ResourceMetadata;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.DeepReadModifiableValueMapDecorator;
+import org.apache.sling.api.wrappers.DeepReadValueMapDecorator;
+import org.apache.sling.nosql.generic.adapter.NoSqlData;
+
+/**
+ * Generic implementation of a NoSQL database resource.
+ */
+class NoSqlResource extends AbstractResource {
+    
+    private final NoSqlData data;
+    private final ResourceResolver resourceResolver;
+    private final NoSqlResourceProvider resourceProvider;
+    private final ResourceMetadata metadata;
+    
+    public NoSqlResource(NoSqlData data, ResourceResolver resourceResolver, NoSqlResourceProvider resourceProvider) {
+        this.data = data;
+        this.resourceResolver = resourceResolver;
+        this.resourceProvider = resourceProvider;
+        this.metadata = new ResourceMetadata();
+    }
+
+    public ResourceResolver getResourceResolver() {
+        return resourceResolver;
+    }
+
+    public String getPath() {
+        return data.getPath();
+    }
+
+    public String getResourceType() {
+        return getValueMap().get(ResourceResolver.PROPERTY_RESOURCE_TYPE, "nt:unstructured");
+    }
+
+    public String getResourceSuperType() {
+        return getValueMap().get(SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_SUPER_TYPE, String.class);
+    }
+
+    public ResourceMetadata getResourceMetadata() {
+        return metadata;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+        if (type == ValueMap.class || type == Map.class) {
+            return (AdapterType)new DeepReadValueMapDecorator(this, new NoSqlValueMap(data.getProperties(), this, resourceProvider));
+        }
+        if (type == ModifiableValueMap.class) {
+            return (AdapterType)new DeepReadModifiableValueMapDecorator(this, new NoSqlValueMap(data.getProperties(), this, resourceProvider));
+        }
+        return super.adaptTo(type);
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName()
+            + ", type=" + getResourceType()
+            + ", superType=" + getResourceSuperType()
+            + ", path=" + getPath();
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
new file mode 100644
index 0000000..384a8e3
--- /dev/null
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
@@ -0,0 +1,272 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.resource.impl;
+
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.regex.Pattern;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.sling.api.SlingConstants;
+import org.apache.sling.api.resource.ModifyingResourceProvider;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.QueriableResourceProvider;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceProvider;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.nosql.generic.adapter.NoSqlAdapter;
+import org.apache.sling.nosql.generic.adapter.NoSqlData;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+
+/**
+ * Generic implementation of a NoSQL resource provider.
+ * The mapping to the NoSQL database implementation details is done via the provided {@link NoSqlAdapter}.
+ */
+public class NoSqlResourceProvider implements ResourceProvider, ModifyingResourceProvider, QueriableResourceProvider {
+    
+    private final NoSqlAdapter adapter;
+    private final EventAdmin eventAdmin;
+    private final Map<String, NoSqlData> changedResources = new HashMap<String, NoSqlData>();
+    private final Set<String> deletedResources = new HashSet<String>();
+    
+    public NoSqlResourceProvider(NoSqlAdapter adapter, EventAdmin eventAdmin) {
+        this.adapter = adapter;
+        this.eventAdmin = eventAdmin;
+    }
+
+    
+    // ### READONLY ACCESS ###
+    
+    public Resource getResource(ResourceResolver resourceResolver, String path) {
+        if (!adapter.validPath(path)) {
+            return null;
+        }
+        if (!this.deletedResources.isEmpty()) {
+            for (String deletedPath : deletedResources) {
+                Pattern deletedPathPattern = PathUtil.getSameOrDescendantPathPattern(deletedPath);
+                if (deletedPathPattern.matcher(path).matches()) {
+                    return null;
+                }
+            }
+        }
+        if (this.changedResources.containsKey(path)) {
+            return new NoSqlResource(this.changedResources.get(path), resourceResolver, this);
+        }
+        NoSqlData data = adapter.get(path);
+        if (data != null) {
+            return new NoSqlResource(data, resourceResolver, this);
+        }
+        return null;
+    }
+
+    public Resource getResource(ResourceResolver resourceResolver, HttpServletRequest request, String path) {
+        return getResource(resourceResolver, path);
+    }
+
+    public Iterator<Resource> listChildren(Resource parent) {
+        
+        // use map to consolidate data from adapter minus deleted plus changed resources
+        // always sorty result alphabetically to have a consistent ordering - the nosql data source does not support ordering
+        SortedMap<String, Resource> children = new TreeMap<String, Resource>();
+        
+        Iterator<NoSqlData> fromAdapter = adapter.getChildren(parent.getPath());
+        while (fromAdapter.hasNext()) {
+            NoSqlData item = fromAdapter.next();
+            if (isDeleted(item.getPath()) || changedResources.containsKey(item.getPath())) {
+                continue;
+            }
+            children.put(item.getPath(), new NoSqlResource(item, parent.getResourceResolver(), this));
+        }
+        
+        Pattern childPathPattern = PathUtil.getChildPathPattern(parent.getPath());
+        for (NoSqlData item : changedResources.values()) {
+            if (childPathPattern.matcher(item.getPath()).matches()) {
+                children.put(item.getPath(), new NoSqlResource(item, parent.getResourceResolver(), this));
+            }
+        }
+        
+        return children.values().iterator();
+    }
+
+    private boolean isDeleted(String path) {
+        for (String deletedPath : deletedResources) {
+            return path.equals(deletedPath) || path.equals(deletedPath + "/");
+        }
+        return false;
+    }
+
+    
+    // ### WRITE ACCESS ###
+    
+    public Resource create(ResourceResolver resolver, String path, Map<String, Object> properties)
+            throws PersistenceException {
+        if (!adapter.validPath(path)) {
+            throw new PersistenceException("Illegal path - unable to create resource at " + path, null, path, null);
+        }
+
+        // check if already exists
+        boolean deleted = this.deletedResources.remove(path);
+        boolean exists = changedResources.containsKey(path) || this.adapter.get(path) != null;
+        if (!deleted && exists) {
+            throw new PersistenceException("Resource already exists at " + path, null, path, null);
+        }
+        
+        // create new resource in changeset
+        NoSqlData data = new NoSqlData(path, NoSqlValueMap.convertForWriteAll(new HashMap<String, Object>(properties)));
+        changedResources.put(path, data);
+        return new NoSqlResource(data, resolver, this);
+    }
+    
+    public void delete(ResourceResolver resolver, String path) throws PersistenceException {
+        if (!adapter.validPath(path)) {
+            throw new PersistenceException("Unable to delete resource at {}" + path, null, path, null);
+        }
+
+        Pattern pathsToDeletePattern = PathUtil.getSameOrDescendantPathPattern(path);
+
+        // remove all existing path and probably descendant paths from list of deleted paths
+        Iterator<String> deletedResourcesIterator = deletedResources.iterator();
+        while (deletedResourcesIterator.hasNext()) {
+            String deletedPath = deletedResourcesIterator.next();
+            if (pathsToDeletePattern.matcher(deletedPath).matches()) {
+                deletedResourcesIterator.remove();
+            }
+        }
+        
+        // remove all changed descendant items from changeset
+        Iterator<Map.Entry<String, NoSqlData>> changeResourcesIterator = changedResources.entrySet().iterator();
+        while (changeResourcesIterator.hasNext()) {
+            Map.Entry<String, NoSqlData> entry = changeResourcesIterator.next();
+            if (pathsToDeletePattern.matcher(entry.getKey()).matches()) {
+                changeResourcesIterator.remove();
+            }
+        }
+        
+        // add path to delete
+        deletedResources.add(path);
+    }
+    
+    public void revert(ResourceResolver resolver) {
+        changedResources.clear();
+        deletedResources.clear();
+    }
+    
+    public void commit(ResourceResolver resolver) throws PersistenceException {
+        try {
+            for (String path : deletedResources) {
+               adapter.deleteRecursive(path); 
+               notifyRemoved(path);
+            }
+            for (NoSqlData item : changedResources.values()) {
+                boolean created = adapter.store(item);
+                if (created) {
+                    notifyAdded(item.getPath());
+                }
+                else {
+                    notifyUpdated(item.getPath());
+                }
+            }
+        }
+        finally {
+            this.revert(resolver);
+        }
+    }
+    
+    public boolean hasChanges(ResourceResolver resolver) {
+        return !(changedResources.isEmpty() && deletedResources.isEmpty());
+    }
+    
+    void markAsChanged(Resource resource) {
+        changedResources.put(resource.getPath(), new NoSqlData(resource.getPath(), resource.getValueMap()));
+    }
+    
+    private void notifyAdded(String path) {
+        final Dictionary<String, Object> props = new Hashtable<String, Object>();
+        props.put(SlingConstants.PROPERTY_PATH, path);
+        props.put("event.distribute", "");
+        final Event event = new Event(SlingConstants.TOPIC_RESOURCE_ADDED, props);
+        this.eventAdmin.postEvent(event);
+    }
+
+    private void notifyUpdated(String path) {
+        final Dictionary<String, Object> props = new Hashtable<String, Object>();
+        props.put(SlingConstants.PROPERTY_PATH, path);
+        props.put("event.distribute", "");
+        final Event event = new Event(SlingConstants.TOPIC_RESOURCE_CHANGED, props);
+        this.eventAdmin.postEvent(event);
+    }    
+
+    private void notifyRemoved(String path) {
+        final Dictionary<String, Object> props = new Hashtable<String, Object>();
+        props.put(SlingConstants.PROPERTY_PATH, path);
+        props.put("event.distribute", "");
+        final Event event = new Event(SlingConstants.TOPIC_RESOURCE_REMOVED, props);
+        this.eventAdmin.postEvent(event);
+    }
+
+    
+    // ### QUERY ACCESS ###
+    
+    public Iterator<Resource> findResources(final ResourceResolver resolver, final String query, final String language) {
+        final Iterator<NoSqlData> result = adapter.query(query, language);
+        if (result == null) {
+            return null;
+        }
+        return new Iterator<Resource>() {
+            public boolean hasNext() {
+                return result.hasNext();
+            }
+            public Resource next() {
+                return new NoSqlResource(result.next(), resolver, NoSqlResourceProvider.this);
+            }
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    public Iterator<ValueMap> queryResources(final ResourceResolver resolver, final String query, final String language) {
+        final Iterator<Resource> result = findResources(resolver, query, language);
+        if (result == null) {
+            return null;
+        }
+        return new Iterator<ValueMap>() {
+            public boolean hasNext() {
+                return result.hasNext();
+            }
+            public ValueMap next() {
+                return result.next().getValueMap();
+            }
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+    
+}
diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlValueMap.java b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlValueMap.java
new file mode 100644
index 0000000..42e07f9
--- /dev/null
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlValueMap.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.resource.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.sling.api.resource.ModifiableValueMap;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+
+/**
+ * Enhances ValueMap that adds special support for deep path access.
+ * Additionally date and binary types are converted to string and back when reading.
+ * Besides this only primitive types String, Integer, Long, Double, Boolean and arrays of them are supported.
+ */
+class NoSqlValueMap extends ValueMapDecorator implements ModifiableValueMap {
+    
+    private final Resource resource;
+    private final NoSqlResourceProvider resourceProvider;
+    
+    public NoSqlValueMap(Map<String,Object> map, Resource resource, NoSqlResourceProvider resourceProvider) {
+        super(convertForWriteAll(map));
+        this.resource = resource;
+        this.resourceProvider = resourceProvider;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T get(String name, Class<T> type) {
+        
+        if (type == Calendar.class) {
+            Date date = get(name, Date.class);
+            if (date != null) {
+                Calendar calendar = Calendar.getInstance();
+                calendar.setTime(date);
+                return (T)calendar;
+            }
+            else {
+                return null;
+            }
+        }
+        else if (type == Date.class) {
+            Object value = get(name);
+            if (value instanceof String) {
+                try {
+                    return (T)getISO8601Format().parse((String)value);
+                } catch (ParseException e) {
+                    return null;
+                }
+            }
+        }
+        else if (type == InputStream.class) {
+            // Support conversion from byte array to InputStream
+            byte[] data = get(name, byte[].class);
+            if (data != null) {
+                return (T)new ByteArrayInputStream(data);
+            }
+            else {
+                return null;
+            }
+        }
+        else if (type == byte[].class) {
+            // Support conversion from base64 string to byte array
+            Object value = get(name);
+            if (value instanceof String) {
+                return (T)DatatypeConverter.parseBase64Binary((String)value);
+            }
+        }
+        else if ( type == null ) {
+            return (T) super.get(name);
+        }
+        return super.get(name, type);
+    }
+    
+    @Override
+    public Object put(String key, Object value) {
+        Object result = super.put(key, convertForWrite(value));
+        resourceProvider.markAsChanged(resource);
+        return result;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void putAll(Map<? extends String, ?> map) {
+        super.putAll((Map<? extends String, ?>)convertForWriteAll((Map<String, Object>)map));
+        resourceProvider.markAsChanged(resource);
+    }
+    
+    @Override
+    public Object remove(Object key) {
+        Object result = super.remove(key);
+        resourceProvider.markAsChanged(resource);
+        return result;
+    }
+
+    @Override
+    public void clear() {
+        super.clear();
+        resourceProvider.markAsChanged(resource);
+    }
+
+    private static Object convertForWrite(Object value) {
+        if (value instanceof Calendar) {
+            value = getISO8601Format().format(((Calendar)value).getTime());
+        }
+        if (value instanceof Date) {
+            value = getISO8601Format().format((Date)value);
+        }
+        else if (value instanceof InputStream) {
+            // Store InputStream values as byte array
+            try {
+                value = convertForWrite(IOUtils.toByteArray((InputStream)value));
+            } catch (IOException ex) {
+                throw new RuntimeException("Unable to convert input stream to byte array.");
+            }
+        }
+        else if (value instanceof byte[]) {
+            value = DatatypeConverter.printBase64Binary((byte[])value);
+        }
+        else if (value != null && !isValidPrimitveType(value.getClass())) {
+            throw new IllegalArgumentException("Data type not supported for NoSqlValueMap: " + value.getClass());
+        }
+        return value;
+    }
+    
+    static boolean isValidPrimitveType(Class clazz) {
+        if (clazz.isArray()) {
+            return isValidPrimitveType(clazz.getComponentType());
+        }
+        else {
+            return clazz == String.class
+                    || clazz == Integer.class
+                    || clazz == Long.class
+                    || clazz == Double.class
+                    || clazz == Boolean.class;
+        }
+    }
+    
+    public static Map<String, Object> convertForWriteAll(Map<String, Object> map) {
+        for (Map.Entry<String, Object> entry : map.entrySet()) {
+            map.put(entry.getKey(), convertForWrite(entry.getValue()));
+        }
+        return map;
+    }
+
+    private static DateFormat getISO8601Format() {
+        return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/impl/PathUtil.java b/src/main/java/org/apache/sling/nosql/generic/resource/impl/PathUtil.java
new file mode 100644
index 0000000..a4a59b0
--- /dev/null
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/impl/PathUtil.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.sling.nosql.generic.resource.impl;
+
+import java.util.regex.Pattern;
+
+/**
+ * Helper functions for handling paths.
+ */
+public final class PathUtil {
+
+    private PathUtil() {
+        // static methods only
+    }
+    
+    /**
+     * Generated a regex pattern that accepts all paths that are direct children of the given parent path.
+     * @param parentPath Parent path
+     * @return Regex pattern
+     */
+    public static Pattern getChildPathPattern(String parentPath) {
+        return Pattern.compile("^" + Pattern.quote(parentPath) + "/[^/]+$");
+    }
+    
+    /**
+     * Generated a regex pattern that accepts all paths that are same or descendants of the given parent path.
+     * @param path Path
+     * @return Regex pattern
+     */
+    public static Pattern getSameOrDescendantPathPattern(String path) {
+        return Pattern.compile("^" + Pattern.quote(path) + "(/.*)?$");
+    }
+    
+}
diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/package-info.java b/src/main/java/org/apache/sling/nosql/generic/resource/package-info.java
new file mode 100644
index 0000000..a804837
--- /dev/null
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * Generic NoSQL resource provider implementation.
+ */
+@aQute.bnd.annotation.Version("0.5")
+package org.apache.sling.nosql.generic.resource;
diff --git a/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderTest.java b/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderTest.java
new file mode 100644
index 0000000..eda8f8c
--- /dev/null
+++ b/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderTest.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.resource.impl;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Test basic ResourceResolver and ValueMap with different data types.
+ */
+public abstract class AbstractNoSqlResourceProviderTest {
+    
+    private static final String STRING_VALUE = "value1";
+    private static final String[] STRING_ARRAY_VALUE = new String[] { "value1", "value2" };
+    private static final int INTEGER_VALUE = 25;
+    private static final double DOUBLE_VALUE = 3.555d;
+    private static final boolean BOOLEAN_VALUE = true;
+    private static final Date DATE_VALUE = new Date(10000);
+    private static final Calendar CALENDAR_VALUE = Calendar.getInstance();
+    private static final byte[] BINARY_VALUE = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+
+    @Rule
+    public SlingContext context = new SlingContext(ResourceResolverType.JCR_MOCK);
+    
+    protected abstract void registerResourceProviderFactory();
+
+    protected abstract Resource testRoot();
+
+    @Before
+    public void setUp() throws Exception {
+        registerResourceProviderFactory();
+        
+        // prepare some test data using Sling CRUD API
+        Resource rootNode = testRoot();
+
+        Map<String, Object> props = new HashMap<String, Object>();
+        props.put(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED);
+        props.put("stringProp", STRING_VALUE);
+        props.put("stringArrayProp", STRING_ARRAY_VALUE);
+        props.put("integerProp", INTEGER_VALUE);
+        props.put("doubleProp", DOUBLE_VALUE);
+        props.put("booleanProp", BOOLEAN_VALUE);
+        props.put("dateProp", DATE_VALUE);
+        props.put("calendarProp", CALENDAR_VALUE);
+        props.put("binaryProp", new ByteArrayInputStream(BINARY_VALUE));
+        Resource node1 = context.resourceResolver().create(rootNode, "node1", props);
+
+        context.resourceResolver().create(node1, "node11", ImmutableMap.<String, Object>builder()
+                .put("stringProp11", STRING_VALUE)
+                .build());
+        context.resourceResolver().create(node1, "node12", ValueMap.EMPTY);
+
+        context.resourceResolver().commit();
+    }
+    
+    @After
+    public void tearDown() {
+        context.resourceResolver().revert();
+        try {
+            context.resourceResolver().delete(testRoot());
+            context.resourceResolver().commit();
+        }
+        catch (PersistenceException ex) {
+            // ignore
+        }        
+    }
+
+    @Test
+    public void testSimpleProperties() throws IOException {
+        Resource resource1 = context.resourceResolver().getResource(testRoot().getPath() + "/node1");
+        assertTrue(resource1 instanceof NoSqlResource);
+        
+        assertNotNull(resource1);
+        assertEquals("node1", resource1.getName());
+
+        ValueMap props = ResourceUtil.getValueMap(resource1);
+        assertEquals(STRING_VALUE, props.get("stringProp", String.class));
+        assertArrayEquals(STRING_ARRAY_VALUE, props.get("stringArrayProp", String[].class));
+        assertEquals((Integer) INTEGER_VALUE, props.get("integerProp", Integer.class));
+        assertEquals(DOUBLE_VALUE, props.get("doubleProp", Double.class), 0.0001);
+        assertEquals(BOOLEAN_VALUE, props.get("booleanProp", Boolean.class));
+    }
+
+    @Test
+    public void testSimpleProperties_DeepPathAccess() throws IOException {
+        Resource resource1 = context.resourceResolver().getResource(testRoot().getPath());
+        assertNotNull(resource1);
+        assertEquals(testRoot().getName(), resource1.getName());
+
+        ValueMap props = ResourceUtil.getValueMap(resource1);
+        assertEquals(STRING_VALUE, props.get("node1/stringProp", String.class));
+        assertArrayEquals(STRING_ARRAY_VALUE, props.get("node1/stringArrayProp", String[].class));
+        assertEquals((Integer) INTEGER_VALUE, props.get("node1/integerProp", Integer.class));
+        assertEquals(DOUBLE_VALUE, props.get("node1/doubleProp", Double.class), 0.0001);
+        assertEquals(BOOLEAN_VALUE, props.get("node1/booleanProp", Boolean.class));
+        assertEquals(STRING_VALUE, props.get("node1/node11/stringProp11", String.class));
+    }
+    
+    @Test
+    public void testDateProperty() throws IOException {
+        Resource resource1 = context.resourceResolver().getResource(testRoot().getPath() + "/node1");
+        ValueMap props = ResourceUtil.getValueMap(resource1);
+        assertEquals(DATE_VALUE, props.get("dateProp", Date.class));
+    }
+
+    @Test
+    public void testDatePropertyToCalendar() throws IOException {
+        Resource resource1 = context.resourceResolver().getResource(testRoot().getPath() + "/node1");
+        ValueMap props = ResourceUtil.getValueMap(resource1);
+        Calendar calendarValue = props.get("dateProp", Calendar.class);
+        assertNotNull(calendarValue);
+        assertEquals(DATE_VALUE, calendarValue.getTime());
+    }
+
+    @Test
+    public void testCalendarProperty() throws IOException {
+        Resource resource1 = context.resourceResolver().getResource(testRoot().getPath() + "/node1");
+        ValueMap props = ResourceUtil.getValueMap(resource1);
+        assertEquals(CALENDAR_VALUE.getTime(), props.get("calendarProp", Calendar.class).getTime());
+    }
+
+    @Test
+    public void testCalendarPropertyToDate() throws IOException {
+        Resource resource1 = context.resourceResolver().getResource(testRoot().getPath() + "/node1");
+        ValueMap props = ResourceUtil.getValueMap(resource1);
+        Date dateValue = props.get("calendarProp", Date.class);
+        assertNotNull(dateValue);
+        assertEquals(CALENDAR_VALUE.getTime(), dateValue);
+    }
+
+    @Test
+    public void testListChildren() throws IOException {
+        Resource resource1 = context.resourceResolver().getResource(testRoot().getPath() + "/node1");
+
+        List<Resource> children = ImmutableList.copyOf(resource1.listChildren());
+        assertEquals(2, children.size());
+        assertEquals("node11", children.get(0).getName());
+        assertEquals("node12", children.get(1).getName());
+    }
+
+    @Test
+    public void testBinaryData() throws IOException {
+        Resource resource1 = context.resourceResolver().getResource(testRoot().getPath() + "/node1");
+
+        InputStream is = ResourceUtil.getValueMap(resource1).get("binaryProp", InputStream.class);
+        byte[] dataFromResource = IOUtils.toByteArray(is);
+        is.close();
+        assertArrayEquals(BINARY_VALUE, dataFromResource);
+    }
+
+    @Test
+    public void testValueMapTypes() throws IOException {
+        Resource resource1 = context.resourceResolver().getResource(testRoot().getPath() + "/node1");
+
+        // ensure that value map has only supported primitive types (all other supported types converted to string)
+        ValueMap valueMap = resource1.getValueMap();
+        for (Map.Entry<String, Object> entry : valueMap.entrySet()) {
+            assertTrue(NoSqlValueMap.isValidPrimitveType(entry.getValue().getClass()));
+        }
+    }
+
+    @Test
+    public void testPrimaryTypeResourceType() throws PersistenceException {
+        Resource resource = context.resourceResolver().getResource(testRoot().getPath());
+        assertEquals(JcrConstants.NT_UNSTRUCTURED, resource.getResourceType());
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderTransactionalTest.java b/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderTransactionalTest.java
new file mode 100644
index 0000000..3320806
--- /dev/null
+++ b/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderTransactionalTest.java
@@ -0,0 +1,227 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.resource.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Iterator;
+
+import org.apache.sling.api.resource.ModifiableValueMap;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Test basic ResourceResolver and ValueMap with different data types.
+ */
+public abstract class AbstractNoSqlResourceProviderTransactionalTest {
+    
+    @Rule
+    public SlingContext context = new SlingContext(ResourceResolverType.JCR_MOCK);
+    
+    protected abstract void registerResourceProviderFactory();
+
+    protected abstract Resource testRoot();
+
+    @Before
+    public void setUp() throws Exception {
+        registerResourceProviderFactory();
+    }
+    
+    @After
+    public void tearDown() {
+        context.resourceResolver().revert();
+        try {
+            context.resourceResolver().delete(testRoot());
+            context.resourceResolver().commit();
+        }
+        catch (PersistenceException ex) {
+            // ignore
+        }        
+    }
+
+    @Test
+    public void testRootNode() {
+        assertTrue(testRoot() instanceof NoSqlResource);
+    }
+
+    @Test
+    public void testAddDeleteNodesPartialCommit() throws PersistenceException {
+        context.resourceResolver().create(testRoot(), "node0", ImmutableMap.<String, Object>of());
+        context.resourceResolver().create(testRoot(), "node1", ImmutableMap.<String, Object>of());
+        context.resourceResolver().commit();
+
+        assertFalse(context.resourceResolver().hasChanges());
+        
+        context.resourceResolver().create(testRoot(), "node2", ImmutableMap.<String, Object>of());
+        context.resourceResolver().create(testRoot(), "node3", ImmutableMap.<String, Object>of());
+
+        assertTrue(context.resourceResolver().hasChanges());
+        
+        assertNotNull(testRoot().getChild("node0"));
+        assertNotNull(testRoot().getChild("node1"));
+        assertNotNull(testRoot().getChild("node2"));
+        assertNotNull(testRoot().getChild("node3"));
+        
+        context.resourceResolver().delete(testRoot().getChild("node0"));
+        context.resourceResolver().delete(testRoot().getChild("node2"));
+
+        assertNull(testRoot().getChild("node0"));
+        assertNotNull(testRoot().getChild("node1"));
+        assertNull(testRoot().getChild("node2"));
+        assertNotNull(testRoot().getChild("node3"));
+        
+        Iterator<Resource> children = testRoot().listChildren();
+        assertEquals("node1", children.next().getName());
+        assertEquals("node3", children.next().getName());
+        assertFalse(children.hasNext());
+        
+        assertTrue(context.resourceResolver().hasChanges());
+        
+        context.resourceResolver().revert();
+
+        assertFalse(context.resourceResolver().hasChanges());
+        
+        assertNotNull(testRoot().getChild("node1"));
+        assertNull(testRoot().getChild("node2"));
+        assertNull(testRoot().getChild("node3"));
+        
+        children = testRoot().listChildren();
+        assertEquals("node0", children.next().getName());
+        assertEquals("node1", children.next().getName());
+        assertFalse(children.hasNext());
+    }
+
+    @Test
+    public void testRecursiveDeleteWithoutCommit() throws PersistenceException {
+        Resource node1 = context.resourceResolver().create(testRoot(), "node1", ImmutableMap.<String, Object>of());
+        Resource node11 = context.resourceResolver().create(node1, "node11", ImmutableMap.<String, Object>of());
+        context.resourceResolver().create(node11, "node111", ImmutableMap.<String, Object>of());
+
+        assertNotNull(testRoot().getChild("node1"));
+        assertNotNull(testRoot().getChild("node1/node11"));
+        assertNotNull(testRoot().getChild("node1/node11/node111"));
+        
+        context.resourceResolver().delete(node1);
+
+        assertNull(testRoot().getChild("node1"));
+        assertNull(testRoot().getChild("node1/node11"));
+        assertNull(testRoot().getChild("node1/node11/node111"));
+    }
+
+    @Test
+    public void testRecursiveDeleteWithCommit() throws PersistenceException {
+        Resource node1 = context.resourceResolver().create(testRoot(), "node1", ImmutableMap.<String, Object>of());
+        Resource node11 = context.resourceResolver().create(node1, "node11", ImmutableMap.<String, Object>of());
+        context.resourceResolver().create(node11, "node111", ImmutableMap.<String, Object>of());
+        
+        assertTrue(context.resourceResolver().hasChanges());
+        
+        context.resourceResolver().commit();
+
+        assertFalse(context.resourceResolver().hasChanges());
+        
+        assertNotNull(testRoot().getChild("node1"));
+        assertNotNull(testRoot().getChild("node1/node11"));
+        assertNotNull(testRoot().getChild("node1/node11/node111"));
+        
+        context.resourceResolver().delete(node1);
+
+        assertNull(testRoot().getChild("node1"));
+        assertNull(testRoot().getChild("node1/node11"));
+        assertNull(testRoot().getChild("node1/node11/node111"));
+
+        assertTrue(context.resourceResolver().hasChanges());
+
+        context.resourceResolver().commit();
+
+        assertFalse(context.resourceResolver().hasChanges());
+
+        assertNull(testRoot().getChild("node1"));
+        assertNull(testRoot().getChild("node1/node11"));
+        assertNull(testRoot().getChild("node1/node11/node111"));
+    }
+
+    @Test(expected = PersistenceException.class)
+    public void testCreateAlreadyExistWithoutCommit() throws PersistenceException {
+        context.resourceResolver().create(testRoot(), "node1", ImmutableMap.<String, Object>of());
+        context.resourceResolver().create(testRoot(), "node1", ImmutableMap.<String, Object>of());
+    }
+    
+    @Test(expected = PersistenceException.class)
+    public void testCreateAlreadyExistWithCommit() throws PersistenceException {
+        context.resourceResolver().create(testRoot(), "node1", ImmutableMap.<String, Object>of());
+        context.resourceResolver().commit();
+        context.resourceResolver().create(testRoot(), "node1", ImmutableMap.<String, Object>of());
+    }
+    
+    @Test
+    public void testCreateAlreadyExistDeletedWithoutCommit() throws PersistenceException {
+        context.resourceResolver().create(testRoot(), "node1", ImmutableMap.<String, Object>of());
+        context.resourceResolver().delete(testRoot().getChild("node1"));
+        context.resourceResolver().create(testRoot(), "node1", ImmutableMap.<String, Object>of());
+    }
+    
+    @Test
+    public void testCreateAlreadyExistDeletedWithCommit() throws PersistenceException {
+        context.resourceResolver().create(testRoot(), "node1", ImmutableMap.<String, Object>of());
+        context.resourceResolver().commit();
+        context.resourceResolver().delete(testRoot().getChild("node1"));
+        context.resourceResolver().commit();
+        context.resourceResolver().create(testRoot(), "node1", ImmutableMap.<String, Object>of());
+    }
+    
+    @Test
+    public void testUpdateWithoutCommit() throws PersistenceException {
+        Resource node1 = context.resourceResolver().create(testRoot(), "node1", ImmutableMap.<String, Object>of("prop1", "value1"));
+        assertEquals("value1", node1.getValueMap().get("prop1", String.class));
+        
+        ModifiableValueMap props = node1.adaptTo(ModifiableValueMap.class);
+        props.put("prop1", "value2");
+        
+        node1 = testRoot().getChild("node1");
+        assertEquals("value2", node1.getValueMap().get("prop1", String.class));
+    }
+    
+    @Test
+    public void testUpdateWithCommit() throws PersistenceException {
+        Resource node1 = context.resourceResolver().create(testRoot(), "node1", ImmutableMap.<String, Object>of("prop1", "value1"));
+        assertEquals("value1", node1.getValueMap().get("prop1", String.class));
+        context.resourceResolver().commit();
+        
+        ModifiableValueMap props = node1.adaptTo(ModifiableValueMap.class);
+        props.put("prop1", "value2");
+        context.resourceResolver().commit();
+        
+        node1 = testRoot().getChild("node1");
+        assertEquals("value2", node1.getValueMap().get("prop1", String.class));
+    }
+    
+}
diff --git a/src/test/java/org/apache/sling/nosql/generic/resource/impl/PathUtilTest.java b/src/test/java/org/apache/sling/nosql/generic/resource/impl/PathUtilTest.java
new file mode 100644
index 0000000..67efd33
--- /dev/null
+++ b/src/test/java/org/apache/sling/nosql/generic/resource/impl/PathUtilTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.resource.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.regex.Pattern;
+
+import org.junit.Test;
+
+public class PathUtilTest {
+
+    @Test
+    public void testGetChildPathPattern() {
+        Pattern pattern = PathUtil.getChildPathPattern("/my/path");
+        
+        assertFalse(pattern.matcher("/my/path").matches());
+        assertTrue(pattern.matcher("/my/path/child1").matches());
+        assertTrue(pattern.matcher("/my/path/child2").matches());
+        assertFalse(pattern.matcher("/my/path/child1/subchild1").matches());
+        assertFalse(pattern.matcher("/my/path/child1/subchild1/subchild2").matches());
+        assertFalse(pattern.matcher("/my/sibling").matches());
+        assertFalse(pattern.matcher("/other").matches());
+    }
+
+    @Test
+    public void testGetDescendantPathPattern() {
+        Pattern pattern = PathUtil.getSameOrDescendantPathPattern("/my/path");
+        
+        assertTrue(pattern.matcher("/my/path").matches());
+        assertTrue(pattern.matcher("/my/path/child1").matches());
+        assertTrue(pattern.matcher("/my/path/child2").matches());
+        assertTrue(pattern.matcher("/my/path/child1/subchild1").matches());
+        assertTrue(pattern.matcher("/my/path/child1/subchild1/subchild2").matches());
+        assertFalse(pattern.matcher("/my/sibling").matches());
+        assertFalse(pattern.matcher("/other").matches());
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/nosql/generic/simple/SimpleNoSqlResourceProviderQueryTest.java b/src/test/java/org/apache/sling/nosql/generic/simple/SimpleNoSqlResourceProviderQueryTest.java
new file mode 100644
index 0000000..6c79168
--- /dev/null
+++ b/src/test/java/org/apache/sling/nosql/generic/simple/SimpleNoSqlResourceProviderQueryTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.simple;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceProvider;
+import org.apache.sling.nosql.generic.simple.provider.SimpleNoSqlResourceProviderFactory;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Test basic ResourceResolver and ValueMap with different data types.
+ */
+public class SimpleNoSqlResourceProviderQueryTest {
+    
+    @Rule
+    public SlingContext context = new SlingContext(ResourceResolverType.JCR_MOCK);
+    
+    private Resource testRoot;
+
+    @Before
+    public void setUp() throws Exception {
+        context.registerInjectActivateService(new SimpleNoSqlResourceProviderFactory(), ImmutableMap.<String, Object>builder()
+                .put(ResourceProvider.ROOTS, "/nosql-simple")
+                .build());
+        
+        // prepare some test data using Sling CRUD API
+        Map<String, Object> props = new HashMap<String, Object>();
+        props.put(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED);
+        final Resource root = context.resourceResolver().getResource("/");
+        Resource noSqlRoot = context.resourceResolver().create(root, "nosql-simple", props);
+        this.testRoot = context.resourceResolver().create(noSqlRoot, "test", props);
+        
+        context.resourceResolver().create(testRoot, "node1", ImmutableMap.<String, Object>of("prop1", "value1"));
+        context.resourceResolver().create(testRoot, "node2", ImmutableMap.<String, Object>of("prop1", "value2"));
+        
+        context.resourceResolver().commit();
+    }
+
+    @Test
+    public void testFindResources_ValidQuery() {
+        Iterator<Resource> result = context.resourceResolver().findResources("all", "simple");
+        assertEquals("/nosql-simple", result.next().getPath());
+        assertEquals("/nosql-simple/test", result.next().getPath());
+        assertEquals("/nosql-simple/test/node1", result.next().getPath());
+        assertEquals("/nosql-simple/test/node2", result.next().getPath());
+        assertFalse(result.hasNext());
+    }
+
+    @Test
+    public void testFindResources_InvalidQuery() {
+        Iterator<Resource> result = context.resourceResolver().findResources("all", "invalid");
+        assertFalse(result.hasNext());
+    }
+
+    @Test
+    public void testQueryResources_ValidQuery() {
+        Iterator<Map<String, Object>> result = context.resourceResolver().queryResources("all", "simple");
+        assertNull(result.next().get("prop1"));
+        assertNull(result.next().get("prop1"));
+        assertEquals("value1", result.next().get("prop1"));
+        assertEquals("value2", result.next().get("prop1"));
+        assertFalse(result.hasNext());
+    }
+
+    @Test
+    public void testQueryResources_InvalidQuery() {
+        Iterator<Map<String, Object>> result = context.resourceResolver().queryResources("all", "invalid");
+        assertFalse(result.hasNext());
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/nosql/generic/simple/SimpleNoSqlResourceProviderTest.java b/src/test/java/org/apache/sling/nosql/generic/simple/SimpleNoSqlResourceProviderTest.java
new file mode 100644
index 0000000..aa37032
--- /dev/null
+++ b/src/test/java/org/apache/sling/nosql/generic/simple/SimpleNoSqlResourceProviderTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.simple;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceProvider;
+import org.apache.sling.nosql.generic.resource.impl.AbstractNoSqlResourceProviderTest;
+import org.apache.sling.nosql.generic.simple.provider.SimpleNoSqlResourceProviderFactory;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Test basic ResourceResolver and ValueMap with different data types.
+ */
+public class SimpleNoSqlResourceProviderTest extends AbstractNoSqlResourceProviderTest {
+    
+    private Resource testRoot;
+
+    @Override
+    protected void registerResourceProviderFactory() {
+        context.registerInjectActivateService(new SimpleNoSqlResourceProviderFactory(), ImmutableMap.<String, Object>builder()
+                .put(ResourceProvider.ROOTS, "/nosql-simple")
+                .build());
+    }
+
+    @Override
+    protected Resource testRoot() {
+        if (this.testRoot == null) {
+            try {
+                Map<String, Object> props = new HashMap<String, Object>();
+                props.put(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED);
+                final Resource root = context.resourceResolver().getResource("/");
+                Resource noSqlRoot = context.resourceResolver().create(root, "nosql-simple", props);
+                this.testRoot = context.resourceResolver().create(noSqlRoot, "test", props);
+            }
+            catch (PersistenceException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+        return this.testRoot;
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/nosql/generic/simple/SimpleNoSqlResourceProviderTransactionalTest.java b/src/test/java/org/apache/sling/nosql/generic/simple/SimpleNoSqlResourceProviderTransactionalTest.java
new file mode 100644
index 0000000..6c8fe12
--- /dev/null
+++ b/src/test/java/org/apache/sling/nosql/generic/simple/SimpleNoSqlResourceProviderTransactionalTest.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.simple;
+
+import static org.junit.Assert.assertNull;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceProvider;
+import org.apache.sling.nosql.generic.resource.impl.AbstractNoSqlResourceProviderTransactionalTest;
+import org.apache.sling.nosql.generic.simple.provider.SimpleNoSqlResourceProviderFactory;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Test basic ResourceResolver and ValueMap with different data types.
+ */
+public class SimpleNoSqlResourceProviderTransactionalTest extends AbstractNoSqlResourceProviderTransactionalTest {
+    
+    private Resource testRoot;
+
+    @Override
+    protected void registerResourceProviderFactory() {
+        context.registerInjectActivateService(new SimpleNoSqlResourceProviderFactory(), ImmutableMap.<String, Object>builder()
+                .put(ResourceProvider.ROOTS, "/nosql-simple")
+                .build());
+    }
+
+    @Override
+    protected Resource testRoot() {
+        if (this.testRoot == null) {
+            try {
+                Map<String, Object> props = new HashMap<String, Object>();
+                props.put(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED);
+                final Resource root = context.resourceResolver().getResource("/");
+                Resource noSqlRoot = context.resourceResolver().create(root, "nosql-simple", props);
+                this.testRoot = context.resourceResolver().create(noSqlRoot, "test", props);
+                context.resourceResolver().commit();
+            }
+            catch (PersistenceException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+        return this.testRoot;
+    }
+
+    @Test
+    public void testGetInvalidPath() {
+        assertNull(context.resourceResolver().getResource(testRoot().getPath() + "/invalid/1"));
+    }
+    
+}
diff --git a/src/test/java/org/apache/sling/nosql/generic/simple/provider/SimpleNoSqlAdapter.java b/src/test/java/org/apache/sling/nosql/generic/simple/provider/SimpleNoSqlAdapter.java
new file mode 100644
index 0000000..f1743ff
--- /dev/null
+++ b/src/test/java/org/apache/sling/nosql/generic/simple/provider/SimpleNoSqlAdapter.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.simple.provider;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.nosql.generic.adapter.NoSqlAdapter;
+import org.apache.sling.nosql.generic.adapter.NoSqlData;
+import org.apache.sling.nosql.generic.resource.impl.PathUtil;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterators;
+
+/**
+ * Stores resource data in a hash map for testing.
+ */
+public class SimpleNoSqlAdapter implements NoSqlAdapter {
+    
+    private final SortedMap<String, Map<String,Object>> store = new TreeMap<String, Map<String,Object>>();
+
+    public boolean validPath(String path) {
+        return !(StringUtils.contains(path, "/invalid/") || StringUtils.endsWith(path, "/invalid"));
+    }
+
+    public NoSqlData get(String path) {
+        Map<String,Object> properties = store.get(path);
+        if (properties != null) {
+            return new NoSqlData(path, properties);
+        }
+        else {
+            return null;
+        }
+    }
+
+    public Iterator<NoSqlData> getChildren(String parentPath) {
+        Iterator<String> keys = store.keySet().iterator();
+        
+        final Pattern childKeyPattern = PathUtil.getChildPathPattern(parentPath);
+        Iterator<String> childKeys = Iterators.filter(keys, new Predicate<String>() {
+            public boolean apply(String path) {
+                return childKeyPattern.matcher(path).matches();
+            }
+        });
+        
+        return Iterators.transform(childKeys, new Function<String, NoSqlData>() {
+            public NoSqlData apply(String path) {
+                return get(path);
+            }
+        });
+    }
+
+    public boolean store(NoSqlData data) {
+        boolean exists = store.containsKey(data.getPath());
+        store.put(data.getPath(), new HashMap<String, Object>(data.getProperties()));
+        return !exists;
+    }
+
+    public boolean deleteRecursive(String path) {
+        boolean deletedAnything = false;
+        final Pattern pathToDeletePattern = PathUtil.getSameOrDescendantPathPattern(path);
+        Iterator<Entry<String, Map<String,Object>>> entries = store.entrySet().iterator();
+        while (entries.hasNext()) {
+            Entry<String, Map<String,Object>> entry = entries.next();
+            if (pathToDeletePattern.matcher(entry.getKey()).matches()) {
+                entries.remove();
+                deletedAnything = true;
+            }
+        }
+        return deletedAnything;
+    }
+
+    public Iterator<NoSqlData> query(String query, String language) {
+        // implement simple dummy query
+        if (StringUtils.equals(language, "simple") && StringUtils.equals(query, "all")) {
+            final Iterator<Entry<String, Map<String,Object>>> entries = store.entrySet().iterator();
+            return new Iterator<NoSqlData>() {
+                public boolean hasNext() {
+                    return entries.hasNext();
+                }
+                public NoSqlData next() {
+                    Entry<String, Map<String,Object>> entry = entries.next();
+                    return new NoSqlData(entry.getKey(), entry.getValue());
+                }
+                public void remove() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+        }
+        return Collections.<NoSqlData>emptyList().iterator();
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/nosql/generic/simple/provider/SimpleNoSqlResourceProviderFactory.java b/src/test/java/org/apache/sling/nosql/generic/simple/provider/SimpleNoSqlResourceProviderFactory.java
new file mode 100644
index 0000000..1a9d09b
--- /dev/null
+++ b/src/test/java/org/apache/sling/nosql/generic/simple/provider/SimpleNoSqlResourceProviderFactory.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.nosql.generic.simple.provider;
+
+import java.util.Map;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.ConfigurationPolicy;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.resource.QueriableResourceProvider;
+import org.apache.sling.api.resource.ResourceProvider;
+import org.apache.sling.api.resource.ResourceProviderFactory;
+import org.apache.sling.nosql.generic.adapter.NoSqlAdapter;
+import org.apache.sling.nosql.generic.resource.AbstractNoSqlResourceProviderFactory;
+import org.osgi.service.event.EventAdmin;
+
+/**
+ * Simple NoSQL resource provider factory based on {@link SimpleNoSqlAdapter} which just stores
+ * the resource data in a hash map.
+ */
+@Component(configurationFactory = true, policy = ConfigurationPolicy.REQUIRE, metatype = true)
+@Service(value = ResourceProviderFactory.class)
+@Properties({
+    @Property(name = ResourceProvider.ROOTS, value = ""),
+    @Property(name = QueriableResourceProvider.LANGUAGES, value = { "simple" })
+})
+public class SimpleNoSqlResourceProviderFactory extends AbstractNoSqlResourceProviderFactory {
+
+    @Reference
+    private EventAdmin eventAdmin;
+    
+    private NoSqlAdapter noSqlAdapter;
+    
+    @Activate
+    protected void activate(final Map<String, Object> props) {
+        noSqlAdapter = new SimpleNoSqlAdapter();
+    }
+    
+    @Override
+    protected NoSqlAdapter getNoSqlAdapter() {
+        return noSqlAdapter;
+    }
+
+    @Override
+    protected EventAdmin getEventAdmin() {
+        return eventAdmin;
+    }
+    
+    protected void bindEventAdmin(EventAdmin eventAdmin) {
+        this.eventAdmin = eventAdmin;
+    }
+
+    protected void unbindEventAdmin(EventAdmin eventAdmin) {
+        this.eventAdmin = null;
+    }
+
+}
diff --git a/src/test/resources/OSGI-INF/org.apache.sling.nosql.generic.simple.provider.SimpleNoSqlResourceProviderFactory.xml b/src/test/resources/OSGI-INF/org.apache.sling.nosql.generic.simple.provider.SimpleNoSqlResourceProviderFactory.xml
new file mode 100644
index 0000000..21f2864
--- /dev/null
+++ b/src/test/resources/OSGI-INF/org.apache.sling.nosql.generic.simple.provider.SimpleNoSqlResourceProviderFactory.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+    <scr:component name="org.apache.sling.nosql.generic.simple.SimpleNoSqlResourceProviderFactory" configuration-policy="require" activate="activate">
+        <implementation class="org.apache.sling.nosql.generic.simple.provider.SimpleNoSqlResourceProviderFactory"/>
+        <service servicefactory="false">
+            <provide interface="org.apache.sling.api.resource.ResourceProviderFactory"/>
+        </service>
+        <property name="provider.roots" value=""/>
+        <property name="provider.query.languages" value="simple"/>
+        <property name="service.vendor" value="The Apache Software Foundation"/>
+        <property name="service.pid" value="org.apache.sling.nosql.generic.simple.provider.SimpleNoSqlResourceProviderFactory"/>
+        <reference name="eventAdmin" interface="org.osgi.service.event.EventAdmin" cardinality="1..1" policy="static" bind="bindEventAdmin" unbind="unbindEventAdmin"/>
+    </scr:component>
+</components>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 16/23: SLING-4881 NoSQL Generic Resource Provider: Preserve order of changed resources (patch contributed by Levente Santha)

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit 0e42677e30d4c74e97995d97245bd4af8525164a
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Tue Jul 14 15:35:35 2015 +0000

    SLING-4881 NoSQL Generic Resource Provider: Preserve order of changed resources (patch contributed by Levente Santha)
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1690990 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/nosql/generic/resource/impl/NoSqlResourceProvider.java       | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
index 056c03e..2649323 100644
--- a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
@@ -24,6 +24,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.SortedMap;
@@ -56,7 +57,7 @@ public class NoSqlResourceProvider implements ResourceProvider, ModifyingResourc
     
     private final NoSqlAdapter adapter;
     private final EventAdmin eventAdmin;
-    private final Map<String, NoSqlData> changedResources = new HashMap<String, NoSqlData>();
+    private final Map<String, NoSqlData> changedResources = new LinkedHashMap<String, NoSqlData>();
     private final Set<String> deletedResources = new HashSet<String>();
     
     public NoSqlResourceProvider(NoSqlAdapter adapter, EventAdmin eventAdmin) {

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 08/23: SLING-4381 allow null map when creating a resource

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit 330fa606090d7785423875944f21e12be198d1f6
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Thu May 21 08:54:21 2015 +0000

    SLING-4381 allow null map when creating a resource
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1680767 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                                             | 6 ++++++
 .../sling/nosql/generic/resource/impl/NoSqlResourceProvider.java    | 3 ++-
 .../generic/resource/impl/AbstractNoSqlResourceProviderTest.java    | 6 ++++++
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index ec6cdb2..1ec9f11 100644
--- a/pom.xml
+++ b/pom.xml
@@ -132,6 +132,12 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.logging-mock</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>javax.jcr</groupId>
             <artifactId>jcr</artifactId>
             <version>2.0</version>
diff --git a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
index a1bc13f..1df45cb 100644
--- a/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
+++ b/src/main/java/org/apache/sling/nosql/generic/resource/impl/NoSqlResourceProvider.java
@@ -148,7 +148,8 @@ public class NoSqlResourceProvider implements ResourceProvider, ModifyingResourc
         }
         
         // create new resource in changeset
-        NoSqlData data = new NoSqlData(path, NoSqlValueMap.convertForWriteAll(new HashMap<String, Object>(properties)));
+        Map<String, Object> writableMap = properties != null ? new HashMap<String, Object>(properties) : new HashMap<String, Object>();
+        NoSqlData data = new NoSqlData(path, NoSqlValueMap.convertForWriteAll(writableMap));
         changedResources.put(path, data);
         return new NoSqlResource(data, resolver, this);
     }
diff --git a/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderTest.java b/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderTest.java
index eda8f8c..fde5152 100644
--- a/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderTest.java
+++ b/src/test/java/org/apache/sling/nosql/generic/resource/impl/AbstractNoSqlResourceProviderTest.java
@@ -208,4 +208,10 @@ public abstract class AbstractNoSqlResourceProviderTest {
         assertEquals(JcrConstants.NT_UNSTRUCTURED, resource.getResourceType());
     }
 
+    @Test
+    public void testCreateWithNullMap() throws IOException {
+        Resource resource1 = context.resourceResolver().getResource(testRoot().getPath() + "/node1");
+        context.resourceResolver().create(resource1, "nullMap", null);
+    }
+
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 12/23: update to released mock versions

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit 9083d70c17fde1c9733ecdc6ef35422b9df0145b
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Sat May 30 10:00:03 2015 +0000

    update to released mock versions
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1682593 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/pom.xml b/pom.xml
index 1ec9f11..e0c5045 100644
--- a/pom.xml
+++ b/pom.xml
@@ -128,13 +128,13 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.testing.sling-mock</artifactId>
-            <version>1.2.1-SNAPSHOT</version>
+            <version>1.3.0</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.testing.logging-mock</artifactId>
-            <version>1.0.0-SNAPSHOT</version>
+            <version>1.0.0</version>
             <scope>test</scope>
         </dependency>
         <dependency>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 23/23: [maven-release-plugin] copy for tag org.apache.sling.nosql.generic-1.0.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit 7a67728e73179ed360958dbe26555fc0e6f5ee83
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Thu Sep 17 21:27:19 2015 +0000

    [maven-release-plugin] copy for tag org.apache.sling.nosql.generic-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.nosql.generic-1.0.0@1703696 13f79535-47bb-0310-9956-ffa450edef68

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-nosql-generic] 17/23: Added Eclipse files to svn:ignore in the new contrib bundles

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.nosql.generic-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-nosql-generic.git

commit e5ad3dd5641fef10e4daf6b35e7bfdc255f720dd
Author: Tomasz Rekawek <to...@apache.org>
AuthorDate: Tue Sep 1 11:45:20 2015 +0000

    Added Eclipse files to svn:ignore in the new contrib bundles
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/nosql/generic@1700501 13f79535-47bb-0310-9956-ffa450edef68

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.