You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by wi...@apache.org on 2014/06/13 10:57:34 UTC

[014/100] [abbrv] [partial] Reverting the erroneous merge by Sebastian according to the instructions in INFRA-6876

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-tripletable/src/test/java/org/apache/marmotta/kiwi/model/caching/TripleTableTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-tripletable/src/test/java/org/apache/marmotta/kiwi/model/caching/TripleTableTest.java b/libraries/kiwi/kiwi-tripletable/src/test/java/org/apache/marmotta/kiwi/model/caching/TripleTableTest.java
new file mode 100644
index 0000000..98858bc
--- /dev/null
+++ b/libraries/kiwi/kiwi-tripletable/src/test/java/org/apache/marmotta/kiwi/model/caching/TripleTableTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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.marmotta.kiwi.model.caching;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Test;
+import org.openrdf.model.Literal;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.model.impl.LiteralImpl;
+import org.openrdf.model.impl.StatementImpl;
+import org.openrdf.model.impl.URIImpl;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test cases for triple tables.
+ *
+ * @author Sebastian Schaffert (sschaffert@apache.org)
+ */
+public class TripleTableTest {
+
+
+
+    @Test
+    public void testListTriples() {
+        URI subject1 = new URIImpl("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+        URI subject2 = new URIImpl("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+        URI predicate1 = new URIImpl("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+        URI predicate2 = new URIImpl("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+        Literal object1 = new LiteralImpl("http://localhost/"+ RandomStringUtils.random(40));
+        Literal object2 = new LiteralImpl("http://localhost/"+ RandomStringUtils.random(40));
+
+        Statement stmt1 = new StatementImpl(subject1,predicate1,object1);
+        Statement stmt2 = new StatementImpl(subject1,predicate1,object2);
+        Statement stmt3 = new StatementImpl(subject1,predicate2,object1);
+        Statement stmt4 = new StatementImpl(subject1,predicate2,object2);
+        Statement stmt5 = new StatementImpl(subject2,predicate1,object1);
+        Statement stmt6 = new StatementImpl(subject2,predicate1,object2);
+        Statement stmt7 = new StatementImpl(subject2,predicate2,object1);
+        Statement stmt8 = new StatementImpl(subject2,predicate2,object2);
+
+        TripleTable<Statement> table = new TripleTable<>();
+        table.add(stmt1);
+        table.add(stmt2);
+        table.add(stmt3);
+        table.add(stmt4);
+        table.add(stmt5);
+        table.add(stmt6);
+        table.add(stmt7);
+        //table.add(stmt8);
+
+        // tests
+
+        // 1. test existence and non-existence of a triple
+        assertEquals(1, table.listTriples(subject2,predicate2,object1,null, true).size());
+        assertEquals(0, table.listTriples(subject2,predicate2,object2,null, true).size());
+
+        // 2. test listing with wildcards
+        assertEquals(7, table.listTriples(null,null,null,null, true).size());
+        assertEquals(4, table.listTriples(subject1,null,null,null, true).size());
+        assertEquals(3, table.listTriples(subject2,null,null,null, true).size());
+        assertEquals(4, table.listTriples(null,predicate1,null,null, true).size());
+        assertEquals(3, table.listTriples(null,predicate2,null,null, true).size());
+        assertEquals(4, table.listTriples(null,null,object1,null, true).size());
+        assertEquals(3, table.listTriples(null,null,object2,null, true).size());
+        assertEquals(2, table.listTriples(subject1,predicate1,null,null, true).size());
+        assertEquals(1, table.listTriples(subject2,predicate2,null,null, true).size());
+    }
+
+    @Test
+    public void testRemoveTriples() {
+        URI subject1 = new URIImpl("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+        URI subject2 = new URIImpl("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+        URI predicate1 = new URIImpl("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+        URI predicate2 = new URIImpl("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+        Literal object1 = new LiteralImpl("http://localhost/"+ RandomStringUtils.random(40));
+        Literal object2 = new LiteralImpl("http://localhost/"+ RandomStringUtils.random(40));
+
+        Statement stmt1 = new StatementImpl(subject1,predicate1,object1);
+        Statement stmt2 = new StatementImpl(subject1,predicate1,object2);
+        Statement stmt3 = new StatementImpl(subject1,predicate2,object1);
+        Statement stmt4 = new StatementImpl(subject1,predicate2,object2);
+        Statement stmt5 = new StatementImpl(subject2,predicate1,object1);
+        Statement stmt6 = new StatementImpl(subject2,predicate1,object2);
+        Statement stmt7 = new StatementImpl(subject2,predicate2,object1);
+        Statement stmt8 = new StatementImpl(subject2,predicate2,object2);
+
+        TripleTable<Statement> table = new TripleTable<>();
+        table.add(stmt1);
+        table.add(stmt2);
+        table.add(stmt3);
+        table.add(stmt4);
+        table.add(stmt5);
+        table.add(stmt6);
+        table.add(stmt7);
+        table.add(stmt8);
+
+        // tests
+
+        // 1. test existence and non-existence of a triple
+        assertEquals(1, table.listTriples(subject2,predicate2,object1,null, true).size());
+        assertEquals(1, table.listTriples(subject2,predicate2,object2,null, true).size());
+
+
+        table.remove(stmt8);
+
+        assertEquals(1, table.listTriples(subject2,predicate2,object1,null, true).size());
+        assertEquals(0, table.listTriples(subject2,predicate2,object2,null, true).size());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-versioning/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-versioning/pom.xml b/libraries/kiwi/kiwi-versioning/pom.xml
index 3d37f81..81c2a4c 100644
--- a/libraries/kiwi/kiwi-versioning/pom.xml
+++ b/libraries/kiwi/kiwi-versioning/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.marmotta</groupId>
         <artifactId>kiwi-parent</artifactId>
-        <version>3.1.0-incubating-SNAPSHOT</version>
+        <version>3.1.0-incubating</version>
         <relativePath>../</relativePath>
     </parent>
 
@@ -74,8 +74,8 @@
             <artifactId>guava</artifactId>
         </dependency>
         <dependency>
-            <groupId>commons-lang</groupId>
-            <artifactId>commons-lang</artifactId>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.marmotta</groupId>
@@ -129,7 +129,7 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.jumpmind.symmetric.jdbc</groupId>
+            <groupId>org.postgresql</groupId>
             <artifactId>postgresql</artifactId>
             <scope>test</scope>
         </dependency>

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/persistence/KiWiVersioningConnection.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/persistence/KiWiVersioningConnection.java b/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/persistence/KiWiVersioningConnection.java
index 054cf20..2ef8946 100644
--- a/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/persistence/KiWiVersioningConnection.java
+++ b/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/persistence/KiWiVersioningConnection.java
@@ -17,6 +17,7 @@
  */
 package org.apache.marmotta.kiwi.versioning.persistence;
 
+import com.google.common.base.Preconditions;
 import info.aduna.iteration.CloseableIteration;
 import info.aduna.iteration.EmptyIteration;
 import info.aduna.iteration.ExceptionConvertingIteration;
@@ -130,6 +131,65 @@ public class KiWiVersioningConnection extends KiWiConnection {
     }
 
     /**
+     * Remove the version with the id passed as argument, including all references to added and removed triples. The
+     * triples themselves are not deleted immediately, we let the garbage collector carry this out periodically.
+     * @param id
+     * @throws SQLException
+     */
+    public void removeVersion(Long id) throws SQLException {
+        Preconditions.checkNotNull(id);
+        Preconditions.checkArgument(id > 0);
+
+        requireJDBCConnection();
+
+        PreparedStatement removeAdded = getPreparedStatement("delete.version_added");
+        removeAdded.clearParameters();
+        removeAdded.setLong(1, id);
+        removeAdded.executeUpdate();
+
+        PreparedStatement removeRemoved = getPreparedStatement("delete.version_removed");
+        removeRemoved.clearParameters();
+        removeRemoved.setLong(1, id);
+        removeRemoved.executeUpdate();
+
+        PreparedStatement removeVersion = getPreparedStatement("delete.version");
+        removeVersion.clearParameters();
+        removeVersion.setLong(1, id);
+        removeVersion.executeUpdate();
+
+    }
+
+    /**
+     * Remove all versions until the date given as argument. Iterates over all versions and deletes them individually.
+     * Entries in join tables (added/removed triples) are also deleted, the triples themselves not. Deleted triples
+     * without version will later be cleaned up by the garbage collector
+     * @param until date until when to delete versions
+     * @throws SQLException
+     */
+    public void removeVersions(Date until) throws SQLException {
+        removeVersions(new Date(0), until);
+    }
+
+
+    /**
+     * Remove all versions in the given time interval. Iterates over all versions and deletes them individually.
+     * Entries in join tables (added/removed triples) are also deleted, the triples themselves not. Deleted triples
+     * without version will later be cleaned up by the garbage collector
+     * @param from date after which versions will be deleted
+     * @param to   date before which versions will be deleted
+     * @throws SQLException
+     */
+    public void removeVersions(Date from, Date to) throws SQLException {
+        CloseableIteration<Version, SQLException> it = listVersionsInternal(from,to);
+        while(it.hasNext()) {
+            Version next = it.next();
+            removeVersion(next.getId());
+        }
+    }
+
+
+
+    /**
      * Retrieve a version by its id. If the version does not exist, returns null
      *
      * @param id

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/persistence/KiWiVersioningPersistence.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/persistence/KiWiVersioningPersistence.java b/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/persistence/KiWiVersioningPersistence.java
index 797c58c..a3bb6a6 100644
--- a/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/persistence/KiWiVersioningPersistence.java
+++ b/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/persistence/KiWiVersioningPersistence.java
@@ -46,10 +46,6 @@ public class KiWiVersioningPersistence {
 
     public KiWiVersioningPersistence(KiWiPersistence persistence) {
         this.persistence = persistence;
-
-        persistence.addNodeTableDependency("versions", "creator");
-        persistence.addTripleTableDependency("versions_added","triple_id");
-        persistence.addTripleTableDependency("versions_removed","triple_id");
     }
 
     /**
@@ -58,6 +54,10 @@ public class KiWiVersioningPersistence {
      */
     public void initDatabase() throws SQLException {
         persistence.initDatabase("versioning", new String[] {"versions", "versions_added", "versions_removed"});
+
+        persistence.addNodeTableDependency("versions", "creator");
+        persistence.addTripleTableDependency("versions_added","triple_id");
+        persistence.addTripleTableDependency("versions_removed","triple_id");
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/sail/KiWiVersioningSail.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/sail/KiWiVersioningSail.java b/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/sail/KiWiVersioningSail.java
index 91de399..84f448b 100644
--- a/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/sail/KiWiVersioningSail.java
+++ b/libraries/kiwi/kiwi-versioning/src/main/java/org/apache/marmotta/kiwi/versioning/sail/KiWiVersioningSail.java
@@ -34,6 +34,8 @@ import org.openrdf.model.Statement;
 import org.openrdf.model.URI;
 import org.openrdf.repository.RepositoryException;
 import org.openrdf.repository.RepositoryResult;
+import org.openrdf.repository.sail.SailRepositoryConnection;
+import org.openrdf.sail.SailConnection;
 import org.openrdf.sail.SailException;
 import org.openrdf.sail.StackableSail;
 import org.slf4j.Logger;
@@ -72,33 +74,33 @@ public class KiWiVersioningSail extends TransactionalSailWrapper implements Tran
 
     private SesameFilter<Statement> filter;
 
-	/**
-	 * Build a new {@link KiWiVersioningSail} based on the provided parent
-	 * {@link TransactionalSail}.
-	 * 
-	 * @param parent
-	 *            the {@link TransactionalSail} to base the
-	 *            {@link KiWiVersioningSail} on.
-	 */
+    /**
+     * Build a new {@link KiWiVersioningSail} based on the provided parent
+     * {@link TransactionalSail}.
+     *
+     * @param parent
+     *            the {@link TransactionalSail} to base the
+     *            {@link KiWiVersioningSail} on.
+     */
     public KiWiVersioningSail(TransactionalSail parent) {
         this(parent,new AlwaysTrueFilter<Statement>());
     }
 
-	/**
-	 * Build a new selective {@link KiWiVersioningSail} based on the provided
-	 * parent {@link TransactionalSail}. Only {@link Statement}s that are
-	 * accepted by the filter are included in versioning.
-	 * 
-	 * @param parent
-	 *            the {@link TransactionalSail} to base the
-	 *            {@link KiWiVersioningSail} on.
-	 * @param filter
-	 *            a {@link SesameFilter} to filter out {@link Statement}s that
-	 *            should not be versioned. Only a {@link Statement} that is
-	 *            accepted by this filter will be versioned.
-	 * 
-	 * @see SesameFilter#accept(Object)
-	 */
+    /**
+     * Build a new selective {@link KiWiVersioningSail} based on the provided
+     * parent {@link TransactionalSail}. Only {@link Statement}s that are
+     * accepted by the filter are included in versioning.
+     *
+     * @param parent
+     *            the {@link TransactionalSail} to base the
+     *            {@link KiWiVersioningSail} on.
+     * @param filter
+     *            a {@link SesameFilter} to filter out {@link Statement}s that
+     *            should not be versioned. Only a {@link Statement} that is
+     *            accepted by this filter will be versioned.
+     *
+     * @see SesameFilter#accept(Object)
+     */
     public KiWiVersioningSail(TransactionalSail parent, SesameFilter<Statement> filter) {
         super(parent);
         this.persistence = new KiWiVersioningPersistence(getBaseStore().getPersistence());
@@ -316,12 +318,80 @@ public class KiWiVersioningSail extends TransactionalSailWrapper implements Tran
         }
     }
 
+
+    /**
+     * Remove the version with the id passed as argument, including all references to added and removed triples. The
+     * triples themselves are not deleted immediately, we let the garbage collector carry this out periodically.
+     * @param id  the database ID of the version (see {@link Version#getId()})
+     * @throws SailException
+     */
+    public void removeVersion(Long id) throws SailException {
+        try {
+            final KiWiVersioningConnection connection = persistence.getConnection();
+            try {
+                connection.removeVersion(id);
+                connection.commit();
+            } finally {
+                connection.close();
+            }
+
+        } catch(SQLException ex) {
+            throw new SailException("database error while listing versions",ex);
+        }
+    }
+
+    /**
+     * Remove all versions until the date given as argument. Iterates over all versions and deletes them individually.
+     * Entries in join tables (added/removed triples) are also deleted, the triples themselves not. Deleted triples
+     * without version will later be cleaned up by the garbage collector
+     * @param until date until when to delete versions
+     * @throws SailException
+     */
+    public void removeVersions(Date until) throws SailException {
+        try {
+            final KiWiVersioningConnection connection = persistence.getConnection();
+            try {
+                connection.removeVersions(until);
+                connection.commit();
+            } finally {
+                connection.close();
+            }
+
+        } catch(SQLException ex) {
+            throw new SailException("database error while listing versions",ex);
+        }
+    }
+
+
+    /**
+     * Remove all versions in the given time interval. Iterates over all versions and deletes them individually.
+     * Entries in join tables (added/removed triples) are also deleted, the triples themselves not. Deleted triples
+     * without version will later be cleaned up by the garbage collector
+     * @param from date after which versions will be deleted
+     * @param to   date before which versions will be deleted
+     * @throws SailException
+     */
+    public void removeVersions(Date from, Date to) throws SailException {
+        try {
+            final KiWiVersioningConnection connection = persistence.getConnection();
+            try {
+                connection.removeVersions(from, to);
+                connection.commit();
+            } finally {
+                connection.close();
+            }
+
+        } catch(SQLException ex) {
+            throw new SailException("database error while listing versions",ex);
+        }
+    }
+
     /**
      * Return the version that is the most recent version for a resource given a reference date. The method will either
      * return the version that was current for the resource at the given date or return null in case such a version
      * does not exist (e.g. before the resource was created).
      *
-     * @param resource  the resource for which to find a version
+     * @param r         the resource for which to find a version
      * @param date      the reference date
      * @return the latest version of the resource at the given date, or null if such a version does not exist
      * @throws SQLException
@@ -405,6 +475,32 @@ public class KiWiVersioningSail extends TransactionalSailWrapper implements Tran
         }
     }
 
+    /**
+     * Revert (undo) the version given as argument. This method creates a new transaction, adds all triples
+     * that were deleted in the old version, removes all triples that were added in the old version, and commits
+     * the transaction, effectively creating a new (reverted) version.
+     *
+     * @param version    the version to revert
+     * @throws SailException in case reverting the version failed
+     */
+    public void revertVersion(Version version) throws SailException {
+        SailConnection con = getConnection();
+        try {
+            con.begin();
+
+            for(Statement stmt : version.getAddedTriples()) {
+                con.removeStatements(stmt.getSubject(), stmt.getPredicate(), stmt.getObject(), stmt.getContext());
+            }
+
+            for(Statement stmt : version.getRemovedTriples()) {
+                con.addStatement(stmt.getSubject(), stmt.getPredicate(), stmt.getObject(), stmt.getContext());
+            }
+
+            con.commit();
+        } finally {
+            con.close();
+        }
+    }
 
 
     @Override

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties b/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties
index 1001040..e5b1ae3 100644
--- a/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties
+++ b/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/h2/statements.properties
@@ -48,4 +48,4 @@ store.version_removed = INSERT INTO versions_removed (version_id,triple_id) VALU
 
 delete.version_added   = DELETE FROM versions_added WHERE version_id = ?
 delete.version_removed = DELETE FROM versions_removed WHERE version_id = ?
-delete.version         = DELETE FROM verions WHERE id = ?
\ No newline at end of file
+delete.version         = DELETE FROM versions WHERE id = ?
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties b/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties
index 65a39a2..47d7f6a 100644
--- a/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties
+++ b/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/mysql/statements.properties
@@ -19,6 +19,7 @@
 # get sequence numbers
 seq.versions.prep     = UPDATE seq_versions SET id=LAST_INSERT_ID(id+1);
 seq.versions          = SELECT LAST_INSERT_ID();
+seq.versions.set      = UPDATE seq_versions SET id=?;
 
 load.version_by_id    = SELECT id,creator,createdAt FROM versions WHERE id = ?
 load.version_between  = SELECT id,creator,createdAt FROM versions WHERE createdAt > ? AND createdAt <= ? ORDER BY createdAt ASC
@@ -49,4 +50,4 @@ store.version_removed = INSERT INTO versions_removed (version_id,triple_id) VALU
 
 delete.version_added   = DELETE FROM versions_added WHERE version_id = ?
 delete.version_removed = DELETE FROM versions_removed WHERE version_id = ?
-delete.version         = DELETE FROM verions WHERE id = ?
\ No newline at end of file
+delete.version         = DELETE FROM versions WHERE id = ?
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties b/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties
index 442fb02..441adfc 100644
--- a/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties
+++ b/libraries/kiwi/kiwi-versioning/src/main/resources/org/apache/marmotta/kiwi/persistence/pgsql/statements.properties
@@ -18,6 +18,7 @@
 
 # get sequence numbers
 seq.versions          = SELECT nextval('seq_versions')
+seq.versions.set      = SELECT setval('seq_versions',?)
 
 load.version_by_id    = SELECT id,creator,createdAt FROM versions WHERE id = ?
 load.version_between  = SELECT id,creator,createdAt FROM versions WHERE createdAt >= ? AND createdAt <= ? ORDER BY createdAt ASC
@@ -49,7 +50,7 @@ store.version_removed = INSERT INTO versions_removed (version_id,triple_id) VALU
 
 delete.version_added   = DELETE FROM versions_added WHERE version_id = ?
 delete.version_removed = DELETE FROM versions_removed WHERE version_id = ?
-delete.version         = DELETE FROM verions WHERE id = ?
+delete.version         = DELETE FROM versions WHERE id = ?
 
 query.snapshot_size           = SELECT count(*) FROM triples WHERE createdAt <= ? AND (deleted = false OR deletedAt > ?)
 query.snapshot_size_ctx       = SELECT count(*) FROM triples WHERE context = ? AND createdAt <= ? AND (deleted = false OR deletedAt > ?)

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/SnapshotRepositoryTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/SnapshotRepositoryTest.java b/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/SnapshotRepositoryTest.java
index 7cc52e3..0268db5 100644
--- a/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/SnapshotRepositoryTest.java
+++ b/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/SnapshotRepositoryTest.java
@@ -17,24 +17,26 @@
  */
 package org.apache.marmotta.kiwi.versioning.test;
 
-import org.apache.marmotta.kiwi.persistence.KiWiDialect;
-import org.apache.marmotta.kiwi.persistence.h2.H2Dialect;
-import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect;
-import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assume.assumeThat;
+import info.aduna.iteration.Iterations;
+
+import java.io.InputStream;
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
 import org.apache.marmotta.kiwi.sail.KiWiStore;
-import org.apache.marmotta.kiwi.test.helper.DBConnectionChecker;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
 import org.apache.marmotta.kiwi.transactions.sail.KiWiTransactionalSail;
 import org.apache.marmotta.kiwi.versioning.repository.SnapshotRepository;
 import org.apache.marmotta.kiwi.versioning.sail.KiWiVersioningSail;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 import org.openrdf.model.Statement;
 import org.openrdf.query.BooleanQuery;
 import org.openrdf.query.QueryLanguage;
@@ -45,84 +47,17 @@ import org.openrdf.rio.RDFFormat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.InputStream;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assume.assumeThat;
-
 /**
- * This test verifies the snapshot functionality, i.e. if the snapshot connection works properly. It will try running
- * over all available databases. Except for in-memory databases like
- * H2 or Derby, database URLs must be passed as system property, or otherwise the test is skipped for this database.
- * Available system properties:
- * <ul>
- *     <li>PostgreSQL:
- *     <ul>
- *         <li>postgresql.url, e.g. jdbc:postgresql://localhost:5433/kiwitest?prepareThreshold=3</li>
- *         <li>postgresql.user (default: lmf)</li>
- *         <li>postgresql.pass (default: lmf)</li>
- *     </ul>
- *     </li>
- *     <li>MySQL:
- *     <ul>
- *         <li>mysql.url, e.g. jdbc:mysql://localhost:3306/kiwitest?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull</li>
- *         <li>mysql.user (default: lmf)</li>
- *         <li>mysql.pass (default: lmf</li>
- *     </ul>
- *     </li>
- *     <li>H2:
- *     <ul>
- *         <li>h2.url, e.g. jdbc:h2:mem;MVCC=true;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=10</li>
- *         <li>h2.user (default: lmf)</li>
- *         <li>h2.pass (default: lmf</li>
- *     </ul>
- *     </li>
- * </ul>
- * <p/>
+ * This test verifies the snapshot functionality, i.e. if the snapshot connection works properly. 
+ * 
  * @see org.apache.marmotta.kiwi.versioning.repository.SnapshotRepositoryConnection
  * @see org.apache.marmotta.kiwi.versioning.repository.SnapshotRepository
- * <p/>
- * Author: Sebastian Schaffert
+ * @author Sebastian Schaffert (sschaffert@apache.org)
  */
-@RunWith(Parameterized.class)
+@RunWith(KiWiDatabaseRunner.class)
 public class SnapshotRepositoryTest {
 
-    /**
-     * Return database configurations if the appropriate parameters have been set.
-     *
-     * @return an array (database name, url, user, password)
-     */
-    @Parameterized.Parameters(name="Database Test {index}: {0} at {1}")
-    public static Iterable<Object[]> databases() {
-        String[] databases = {"H2", "PostgreSQL", "MySQL"};
-
-        List<Object[]> result = new ArrayList<Object[]>(databases.length);
-        for(String database : databases) {
-            if(System.getProperty(database.toLowerCase()+".url") != null) {
-                result.add(new Object[] {
-                        database,
-                        System.getProperty(database.toLowerCase()+".url"),
-                        System.getProperty(database.toLowerCase()+".user","lmf"),
-                        System.getProperty(database.toLowerCase()+".pass","lmf")
-                });
-            }
-        }
-        return result;
-    }
-
-
-    private KiWiDialect dialect;
-
-    private String jdbcUrl;
-
-    private String jdbcUser;
-
-    private String jdbcPass;
-
+ 
     private KiWiStore store;
 
     private KiWiTransactionalSail tsail;
@@ -131,26 +66,16 @@ public class SnapshotRepositoryTest {
 
     private SnapshotRepository repository;
 
-    public SnapshotRepositoryTest(String database, String jdbcUrl, String jdbcUser, String jdbcPass) {
-        this.jdbcPass = jdbcPass;
-        this.jdbcUrl = jdbcUrl;
-        this.jdbcUser = jdbcUser;
-
-        if("H2".equals(database)) {
-            this.dialect = new H2Dialect();
-        } else if("MySQL".equals(database)) {
-            this.dialect = new MySQLDialect();
-        } else if("PostgreSQL".equals(database)) {
-            this.dialect = new PostgreSQLDialect();
-        }
-        
-        DBConnectionChecker.checkDatabaseAvailability(jdbcUrl, jdbcUser, jdbcPass, dialect);
+    private final KiWiConfiguration dbConfig;
+
+    public SnapshotRepositoryTest(KiWiConfiguration dbConfig) {
+        this.dbConfig = dbConfig;
     }
 
 
     @Before
     public void initDatabase() throws RepositoryException {
-        store = new KiWiStore("test",jdbcUrl,jdbcUser,jdbcPass,dialect, "http://localhost/context/default", "http://localhost/context/inferred");
+        store = new KiWiStore(dbConfig);
         tsail = new KiWiTransactionalSail(store);
         vsail = new KiWiVersioningSail(tsail);
         repository = new SnapshotRepository(vsail);
@@ -167,17 +92,6 @@ public class SnapshotRepositoryTest {
     final Logger logger =
             LoggerFactory.getLogger(this.getClass());
 
-    @Rule
-    public TestWatcher watchman = new TestWatcher() {
-        /**
-         * Invoked when a test is about to start
-         */
-        @Override
-        protected void starting(Description description) {
-            logger.info("{} being run...", description.getMethodName());
-        }
-    };
-
 
     @Test
     public void testSnapshotConnection() throws Exception {
@@ -378,17 +292,6 @@ public class SnapshotRepositoryTest {
      * @return
      */
     public static <E> List<E> asList(RepositoryResult<E> result) throws RepositoryException {
-        ArrayList<E> collection = new ArrayList<E>();
-        try {
-            while (result.hasNext()) {
-                collection.add(result.next());
-            }
-
-            return collection;
-        }
-        finally {
-            result.close();
-        }
+        return Iterations.asList(result);
     }
-
 }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/VersioningPersistenceTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/VersioningPersistenceTest.java b/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/VersioningPersistenceTest.java
index 9d723f3..49277a2 100644
--- a/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/VersioningPersistenceTest.java
+++ b/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/VersioningPersistenceTest.java
@@ -17,17 +17,21 @@
  */
 package org.apache.marmotta.kiwi.versioning.test;
 
-import org.apache.commons.lang.RandomStringUtils;
+import static org.hamcrest.Matchers.hasItems;
+import info.aduna.iteration.Iterations;
+
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
 import org.apache.marmotta.kiwi.model.rdf.KiWiStringLiteral;
 import org.apache.marmotta.kiwi.model.rdf.KiWiTriple;
 import org.apache.marmotta.kiwi.model.rdf.KiWiUriResource;
 import org.apache.marmotta.kiwi.persistence.KiWiConnection;
-import org.apache.marmotta.kiwi.persistence.KiWiDialect;
 import org.apache.marmotta.kiwi.persistence.KiWiPersistence;
-import org.apache.marmotta.kiwi.persistence.h2.H2Dialect;
-import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect;
-import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect;
-import org.apache.marmotta.kiwi.test.helper.DBConnectionChecker;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
 import org.apache.marmotta.kiwi.versioning.model.Version;
 import org.apache.marmotta.kiwi.versioning.persistence.KiWiVersioningConnection;
 import org.apache.marmotta.kiwi.versioning.persistence.KiWiVersioningPersistence;
@@ -43,104 +47,27 @@ import org.junit.runners.Parameterized;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import static org.hamcrest.Matchers.hasItems;
-
 /**
  * This test checks if the database persistence for the versioning functionality works properly.
- * It will try running over all available databases. Except for in-memory databases like
- * H2 or Derby, database URLs must be passed as system property, or otherwise the test is skipped for this database.
- * Available system properties:
- * <ul>
- *     <li>PostgreSQL:
- *     <ul>
- *         <li>postgresql.url, e.g. jdbc:postgresql://localhost:5433/kiwitest?prepareThreshold=3</li>
- *         <li>postgresql.user (default: lmf)</li>
- *         <li>postgresql.pass (default: lmf)</li>
- *     </ul>
- *     </li>
- *     <li>MySQL:
- *     <ul>
- *         <li>mysql.url, e.g. jdbc:mysql://localhost:3306/kiwitest?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull</li>
- *         <li>mysql.user (default: lmf)</li>
- *         <li>mysql.pass (default: lmf</li>
- *     </ul>
- *     </li>
- *     <li>H2:
- *     <ul>
- *         <li>h2.url, e.g. jdbc:h2:mem;MVCC=true;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=10</li>
- *         <li>h2.user (default: lmf)</li>
- *         <li>h2.pass (default: lmf</li>
- *     </ul>
- *     </li>
- * </ul>
- *
- * <p/>
- * Author: Sebastian Schaffert
+ * 
+ * @author Sebastian Schaffert (sschaffert@apache.org)
  */
-@RunWith(Parameterized.class)
+@RunWith(KiWiDatabaseRunner.class)
 public class VersioningPersistenceTest {
 
-
-    /**
-     * Return database configurations if the appropriate parameters have been set.
-     *
-     * @return an array (database name, url, user, password)
-     */
-    @Parameterized.Parameters(name="Database Test {index}: {0} at {1}")
-    public static Iterable<Object[]> databases() {
-        String[] databases = {"H2", "PostgreSQL", "MySQL"};
-
-        List<Object[]> result = new ArrayList<Object[]>(databases.length);
-        for(String database : databases) {
-            if(System.getProperty(database.toLowerCase()+".url") != null) {
-                result.add(new Object[] {
-                        database,
-                        System.getProperty(database.toLowerCase()+".url"),
-                        System.getProperty(database.toLowerCase()+".user","lmf"),
-                        System.getProperty(database.toLowerCase()+".pass","lmf")
-                });
-            }
-        }
-        return result;
-    }
-
-
-    private KiWiDialect dialect;
-
-    private String jdbcUrl;
-
-    private String jdbcUser;
-
-    private String jdbcPass;
-
     private KiWiPersistence persistence;
     private KiWiVersioningPersistence vpersistence;
+    private final KiWiConfiguration dbConfig;
 
-    public VersioningPersistenceTest(String database, String jdbcUrl, String jdbcUser, String jdbcPass) {
-        this.jdbcPass = jdbcPass;
-        this.jdbcUrl = jdbcUrl;
-        this.jdbcUser = jdbcUser;
-
-        if("H2".equals(database)) {
-            this.dialect = new H2Dialect();
-        } else if("MySQL".equals(database)) {
-            this.dialect = new MySQLDialect();
-        } else if("PostgreSQL".equals(database)) {
-            this.dialect = new PostgreSQLDialect();
-        }
-        
-        DBConnectionChecker.checkDatabaseAvailability(jdbcUrl, jdbcUser, jdbcPass, dialect);
+    public VersioningPersistenceTest(KiWiConfiguration dbConfig) {
+        this.dbConfig = dbConfig;
     }
 
 
     @Before
     public void initDatabase() throws SQLException {
-        persistence = new KiWiPersistence("test",jdbcUrl,jdbcUser,jdbcPass,dialect);
+        persistence = new KiWiPersistence(dbConfig);
+        persistence.initialise();
         persistence.initDatabase();
 
         vpersistence = new KiWiVersioningPersistence(persistence);
@@ -158,24 +85,13 @@ public class VersioningPersistenceTest {
     final Logger logger =
             LoggerFactory.getLogger(this.getClass());
 
-    @Rule
-    public TestWatcher watchman = new TestWatcher() {
-        /**
-         * Invoked when a test is about to start
-         */
-        @Override
-        protected void starting(Description description) {
-            logger.info("{} being run...", description.getMethodName());
-        }
-    };
-
     @Test
     public void testTablesCreateDrop() throws Exception {
         // test if database exists and has a version
         KiWiConnection connection = vpersistence.getConnection();
         try {
             Assert.assertThat(connection.getDatabaseTables(), hasItems("versions", "versions_added", "versions_removed"));
-            Assert.assertEquals(1, connection.getDatabaseVersion());
+            Assert.assertEquals(2, connection.getDatabaseVersion());
 
             connection.commit();
         } finally {
@@ -195,13 +111,13 @@ public class VersioningPersistenceTest {
             KiWiStringLiteral object_2 = new KiWiStringLiteral(RandomStringUtils.randomAlphanumeric(32));
             KiWiUriResource context  = new KiWiUriResource("http://localhost/context/"+RandomStringUtils.randomAlphanumeric(8));
 
-            connection.storeNode(subject1);
-            connection.storeNode(subject2);
-            connection.storeNode(pred_1);
-            connection.storeNode(pred_2);
-            connection.storeNode(object_1);
-            connection.storeNode(object_2);
-            connection.storeNode(context);
+            connection.storeNode(subject1, false);
+            connection.storeNode(subject2, false);
+            connection.storeNode(pred_1, false);
+            connection.storeNode(pred_2, false);
+            connection.storeNode(object_1, false);
+            connection.storeNode(object_2, false);
+            connection.storeNode(context, false);
 
             KiWiTriple triple1 = new KiWiTriple(subject1,pred_1,object_1,context);
             KiWiTriple triple2 = new KiWiTriple(subject2,pred_2,object_2,context);
@@ -217,13 +133,13 @@ public class VersioningPersistenceTest {
             connection.commit();
 
             // check if listVersions now gives exactly one version
-            List<Version> list1 = connection.listVersions().asList();
+            List<Version> list1 = Iterations.asList(connection.listVersions());
             Assert.assertEquals("there should be exactly one version",1,list1.size());
             Assert.assertEquals("contents of version differ", version1, list1.get(0));
             Assert.assertEquals("version id is not 1", 1L, (long)list1.get(0).getId());
 
             // check if listVersions with subject1 now gives exactly one version
-            List<Version> listr1 = connection.listVersions(subject1).asList();
+            List<Version> listr1 = Iterations.asList(connection.listVersions(subject1));
             Assert.assertEquals("there should be exactly one version", 1, listr1.size());
             Assert.assertEquals("contents of version differ", version1, listr1.get(0));
             Assert.assertEquals("version id is not 1", 1L, (long)listr1.get(0).getId());
@@ -237,13 +153,13 @@ public class VersioningPersistenceTest {
             connection.commit();
 
             // check if listVersions now gives exactly two versions
-            List<Version> list2 = connection.listVersions().asList();
+            List<Version> list2 = Iterations.asList(connection.listVersions());
             Assert.assertEquals("there should be exactly two version",2,list2.size());
             Assert.assertEquals("contents of version differ", version2, list2.get(1));
 
 
             // check if listVersions with subject1 still gives exactly one version
-            List<Version> listr2 = connection.listVersions(subject1).asList();
+            List<Version> listr2 = Iterations.asList(connection.listVersions(subject1));
             Assert.assertEquals("there should be exactly one version", 2, listr2.size());
             Assert.assertEquals("contents of version differ", version1, listr2.get(0));
             Assert.assertEquals("version id is not 1", 1L, (long)listr2.get(0).getId());
@@ -271,12 +187,12 @@ public class VersioningPersistenceTest {
             KiWiStringLiteral object_2 = new KiWiStringLiteral(RandomStringUtils.randomAlphanumeric(32));
             KiWiUriResource context  = new KiWiUriResource("http://localhost/context/"+RandomStringUtils.randomAlphanumeric(8));
 
-            connection.storeNode(subject);
-            connection.storeNode(pred_1);
-            connection.storeNode(pred_2);
-            connection.storeNode(object_1);
-            connection.storeNode(object_2);
-            connection.storeNode(context);
+            connection.storeNode(subject, false);
+            connection.storeNode(pred_1, false);
+            connection.storeNode(pred_2, false);
+            connection.storeNode(object_1, false);
+            connection.storeNode(object_2, false);
+            connection.storeNode(context, false);
 
             KiWiTriple triple1 = new KiWiTriple(subject,pred_1,object_1,context);
             KiWiTriple triple2 = new KiWiTriple(subject,pred_2,object_2,context);
@@ -320,7 +236,7 @@ public class VersioningPersistenceTest {
 
 
             // now we test different ways of listing versions between dates
-            List<Version> list1 = connection.listVersions(date1,date2).asList();
+            List<Version> list1 = Iterations.asList(connection.listVersions(date1,date2));
             Assert.assertEquals("there should be exactly one version from "+date1+" to "+date2,1,list1.size());
             Assert.assertEquals("contents of version differ", version1, list1.get(0));
             Assert.assertEquals("version id is not 1", 1L, (long)list1.get(0).getId());
@@ -331,21 +247,21 @@ public class VersioningPersistenceTest {
             Assert.assertEquals("latest version is not the expected version", version1,latest2);
 
             // check if listVersions with subject1 now gives exactly one version
-            List<Version> listr1 = connection.listVersions(subject,date1,date2).asList();
+            List<Version> listr1 = Iterations.asList(connection.listVersions(subject,date1,date2));
             Assert.assertEquals("there should be exactly one version", 1, listr1.size());
             Assert.assertEquals("contents of version differ", version1, listr1.get(0));
             Assert.assertEquals("version id is not 1", 1L, (long)listr1.get(0).getId());
 
 
-            List<Version> list2 = connection.listVersions(date2,date3).asList();
+            List<Version> list2 = Iterations.asList(connection.listVersions(date2,date3));
             Assert.assertEquals("there should be exactly one version from "+date2+" to "+date3,1,list2.size());
             Assert.assertEquals("contents of version differ", version2, list2.get(0));
             Assert.assertEquals("version id is not 2", 2L, (long)list2.get(0).getId());
 
-            List<Version> list3 = connection.listVersions(date3,new Date()).asList();
+            List<Version> list3 = Iterations.asList(connection.listVersions(date3,new Date()));
             Assert.assertEquals("there should be no version from "+date3+" to now",0,list3.size());
 
-            List<Version> list4 = connection.listVersions(date1,date3).asList();
+            List<Version> list4 = Iterations.asList(connection.listVersions(date1,date3));
             Assert.assertEquals("there should be exactly two versions from "+date1+" to "+date3,2,list4.size());
             Assert.assertEquals("contents of version1 differ", version1, list4.get(0));
             Assert.assertEquals("contents of version2 differ", version2, list4.get(1));
@@ -359,6 +275,78 @@ public class VersioningPersistenceTest {
 
     }
 
+
+    @Test
+    public void testCreateRemoveVersions() throws Exception {
+        KiWiVersioningConnection connection = vpersistence.getConnection();
+        try {
+            KiWiUriResource subject1  = new KiWiUriResource("http://localhost/resource/"+ RandomStringUtils.randomAlphanumeric(8));
+            KiWiUriResource subject2  = new KiWiUriResource("http://localhost/resource/"+ RandomStringUtils.randomAlphanumeric(8));
+            KiWiUriResource pred_1   = new KiWiUriResource("http://localhost/predicate/P1");
+            KiWiUriResource pred_2   = new KiWiUriResource("http://localhost/predicate/P2");
+            KiWiUriResource object_1 = new KiWiUriResource("http://localhost/resource/"+RandomStringUtils.randomAlphanumeric(8));
+            KiWiStringLiteral object_2 = new KiWiStringLiteral(RandomStringUtils.randomAlphanumeric(32));
+            KiWiUriResource context  = new KiWiUriResource("http://localhost/context/"+RandomStringUtils.randomAlphanumeric(8));
+
+            connection.storeNode(subject1, false);
+            connection.storeNode(subject2, false);
+            connection.storeNode(pred_1, false);
+            connection.storeNode(pred_2, false);
+            connection.storeNode(object_1, false);
+            connection.storeNode(object_2, false);
+            connection.storeNode(context, false);
+
+            KiWiTriple triple1 = new KiWiTriple(subject1,pred_1,object_1,context);
+            KiWiTriple triple2 = new KiWiTriple(subject2,pred_2,object_2,context);
+
+            connection.storeTriple(triple1);
+            connection.storeTriple(triple2);
+            connection.commit();
+
+            Version version1 = new Version();
+            version1.setCommitTime(new Date());
+            version1.addTriple(triple1);
+            connection.storeVersion(version1);
+            connection.commit();
+
+            // check if listVersions now gives exactly one version
+            List<Version> list1 = Iterations.asList(connection.listVersions());
+            Assert.assertEquals("there should be exactly one version",1,list1.size());
+            Assert.assertEquals("contents of version differ", version1, list1.get(0));
+            Assert.assertEquals("version id is not 1", 1L, (long)list1.get(0).getId());
+
+            Version version2 = new Version();
+            version2.setCommitTime(new Date());
+            version2.addTriple(triple2);
+            version2.removeTriple(triple1);
+            connection.storeVersion(version2);
+            connection.commit();
+
+            // check if listVersions now gives exactly two versions
+            List<Version> list2 = Iterations.asList(connection.listVersions());
+            Assert.assertEquals("there should be exactly two version",2,list2.size());
+            Assert.assertEquals("contents of version differ", version2, list2.get(1));
+
+            connection.commit();
+
+            connection.removeVersion(version1.getId());
+            connection.commit();
+
+            // check if listVersions now gives exactly two versions
+            List<Version> list3 = Iterations.asList(connection.listVersions());
+            Assert.assertEquals("there should be exactly one version",1,list3.size());
+            Assert.assertEquals("contents of version differ", version2, list3.get(0));
+
+            connection.commit();
+
+        } finally {
+            connection.close();
+        }
+
+    }
+
+
+
     /**
      * MYSQL rounds timestamps to the second, so it is sometimes necessary to sleep before doing a test
      */

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/VersioningRepositoryTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/VersioningRepositoryTest.java b/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/VersioningRepositoryTest.java
index f0b720a..76f8375 100644
--- a/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/VersioningRepositoryTest.java
+++ b/libraries/kiwi/kiwi-versioning/src/test/java/org/apache/marmotta/kiwi/versioning/test/VersioningRepositoryTest.java
@@ -17,12 +17,19 @@
  */
 package org.apache.marmotta.kiwi.versioning.test;
 
-import org.apache.marmotta.kiwi.persistence.KiWiDialect;
-import org.apache.marmotta.kiwi.persistence.h2.H2Dialect;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assume.assumeThat;
+import info.aduna.iteration.Iterations;
+
+import java.io.InputStream;
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
 import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect;
-import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect;
 import org.apache.marmotta.kiwi.sail.KiWiStore;
-import org.apache.marmotta.kiwi.test.helper.DBConnectionChecker;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
 import org.apache.marmotta.kiwi.transactions.sail.KiWiTransactionalSail;
 import org.apache.marmotta.kiwi.versioning.model.Version;
 import org.apache.marmotta.kiwi.versioning.sail.KiWiVersioningSail;
@@ -34,7 +41,7 @@ import org.junit.Test;
 import org.junit.rules.TestWatcher;
 import org.junit.runner.Description;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import org.openrdf.model.URI;
 import org.openrdf.repository.Repository;
 import org.openrdf.repository.RepositoryConnection;
 import org.openrdf.repository.RepositoryException;
@@ -44,82 +51,15 @@ import org.openrdf.rio.RDFFormat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.InputStream;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assume.assumeThat;
-
 /**
  * This test checks if the versioning functionality itself works, i.e. the system properly creates versions on
- * transaction commits. It will try running over all available databases. Except for in-memory databases like
- * H2 or Derby, database URLs must be passed as system property, or otherwise the test is skipped for this database.
- * Available system properties:
- * <ul>
- *     <li>PostgreSQL:
- *     <ul>
- *         <li>postgresql.url, e.g. jdbc:postgresql://localhost:5433/kiwitest?prepareThreshold=3</li>
- *         <li>postgresql.user (default: lmf)</li>
- *         <li>postgresql.pass (default: lmf)</li>
- *     </ul>
- *     </li>
- *     <li>MySQL:
- *     <ul>
- *         <li>mysql.url, e.g. jdbc:mysql://localhost:3306/kiwitest?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull</li>
- *         <li>mysql.user (default: lmf)</li>
- *         <li>mysql.pass (default: lmf</li>
- *     </ul>
- *     </li>
- *     <li>H2:
- *     <ul>
- *         <li>h2.url, e.g. jdbc:h2:mem;MVCC=true;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=10</li>
- *         <li>h2.user (default: lmf)</li>
- *         <li>h2.pass (default: lmf</li>
- *     </ul>
- *     </li>
- * </ul>
- *
- * <p/>
- * Author: Sebastian Schaffert
+ * transaction commits. 
+ * 
+ * @author Sebastian Schaffert (sschaffert@apache.org)
  */
-@RunWith(Parameterized.class)
+@RunWith(KiWiDatabaseRunner.class)
 public class VersioningRepositoryTest {
 
-    /**
-     * Return database configurations if the appropriate parameters have been set.
-     *
-     * @return an array (database name, url, user, password)
-     */
-    @Parameterized.Parameters(name="Database Test {index}: {0} at {1}")
-    public static Iterable<Object[]> databases() {
-        String[] databases = {"H2", "PostgreSQL", "MySQL"};
-
-        List<Object[]> result = new ArrayList<Object[]>(databases.length);
-        for(String database : databases) {
-            if(System.getProperty(database.toLowerCase()+".url") != null) {
-                result.add(new Object[] {
-                        database,
-                        System.getProperty(database.toLowerCase()+".url"),
-                        System.getProperty(database.toLowerCase()+".user","lmf"),
-                        System.getProperty(database.toLowerCase()+".pass","lmf")
-                });
-            }
-        }
-        return result;
-    }
-
-
-    private KiWiDialect dialect;
-
-    private String jdbcUrl;
-
-    private String jdbcUser;
-
-    private String jdbcPass;
-
     private KiWiStore store;
 
     private KiWiTransactionalSail tsail;
@@ -128,26 +68,16 @@ public class VersioningRepositoryTest {
 
     private Repository repository;
 
-    public VersioningRepositoryTest(String database, String jdbcUrl, String jdbcUser, String jdbcPass) {
-        this.jdbcPass = jdbcPass;
-        this.jdbcUrl = jdbcUrl;
-        this.jdbcUser = jdbcUser;
-
-        if("H2".equals(database)) {
-            this.dialect = new H2Dialect();
-        } else if("MySQL".equals(database)) {
-            this.dialect = new MySQLDialect();
-        } else if("PostgreSQL".equals(database)) {
-            this.dialect = new PostgreSQLDialect();
-        }
-        
-        DBConnectionChecker.checkDatabaseAvailability(jdbcUrl, jdbcUser, jdbcPass, dialect);
+    private final KiWiConfiguration dbConfig;
+
+    public VersioningRepositoryTest(KiWiConfiguration dbConfig) {
+        this.dbConfig = dbConfig;
     }
 
 
     @Before
     public void initDatabase() throws RepositoryException {
-        store = new KiWiStore("test",jdbcUrl,jdbcUser,jdbcPass,dialect, "http://localhost/context/default", "http://localhost/context/inferred");
+        store = new KiWiStore(dbConfig);
         tsail = new KiWiTransactionalSail(store);
         vsail = new KiWiVersioningSail(tsail);
         repository = new SailRepository(vsail);
@@ -164,18 +94,6 @@ public class VersioningRepositoryTest {
     final Logger logger =
             LoggerFactory.getLogger(this.getClass());
 
-    @Rule
-    public TestWatcher watchman = new TestWatcher() {
-        /**
-         * Invoked when a test is about to start
-         */
-        @Override
-        protected void starting(Description description) {
-            logger.info("{} being run...", description.getMethodName());
-        }
-    };
-
-
     /**
      * This test imports three small RDF files in sequence and checks afterwards that the number of versions
      * is correct and they contain the correct information
@@ -249,10 +167,99 @@ public class VersioningRepositoryTest {
 
 
     /**
+     * This test imports three small RDF files in sequence and checks afterwards that the number of versions
+     * is correct and they contain the correct information
+     * @throws Exception
+     */
+    @Test
+    public void testRevertVersions() throws Exception {
+        // import three files in sequence and check if the versions are created properly
+
+        Date date1 = new Date();
+
+        mysqlSleep();
+
+        // base data
+        InputStream baseData = this.getClass().getResourceAsStream("version-base.rdf");
+        assumeThat("Could not load test-data: version-base.rdf", baseData, notNullValue(InputStream.class));
+
+        RepositoryConnection connectionBase = repository.getConnection();
+        try {
+            connectionBase.add(baseData, "http://marmotta.incubator.apache.org/testing/ns1/", RDFFormat.RDFXML);
+            connectionBase.commit();
+        } finally {
+            connectionBase.close();
+        }
+
+        mysqlSleep();
+
+        Date date2 = new Date();
+
+        mysqlSleep();
+
+        // update 1
+        InputStream update1Data = this.getClass().getResourceAsStream("version-update1.rdf");
+        assumeThat("Could not load test-data: version-update1.rdf", update1Data, notNullValue(InputStream.class));
+
+        RepositoryConnection connectionUpdate1 = repository.getConnection();
+        try {
+            connectionUpdate1.add(update1Data, "http://marmotta.incubator.apache.org/testing/ns1/", RDFFormat.RDFXML);
+            connectionUpdate1.commit();
+        } finally {
+            connectionUpdate1.close();
+        }
+
+        // update 2
+        InputStream update2Data = this.getClass().getResourceAsStream("version-update2.rdf");
+        assumeThat("Could not load test-data: version-update2.rdf", update2Data, notNullValue(InputStream.class));
+
+        RepositoryConnection connectionUpdate2 = repository.getConnection();
+        try {
+            connectionUpdate2.add(update2Data, "http://marmotta.incubator.apache.org/testing/ns1/", RDFFormat.RDFXML);
+            connectionUpdate2.commit();
+        } finally {
+            connectionUpdate2.close();
+        }
+
+        // list all versions
+        List<Version> versions = asList(vsail.listVersions());
+        Assert.assertEquals("expected 3 versions!", 3, versions.size());
+        Assert.assertEquals(1, (long)versions.get(0).getId());
+
+        URI subject = repository.getValueFactory().createURI("http://marmotta.incubator.apache.org/testing/ns1/R1");
+        URI predicate = repository.getValueFactory().createURI("http://marmotta.incubator.apache.org/testing/ns1/P2");
+
+        RepositoryConnection connectionBeforeRevert = repository.getConnection();
+        try {
+            Assert.assertTrue(connectionBeforeRevert.hasStatement(subject,predicate,null,true));
+        } finally {
+            connectionBeforeRevert.close();
+        }
+
+        // revert version; afterwards we expect there to be 4 versions
+        vsail.revertVersion(versions.get(0));
+
+        List<Version> versions2 = asList(vsail.listVersions());
+        Assert.assertEquals("expected 4 versions!", 4, versions2.size());
+
+        // the repository should now lo longer contain any P2 property for ns1:C
+        RepositoryConnection connectionAfterRevert = repository.getConnection();
+        try {
+            Assert.assertFalse(connectionAfterRevert.hasStatement(subject, predicate, null, true));
+        } finally {
+            connectionAfterRevert.close();
+        }
+
+
+
+    }
+
+
+    /**
      * MYSQL rounds timestamps to the second, so it is sometimes necessary to sleep before doing a test
      */
     private  void mysqlSleep() {
-        if(this.dialect instanceof MySQLDialect) {
+        if(this.dbConfig.getDialect() instanceof MySQLDialect) {
             try {
                 Thread.sleep(1000);
             } catch (InterruptedException e) {
@@ -267,16 +274,6 @@ public class VersioningRepositoryTest {
      * @return
      */
     public static <E> List<E> asList(RepositoryResult<E> result) throws RepositoryException {
-        ArrayList<E> collection = new ArrayList<E>();
-        try {
-            while (result.hasNext()) {
-                collection.add(result.next());
-            }
-
-            return collection;
-        }
-        finally {
-            result.close();
-        }
+        return Iterations.asList(result);
     }
 }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/kiwi/pom.xml b/libraries/kiwi/pom.xml
index 39132c6..665f70d 100644
--- a/libraries/kiwi/pom.xml
+++ b/libraries/kiwi/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.marmotta</groupId>
         <artifactId>marmotta-parent</artifactId>
-        <version>3.1.0-incubating-SNAPSHOT</version>
+        <version>3.1.0-incubating</version>
         <relativePath>../../parent</relativePath>
     </parent>
 
@@ -64,10 +64,6 @@
                     <version>2.13</version>
                     <configuration>
                         <systemPropertyVariables>
-                            <h2.url>jdbc:h2:mem:test;MVCC=true;DB_CLOSE_ON_EXIT=TRUE</h2.url>
-                            <h2.user>sa</h2.user>
-                            <h2.pass />
-
                             <!-- enable or pass on command line for testing local PostgreSQL -->
                             <postgresql.url>jdbc:postgresql://localhost:5433/kiwitest?prepareThreshold=3</postgresql.url>
                             <postgresql.user>lmf</postgresql.user>
@@ -88,10 +84,21 @@
                 <plugin> <!-- generate JRebel Configuration -->
                     <groupId>org.zeroturnaround</groupId>
                     <artifactId>jrebel-maven-plugin</artifactId>
+                    <executions>
+                        <execution>
+                            <id>generate-rebel-xml</id>
+                            <phase>process-resources</phase>
+                            <goals>
+                                <goal>generate</goal>
+                            </goals>
+                        </execution>
+                    </executions>
                     <configuration>
-                        <relativePath>../../</relativePath>
+                        <relativePath>../../../</relativePath>
+                        <rootPath>$${rebel.root}</rootPath>
                     </configuration>
                 </plugin>
+
             </plugins>
         </pluginManagement>
         <plugins>
@@ -100,19 +107,6 @@
                 <artifactId>maven-surefire-plugin</artifactId>
             </plugin>
 
-            <!-- do not install / deploy reactor -->
-            <plugin>
-                <artifactId>maven-deploy-plugin</artifactId>
-                <configuration>
-                    <skip>true</skip>
-                </configuration>
-            </plugin>
-            <plugin>
-                <artifactId>maven-install-plugin</artifactId>
-                <configuration>
-                    <skip>true</skip>
-                </configuration>
-            </plugin>
         </plugins>
     </build>
 
@@ -135,6 +129,7 @@
         <module>kiwi-tripletable</module>
         <module>kiwi-versioning</module>
         <module>kiwi-reasoner</module>
+        <module>kiwi-sparql</module>
     </modules>
 
 </project>

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/ldcache/ldcache-api/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-api/pom.xml b/libraries/ldcache/ldcache-api/pom.xml
index 8462669..13dbd08 100644
--- a/libraries/ldcache/ldcache-api/pom.xml
+++ b/libraries/ldcache/ldcache-api/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.marmotta</groupId>
         <artifactId>marmotta-parent</artifactId>
-        <version>3.1.0-incubating-SNAPSHOT</version>
+        <version>3.1.0-incubating</version>
         <relativePath>../../../parent</relativePath>
     </parent>
 
@@ -32,6 +32,30 @@
         Interfaces and Data Model for the Linked Data Caching component.
     </description>
 
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin> <!-- generate JRebel Configuration -->
+                    <groupId>org.zeroturnaround</groupId>
+                    <artifactId>jrebel-maven-plugin</artifactId>
+                    <executions>
+                        <execution>
+                            <id>generate-rebel-xml</id>
+                            <phase>process-resources</phase>
+                            <goals>
+                                <goal>generate</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                    <configuration>
+                        <relativePath>../../../</relativePath>
+                        <rootPath>$${rebel.root}</rootPath>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
     <dependencies>
 
         <dependency>

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/api/LDCachingBackend.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/api/LDCachingBackend.java b/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/api/LDCachingBackend.java
index 3e9bc50..a121e20 100644
--- a/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/api/LDCachingBackend.java
+++ b/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/api/LDCachingBackend.java
@@ -60,6 +60,14 @@ public interface LDCachingBackend {
 
 
     /**
+     * Return true in case the resource is a cached resource.
+     *
+     * @param resource the URI of the resource to check
+     * @return true in case the resource is a cached resource
+     */
+    public boolean isCached(String resource)  throws RepositoryException;
+
+    /**
      * Carry out any initialization tasks that might be necessary
      */
     public void initialize();

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/model/CacheEntry.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/model/CacheEntry.java b/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/model/CacheEntry.java
index 61bef7a..4c7db25 100644
--- a/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/model/CacheEntry.java
+++ b/libraries/ldcache/ldcache-api/src/main/java/org/apache/marmotta/ldcache/model/CacheEntry.java
@@ -52,41 +52,83 @@ public class CacheEntry {
     private Integer updateCount;
 
 
+    /**
+     * The number of triples that have been retrieved in the last cache refresh.
+     */
+    private Integer tripleCount;
+
 
     public CacheEntry() {
     }
 
 
+    /**
+     * The URI resource managed by this cache entry.
+     */
     public URI getResource() {
         return resource;
     }
 
+    /**
+     * The URI resource managed by this cache entry.
+     */
     public void setResource(URI resource) {
         this.resource = resource;
     }
 
+    /**
+     * The date when this resource has been retrieved the last time.
+     */
     public Date getLastRetrieved() {
         return lastRetrieved;
     }
 
+    /**
+     * The date when this resource has been retrieved the last time.
+     */
     public void setLastRetrieved(Date lastRetrieved) {
         this.lastRetrieved = new Date(lastRetrieved.getTime());
     }
 
+    /**
+     * The date when this resource needs to be retrieved again according to expiry configuration.
+     */
     public Date getExpiryDate() {
         return expiryDate;
     }
 
+    /**
+     * The date when this resource needs to be retrieved again according to expiry configuration.
+     */
     public void setExpiryDate(Date expiryDate) {
         this.expiryDate = new Date(expiryDate.getTime());
     }
 
+    /**
+     * The number of times this resource has already been updated.
+     */
     public Integer getUpdateCount() {
         return updateCount;
     }
 
+    /**
+     * The number of times this resource has already been updated.
+     */
     public void setUpdateCount(Integer updateCount) {
         this.updateCount = updateCount;
     }
 
+    /**
+     * The number of triples that have been retrieved in the last cache refresh.
+     */
+    public Integer getTripleCount() {
+        return tripleCount;
+    }
+
+    /**
+     * The number of triples that have been retrieved in the last cache refresh.
+     */
+    public void setTripleCount(Integer tripleCount) {
+        this.tripleCount = tripleCount;
+    }
 }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/ldcache/ldcache-backend-ehcache/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-ehcache/pom.xml b/libraries/ldcache/ldcache-backend-ehcache/pom.xml
index 86a9d92..0df8bea 100644
--- a/libraries/ldcache/ldcache-backend-ehcache/pom.xml
+++ b/libraries/ldcache/ldcache-backend-ehcache/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.marmotta</groupId>
         <artifactId>marmotta-parent</artifactId>
-        <version>3.1.0-incubating-SNAPSHOT</version>
+        <version>3.1.0-incubating</version>
         <relativePath>../../../parent</relativePath>
     </parent>
 
@@ -34,6 +34,30 @@
     </description>
 
 
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin> <!-- generate JRebel Configuration -->
+                    <groupId>org.zeroturnaround</groupId>
+                    <artifactId>jrebel-maven-plugin</artifactId>
+                    <executions>
+                        <execution>
+                            <id>generate-rebel-xml</id>
+                            <phase>process-resources</phase>
+                            <goals>
+                                <goal>generate</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                    <configuration>
+                        <relativePath>../../../</relativePath>
+                        <rootPath>$${rebel.root}</rootPath>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
     <dependencies>
 
 

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/ldcache/ldcache-backend-file/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-file/pom.xml b/libraries/ldcache/ldcache-backend-file/pom.xml
index c7d567b..881b2bf 100644
--- a/libraries/ldcache/ldcache-backend-file/pom.xml
+++ b/libraries/ldcache/ldcache-backend-file/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.marmotta</groupId>
         <artifactId>marmotta-parent</artifactId>
-        <version>3.1.0-incubating-SNAPSHOT</version>
+        <version>3.1.0-incubating</version>
         <relativePath>../../../parent</relativePath>
     </parent>
 
@@ -34,8 +34,27 @@
 
 
     <build>
-        <plugins>
-        </plugins>
+        <pluginManagement>
+            <plugins>
+                <plugin> <!-- generate JRebel Configuration -->
+                    <groupId>org.zeroturnaround</groupId>
+                    <artifactId>jrebel-maven-plugin</artifactId>
+                    <executions>
+                        <execution>
+                            <id>generate-rebel-xml</id>
+                            <phase>process-resources</phase>
+                            <goals>
+                                <goal>generate</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                    <configuration>
+                        <relativePath>../../../</relativePath>
+                        <rootPath>$${rebel.root}</rootPath>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
     </build>
 
 

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/ldcache/ldcache-backend-file/src/main/java/org/apache/marmotta/ldcache/backend/file/LDCachingFileBackend.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-file/src/main/java/org/apache/marmotta/ldcache/backend/file/LDCachingFileBackend.java b/libraries/ldcache/ldcache-backend-file/src/main/java/org/apache/marmotta/ldcache/backend/file/LDCachingFileBackend.java
index 937ace5..bff143a 100644
--- a/libraries/ldcache/ldcache-backend-file/src/main/java/org/apache/marmotta/ldcache/backend/file/LDCachingFileBackend.java
+++ b/libraries/ldcache/ldcache-backend-file/src/main/java/org/apache/marmotta/ldcache/backend/file/LDCachingFileBackend.java
@@ -35,9 +35,11 @@ import org.apache.marmotta.ldcache.backend.file.repository.LDCachingFileReposito
 import org.apache.marmotta.ldcache.backend.file.util.FileBackendUtils;
 import org.apache.marmotta.ldcache.model.CacheEntry;
 import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.ValueFactoryImpl;
 import org.openrdf.repository.Repository;
 import org.openrdf.repository.RepositoryException;
 import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.sail.SailException;
 import org.openrdf.sail.nativerdf.NativeStore;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -109,6 +111,26 @@ public class LDCachingFileBackend implements LDCachingBackend {
         };
     }
 
+    /**
+     * Return true in case the resource is a cached resource.
+     *
+     * @param resource the URI of the resource to check
+     * @return true in case the resource is a cached resource
+     */
+    @Override
+    public boolean isCached(String resource) throws RepositoryException {
+        try {
+            final File dataFile = FileBackendUtils.getMetaFile(resource, storageDir);
+            if (!(dataFile.exists())) return false;
+            final CacheEntry ce = FileBackendUtils.readCacheEntry(dataFile, new ValueFactoryImpl());
+            //return ce != null && !FileBackendUtils.isExpired(ce) && ce.getTripleCount() > 0;
+            return ce != null && ce.getTripleCount() > 0;
+        } catch (IOException e) {
+            throw new RepositoryException(e);
+        }
+    }
+
+
     /* (non-Javadoc)
      * @see org.apache.marmotta.ldcache.api.LDCachingBackend#initialize()
      */

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/ldcache/ldcache-backend-file/src/main/java/org/apache/marmotta/ldcache/backend/file/util/FileBackendUtils.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-file/src/main/java/org/apache/marmotta/ldcache/backend/file/util/FileBackendUtils.java b/libraries/ldcache/ldcache-backend-file/src/main/java/org/apache/marmotta/ldcache/backend/file/util/FileBackendUtils.java
index ea90433..a24902c 100644
--- a/libraries/ldcache/ldcache-backend-file/src/main/java/org/apache/marmotta/ldcache/backend/file/util/FileBackendUtils.java
+++ b/libraries/ldcache/ldcache-backend-file/src/main/java/org/apache/marmotta/ldcache/backend/file/util/FileBackendUtils.java
@@ -101,7 +101,8 @@ public class FileBackendUtils {
 				ce.setLastRetrieved(new Date(Long.parseLong(br.readLine().replaceFirst("#.*$", "").trim())));
 				ce.setExpiryDate(new Date(Long.parseLong(br.readLine().replaceFirst("#.*$", "").trim())));
 				ce.setUpdateCount(Integer.parseInt(br.readLine().replaceFirst("#.*$", "").trim()));
-				
+                ce.setTripleCount(Integer.parseInt(br.readLine().replaceFirst("#.*$", "").trim()));
+
 				return ce;
 			} finally {
 				br.close();
@@ -120,6 +121,8 @@ public class FileBackendUtils {
 				ps.printf("%tQ # last retrieved: %<tF %<tT.%<tL%n", ce.getLastRetrieved());
 				ps.printf("%tQ # expires: %<tF %<tT.%<tL%n", ce.getExpiryDate());
 				ps.printf("%d # %<d updates%n", ce.getUpdateCount());
+                ps.printf("%d # %<d triples%n", ce.getTripleCount());
+                ps.flush();
 			} finally {
 				ps.close();
 			}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/ldcache/ldcache-backend-file/src/test/java/org/apache/marmotta/ldcache/backend/file/test/LDCacheBackendTest.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-file/src/test/java/org/apache/marmotta/ldcache/backend/file/test/LDCacheBackendTest.java b/libraries/ldcache/ldcache-backend-file/src/test/java/org/apache/marmotta/ldcache/backend/file/test/LDCacheBackendTest.java
index 2061c9f..0a24002 100644
--- a/libraries/ldcache/ldcache-backend-file/src/test/java/org/apache/marmotta/ldcache/backend/file/test/LDCacheBackendTest.java
+++ b/libraries/ldcache/ldcache-backend-file/src/test/java/org/apache/marmotta/ldcache/backend/file/test/LDCacheBackendTest.java
@@ -19,7 +19,7 @@ package org.apache.marmotta.ldcache.backend.file.test;
 import com.google.common.io.Files;
 import info.aduna.iteration.CloseableIteration;
 import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.RandomStringUtils;
+import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.marmotta.ldcache.api.LDCachingConnection;
 import org.apache.marmotta.ldcache.backend.file.LDCachingFileBackend;
 import org.apache.marmotta.ldcache.model.CacheEntry;
@@ -160,9 +160,12 @@ public class LDCacheBackendTest {
             entry1.setLastRetrieved(new Date());
             entry1.setUpdateCount(1);
             entry1.setResource(subject1);
+            entry1.setTripleCount(1);
             con.addCacheEntry(subject1, entry1);
             con.commit();
 
+            Assert.assertTrue(backend.isCached(subject1.stringValue()));
+            Assert.assertFalse(backend.isCached(subject2.stringValue()));
             Assert.assertEquals(1,asList(backend.listCacheEntries()).size());
             Assert.assertEquals(0,asList(backend.listExpiredEntries()).size());
 
@@ -172,10 +175,13 @@ public class LDCacheBackendTest {
             entry2.setLastRetrieved(new Date());
             entry2.setUpdateCount(1);
             entry2.setResource(subject2);
+            entry2.setTripleCount(1);
             con.addCacheEntry(subject2,entry2);
 
             con.commit();
 
+            Assert.assertTrue(backend.isCached(subject1.stringValue()));
+            Assert.assertTrue(backend.isCached(subject2.stringValue()));
             Assert.assertEquals(2,asList(backend.listCacheEntries()).size());
             Assert.assertEquals(1,asList(backend.listExpiredEntries()).size());
 
@@ -183,6 +189,8 @@ public class LDCacheBackendTest {
             con.removeCacheEntry(subject1);
             con.commit();
 
+            Assert.assertFalse(backend.isCached(subject1.stringValue()));
+            Assert.assertTrue(backend.isCached(subject2.stringValue()));
             Assert.assertEquals(1,asList(backend.listCacheEntries()).size());
             Assert.assertEquals(1,asList(backend.listExpiredEntries()).size());
         } catch(RepositoryException ex) {

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/ldcache/ldcache-backend-kiwi/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-kiwi/pom.xml b/libraries/ldcache/ldcache-backend-kiwi/pom.xml
index 356eacd..1fab347 100644
--- a/libraries/ldcache/ldcache-backend-kiwi/pom.xml
+++ b/libraries/ldcache/ldcache-backend-kiwi/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.marmotta</groupId>
         <artifactId>marmotta-parent</artifactId>
-        <version>3.1.0-incubating-SNAPSHOT</version>
+        <version>3.1.0-incubating</version>
         <relativePath>../../../parent</relativePath>
     </parent>
 
@@ -34,6 +34,27 @@
     </description>
 
     <build>
+        <pluginManagement>
+            <plugins>
+                <plugin> <!-- generate JRebel Configuration -->
+                    <groupId>org.zeroturnaround</groupId>
+                    <artifactId>jrebel-maven-plugin</artifactId>
+                    <executions>
+                        <execution>
+                            <id>generate-rebel-xml</id>
+                            <phase>process-resources</phase>
+                            <goals>
+                                <goal>generate</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                    <configuration>
+                        <relativePath>../../../</relativePath>
+                        <rootPath>$${rebel.root}</rootPath>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
@@ -140,7 +161,7 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.jumpmind.symmetric.jdbc</groupId>
+            <groupId>org.postgresql</groupId>
             <artifactId>postgresql</artifactId>
             <scope>test</scope>
         </dependency>

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/ldcache/ldcache-backend-kiwi/src/main/java/org/apache/marmotta/ldcache/backend/kiwi/LDCachingKiWiBackend.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-kiwi/src/main/java/org/apache/marmotta/ldcache/backend/kiwi/LDCachingKiWiBackend.java b/libraries/ldcache/ldcache-backend-kiwi/src/main/java/org/apache/marmotta/ldcache/backend/kiwi/LDCachingKiWiBackend.java
index 3e90e1e..0d7870b 100644
--- a/libraries/ldcache/ldcache-backend-kiwi/src/main/java/org/apache/marmotta/ldcache/backend/kiwi/LDCachingKiWiBackend.java
+++ b/libraries/ldcache/ldcache-backend-kiwi/src/main/java/org/apache/marmotta/ldcache/backend/kiwi/LDCachingKiWiBackend.java
@@ -23,6 +23,7 @@ import org.apache.marmotta.kiwi.sail.KiWiStore;
 import org.apache.marmotta.ldcache.api.LDCachingBackend;
 import org.apache.marmotta.ldcache.api.LDCachingConnection;
 import org.apache.marmotta.ldcache.backend.kiwi.persistence.LDCachingKiWiPersistence;
+import org.apache.marmotta.ldcache.backend.kiwi.persistence.LDCachingKiWiPersistenceConnection;
 import org.apache.marmotta.ldcache.backend.kiwi.repository.LDCachingSailRepositoryConnection;
 import org.apache.marmotta.ldcache.backend.kiwi.sail.LDCachingKiWiSail;
 import org.apache.marmotta.ldcache.backend.kiwi.sail.LDCachingKiWiSailConnection;
@@ -177,6 +178,28 @@ public class LDCachingKiWiBackend implements LDCachingBackend {
     }
 
 
+    /**
+     * Return true in case the resource is a cached resource.
+     *
+     * @param resource the URI of the resource to check
+     * @return true in case the resource is a cached resource
+     */
+    @Override
+    public boolean isCached(String resource) throws RepositoryException {
+        try {
+            LDCachingKiWiPersistenceConnection con = persistence.getConnection();
+            try {
+                CacheEntry entry = con.getCacheEntry(resource);
+                return  entry != null && entry.getTripleCount() > 0;
+            } finally {
+                con.commit();
+                con.close();
+            }
+        } catch (SQLException e) {
+            throw new RepositoryException(e);
+        }
+    }
+
     public LDCachingKiWiPersistence getPersistence() {
         return persistence;
     }

http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/ldcache/ldcache-backend-kiwi/src/main/java/org/apache/marmotta/ldcache/backend/kiwi/persistence/LDCachingKiWiPersistenceConnection.java
----------------------------------------------------------------------
diff --git a/libraries/ldcache/ldcache-backend-kiwi/src/main/java/org/apache/marmotta/ldcache/backend/kiwi/persistence/LDCachingKiWiPersistenceConnection.java b/libraries/ldcache/ldcache-backend-kiwi/src/main/java/org/apache/marmotta/ldcache/backend/kiwi/persistence/LDCachingKiWiPersistenceConnection.java
index aba5c2f..63e4063 100644
--- a/libraries/ldcache/ldcache-backend-kiwi/src/main/java/org/apache/marmotta/ldcache/backend/kiwi/persistence/LDCachingKiWiPersistenceConnection.java
+++ b/libraries/ldcache/ldcache-backend-kiwi/src/main/java/org/apache/marmotta/ldcache/backend/kiwi/persistence/LDCachingKiWiPersistenceConnection.java
@@ -85,6 +85,7 @@ public class LDCachingKiWiPersistenceConnection  {
         entry.setExpiryDate(new Date(row.getTimestamp("expires_at").getTime()));
         entry.setUpdateCount(row.getInt("update_count"));
         entry.setResource((URI) connection.loadNodeById(row.getLong("resource_id")));
+        entry.setTripleCount(row.getInt("triple_count"));
 
         entryIdCache.put(new Element(id,entry));
         entryResourceCache.put(new Element(entry.getResource().stringValue(),entry));
@@ -145,12 +146,16 @@ public class LDCachingKiWiPersistenceConnection  {
             kEntry.setLastRetrieved(entry.getLastRetrieved());
             kEntry.setUpdateCount(entry.getUpdateCount());
             kEntry.setResource(entry.getResource());
+            kEntry.setTripleCount(entry.getTripleCount());
         }
 
         if(! (entry.getResource() instanceof KiWiResource) || ((KiWiResource) entry.getResource()).getId() == null) {
             throw new IllegalStateException("the resource contained in the cache entry is not a KiWiResource!");
         }
 
+        // needed before the entry can be inserted
+        connection.flushBatch();
+
         kEntry.setId(connection.getNextSequence("seq.ldcache"));
 
         PreparedStatement insertEntry = connection.getPreparedStatement("store.entry");
@@ -159,6 +164,7 @@ public class LDCachingKiWiPersistenceConnection  {
         insertEntry.setTimestamp(3,new Timestamp(kEntry.getExpiryDate().getTime()));
         insertEntry.setLong(4,((KiWiNode)kEntry.getResource()).getId());
         insertEntry.setInt(5, kEntry.getUpdateCount());
+        insertEntry.setInt(6, kEntry.getTripleCount());
         insertEntry.executeUpdate();
 
         log.debug("persisted ld-cache entry with id {}", kEntry.getId());
@@ -326,7 +332,7 @@ public class LDCachingKiWiPersistenceConnection  {
      * @throws java.sql.SQLException
      */
     public void storeNode(KiWiNode node) throws SQLException {
-        connection.storeNode(node);
+        connection.storeNode(node, false);
     }
 
     /**