You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ja...@apache.org on 2014/01/08 16:25:28 UTC

[12/51] [abbrv] [partial] MARMOTTA-397: Reorganized and renamed Marmotta Sesame Tools

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/sail/KiWiTransactionalConnection.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/sail/KiWiTransactionalConnection.java b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/sail/KiWiTransactionalConnection.java
new file mode 100644
index 0000000..913421a
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/sail/KiWiTransactionalConnection.java
@@ -0,0 +1,167 @@
+/**
+ * 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.commons.sesame.transactions.sail;
+
+import org.apache.marmotta.commons.sesame.transactions.api.TransactionListener;
+import org.apache.marmotta.commons.sesame.transactions.api.TransactionalSailConnection;
+import org.apache.marmotta.commons.sesame.transactions.model.TransactionData;
+import org.openrdf.model.Statement;
+import org.openrdf.sail.NotifyingSailConnection;
+import org.openrdf.sail.SailConnectionListener;
+import org.openrdf.sail.SailException;
+import org.openrdf.sail.helpers.NotifyingSailConnectionWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Date;
+
+/**
+ * This is an extended version of the KiWi triple store connection with support for transaction tracking. It offers the
+ * possibility to register transaction listeners that are triggered whenever a connection commits or rolls back.
+ * If the transaction commits, they are also passed over the transaction data, i.e. the added and removed triples.
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class KiWiTransactionalConnection extends NotifyingSailConnectionWrapper implements SailConnectionListener, TransactionalSailConnection {
+
+    private static Logger log = LoggerFactory.getLogger(KiWiTransactionalConnection.class);
+
+    private Collection<TransactionListener> listeners;
+
+    private TransactionData data;
+
+    public KiWiTransactionalConnection(NotifyingSailConnection wrapped, Collection<TransactionListener> listeners) throws SailException {
+        super(wrapped);
+        wrapped.addConnectionListener(this);
+
+        this.listeners = listeners;
+    }
+
+    /**
+     * Add a transaction listener to the transactional connection.
+     *
+     * @param listener
+     */
+    @Override
+    public void addTransactionListener(TransactionListener listener) {
+        if(!listeners.contains(listener)) {
+            listeners.add(listener);
+        }
+    }
+
+    /**
+     * Remove a transaction listener from the transactional connection
+     *
+     * @param listener
+     */
+    @Override
+    public void removeTransactionListener(TransactionListener listener) {
+        listeners.remove(listener);
+    }
+
+
+    /**
+     * This method is called when a triple has been added to the repository. It can be overridden by subclasses to
+     * add additional functionality.
+     *
+     * @param triple
+     */
+    @Override
+    public void statementAdded(Statement triple) {
+        ensureTransactionStarted();
+        data.addTriple(triple);
+    }
+
+    /**
+     * This method is called when a triple has been removed from the repository. It can be overridden by subclasses to
+     * add additional functionality.
+     *
+     * @param triple
+     */
+    @Override
+    public void statementRemoved(Statement triple) {
+        ensureTransactionStarted();
+        data.removeTriple(triple);
+    }
+
+    @Override
+    public void begin() throws SailException {
+        super.begin();
+
+        // start new transaction
+        data = new TransactionData();
+
+    }
+
+    /**
+     * Notify the listeners of a commit before and after calling the super method
+     * @throws SailException
+     */
+    @Override
+    public void commit() throws SailException {
+        // notify only if there is actually any data
+        if(data != null && data.getAddedTriples().size() + data.getRemovedTriples().size() > 0) {
+            data.setCommitTime(new Date());
+
+            // notify beforeCommit listeners
+            for(TransactionListener l : listeners) {
+                l.beforeCommit(data);
+            }
+
+            // perform commit
+            super.commit();
+
+            // notify afterCommit listeners
+            for(TransactionListener l : listeners) {
+                l.afterCommit(data);
+            }
+        } else {
+            super.commit();
+        }
+
+        // empty transaction data
+        data = new TransactionData();
+    }
+
+    /**
+     * Notify the listeners after rolling back.
+     * @throws SailException
+     */
+    @Override
+    public void rollback() throws SailException {
+        // perform rollback
+        super.rollback();
+
+        // notify rollback listeners
+        for(TransactionListener l : listeners) {
+            l.rollback(data);
+        }
+
+        // empty transaction data
+        data = new TransactionData();
+    }
+
+
+    private void ensureTransactionStarted() {
+        if(data == null) {
+            log.warn("transaction was not properly started, autostarting; please consider using connection.begin() explicitly!");
+            data = new TransactionData();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/sail/KiWiTransactionalSail.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/sail/KiWiTransactionalSail.java b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/sail/KiWiTransactionalSail.java
new file mode 100644
index 0000000..4ae35c5
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/sail/KiWiTransactionalSail.java
@@ -0,0 +1,104 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.commons.sesame.transactions.sail;
+
+import org.apache.marmotta.commons.sesame.transactions.api.TransactionListener;
+import org.apache.marmotta.commons.sesame.transactions.api.TransactionalSail;
+import org.openrdf.sail.NotifyingSail;
+import org.openrdf.sail.NotifyingSailConnection;
+import org.openrdf.sail.SailException;
+import org.openrdf.sail.helpers.NotifyingSailWrapper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is an extended version of the KiWi triple store with support for transaction tracking. It offers the
+ * possibility to register transaction listeners that are triggered whenever a connection commits or rolls back.
+ * If the transaction commits, they are also passed over the transaction data, i.e. the added and removed triples.
+ * <p/>
+ * Note that even the basic KiWiStore offers transaction support by directly wrapping database transactions. The
+ * extended transactions provided by the KiWiTransactionalStore are only necessary for getting access to the
+ * transaction data and triggering actions on commit or rollback.s
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class KiWiTransactionalSail extends NotifyingSailWrapper implements TransactionalSail {
+
+    private List<TransactionListener> listeners;
+
+    private boolean transactionsEnabled;
+
+    public KiWiTransactionalSail(NotifyingSail base) {
+        super(base);
+
+        this.listeners           = new ArrayList<TransactionListener>();
+        this.transactionsEnabled = true;
+    }
+
+    /**
+     * Add a transaction listener to the KiWiTransactionalStore. The listener will be notified whenever a connection
+     * commits or rolls back. The listeners are collected in a list, i.e. a listener that is added first is also executed
+     * first.
+     *
+     * @param listener the listener to add to the list
+     */
+    public void addTransactionListener(TransactionListener listener) {
+        listeners.add(listener);
+    }
+
+    /**
+     * Remove a transaction listener from the list.
+     *
+     * @param listener the listener to remove
+     */
+    public void removeTransactionListener(TransactionListener listener) {
+        listeners.remove(listener);
+    }
+
+    /**
+     * Check if extended transaction support is enabled
+     * @return true if extended transactions are enabled
+     */
+    public boolean isTransactionsEnabled() {
+        return transactionsEnabled;
+    }
+
+    /**
+     * Temporarily enable/disable extended transactions. Disabling transactions might be useful when bulk loading large
+     * amounts of data.
+     *
+     * @param transactionsEnabled
+     */
+    public void setTransactionsEnabled(boolean transactionsEnabled) {
+        this.transactionsEnabled = transactionsEnabled;
+    }
+
+    /**
+     * Returns a store-specific SailConnection object.
+     *
+     * @return A connection to the store.
+     */
+    @Override
+    public NotifyingSailConnection getConnection() throws SailException {
+        if(transactionsEnabled)
+            return new KiWiTransactionalConnection(super.getConnection(),listeners);
+        else
+            return super.getConnection();
+    }
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/wrapper/TransactionalSailConnectionWrapper.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/wrapper/TransactionalSailConnectionWrapper.java b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/wrapper/TransactionalSailConnectionWrapper.java
new file mode 100644
index 0000000..4c28e54
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/wrapper/TransactionalSailConnectionWrapper.java
@@ -0,0 +1,59 @@
+/**
+ * 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.commons.sesame.transactions.wrapper;
+
+import org.apache.marmotta.commons.sesame.transactions.api.TransactionListener;
+import org.apache.marmotta.commons.sesame.transactions.api.TransactionalSailConnection;
+import org.openrdf.sail.helpers.NotifyingSailConnectionWrapper;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class TransactionalSailConnectionWrapper extends NotifyingSailConnectionWrapper implements TransactionalSailConnection {
+
+    private TransactionalSailConnection parent;
+
+    public TransactionalSailConnectionWrapper(TransactionalSailConnection parent) {
+        super(parent);
+        this.parent = parent;
+    }
+
+    /**
+     * Add a transaction listener to the KiWiTransactionalStore. The listener will be notified whenever a connection
+     * commits or rolls back. The listeners are collected in a list, i.e. a listener that is added first is also executed
+     * first.
+     *
+     * @param listener the listener to add to the list
+     */
+    @Override
+    public void addTransactionListener(TransactionListener listener) {
+        parent.addTransactionListener(listener);
+    }
+
+    /**
+     * Remove a transaction listener from the list.
+     *
+     * @param listener the listener to remove
+     */
+    @Override
+    public void removeTransactionListener(TransactionListener listener) {
+        parent.removeTransactionListener(listener);
+    }
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/wrapper/TransactionalSailWrapper.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/wrapper/TransactionalSailWrapper.java b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/wrapper/TransactionalSailWrapper.java
new file mode 100644
index 0000000..2471f16
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/main/java/org/apache/marmotta/commons/sesame/transactions/wrapper/TransactionalSailWrapper.java
@@ -0,0 +1,83 @@
+/**
+ * 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.commons.sesame.transactions.wrapper;
+
+import org.apache.marmotta.commons.sesame.transactions.api.TransactionListener;
+import org.apache.marmotta.commons.sesame.transactions.api.TransactionalSail;
+import org.openrdf.sail.helpers.NotifyingSailWrapper;
+
+/**
+ * A Sail Wrapper allowing to pass through transaction functionality to other sails.
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class TransactionalSailWrapper extends NotifyingSailWrapper implements TransactionalSail {
+
+    private TransactionalSail parent;
+
+    /**
+     * Creates a new SailWrapper that wraps the supplied Sail.
+     */
+    public TransactionalSailWrapper(TransactionalSail parent) {
+        super(parent);
+        this.parent = parent;
+    }
+
+    /**
+     * Add a transaction listener to the KiWiTransactionalStore. The listener will be notified whenever a connection
+     * commits or rolls back. The listeners are collected in a list, i.e. a listener that is added first is also executed
+     * first.
+     *
+     * @param listener the listener to add to the list
+     */
+    @Override
+    public void addTransactionListener(TransactionListener listener) {
+        parent.addTransactionListener(listener);
+    }
+
+    /**
+     * Remove a transaction listener from the list.
+     *
+     * @param listener the listener to remove
+     */
+    @Override
+    public void removeTransactionListener(TransactionListener listener) {
+        parent.removeTransactionListener(listener);
+    }
+
+    /**
+     * Check if extended transaction support is enabled
+     *
+     * @return true if extended transactions are enabled
+     */
+    @Override
+    public boolean isTransactionsEnabled() {
+        return parent.isTransactionsEnabled();
+    }
+
+    /**
+     * Temporarily enable/disable extended transactions. Disabling transactions might be useful when bulk loading large
+     * amounts of data.
+     *
+     * @param transactionsEnabled
+     */
+    @Override
+    public void setTransactionsEnabled(boolean transactionsEnabled) {
+        parent.setTransactionsEnabled(transactionsEnabled);
+    }
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/java/org/apache/marmotta/kiwi/test/TransactionTest.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/java/org/apache/marmotta/kiwi/test/TransactionTest.java b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/java/org/apache/marmotta/kiwi/test/TransactionTest.java
new file mode 100644
index 0000000..75da3a8
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/java/org/apache/marmotta/kiwi/test/TransactionTest.java
@@ -0,0 +1,202 @@
+/**
+ * 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.test;
+
+import static org.hamcrest.CoreMatchers.hasItems;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assume.assumeThat;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import org.apache.marmotta.commons.sesame.repository.ResourceUtils;
+import org.apache.marmotta.commons.sesame.transactions.api.TransactionListener;
+import org.apache.marmotta.commons.sesame.transactions.model.TransactionData;
+import org.apache.marmotta.commons.sesame.transactions.sail.KiWiTransactionalSail;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.openrdf.model.Resource;
+import org.openrdf.repository.Repository;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.repository.RepositoryException;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.rio.RDFFormat;
+import org.openrdf.rio.RDFParseException;
+import org.openrdf.sail.NotifyingSail;
+import org.openrdf.sail.memory.MemoryStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+/**
+ * Test the Sesame repository functionality backed by the KiWi triple store. 
+ * 
+ * @author Sebastian Schaffert (sschaffert@apache.org)
+ */
+public class TransactionTest {
+    private static Logger log = LoggerFactory.getLogger(TransactionTest.class);
+
+    private Repository repository;
+
+    private NotifyingSail store;
+
+    private KiWiTransactionalSail tstore;
+
+    private MockListener listener;
+
+    @Before
+    public void initDatabase() throws RepositoryException {
+        store = new MemoryStore();
+        tstore = new KiWiTransactionalSail(store);
+        listener = new MockListener();
+        tstore.addTransactionListener(listener);
+        repository = new SailRepository(tstore);
+        repository.initialize();
+    }
+
+    @After
+    public void dropDatabase() throws RepositoryException {
+        repository.shutDown();
+    }
+
+
+    /**
+     * Test importing data; the test will load a small sample RDF file and check whether the expected resources are
+     * present.
+     *
+     * @throws RepositoryException
+     * @throws org.openrdf.rio.RDFParseException
+     * @throws java.io.IOException
+     */
+    @Test
+    public void testImport() throws RepositoryException, RDFParseException, IOException {
+        long start, end;
+
+        start = System.currentTimeMillis();
+        // load demo data
+        InputStream rdfXML = this.getClass().getResourceAsStream("demo-data.foaf");
+        assumeThat("Could not load test-data: demo-data.foaf", rdfXML, notNullValue(InputStream.class));
+
+        RepositoryConnection connectionRDF = repository.getConnection();
+        try {
+            connectionRDF.begin();
+            connectionRDF.add(rdfXML, "http://localhost/foaf/", RDFFormat.RDFXML);
+            connectionRDF.commit();
+        } finally {
+            connectionRDF.close();
+        }
+        end = System.currentTimeMillis();
+
+        log.info("IMPORT: {} ms", end-start);
+
+
+        // check if the transaction data is available and contains added triples
+        Assert.assertNotNull("transaction data was null",listener.transactionData);
+        Assert.assertTrue("transaction data did not contain added triples", listener.transactionData.getAddedTriples().size() > 0);
+    }
+
+
+    @Test
+    public void testDeleteTriple() throws RepositoryException, RDFParseException, IOException {
+        // load demo data
+        InputStream rdfXML = this.getClass().getResourceAsStream("demo-data.foaf");
+        assumeThat("Could not load test-data: demo-data.foaf", rdfXML, notNullValue(InputStream.class));
+
+        RepositoryConnection connectionRDF = repository.getConnection();
+        try {
+            connectionRDF.begin();
+            connectionRDF.add(rdfXML, "http://localhost/foaf/", RDFFormat.RDFXML);
+            connectionRDF.commit();
+        } finally {
+            connectionRDF.close();
+        }
+        // get another connection and check if demo data is available
+        RepositoryConnection connection = repository.getConnection();
+
+        try {
+            connection.begin();
+            List<String> resources = ImmutableList.copyOf(
+                    Iterables.transform(
+                            ResourceUtils.listSubjects(connection),
+                            new Function<Resource, String>() {
+                                @Override
+                                public String apply(Resource input) {
+                                    return input.stringValue();
+                                }
+                            }
+                    )
+            );
+
+            // test if the result has the expected size
+            Assert.assertEquals(4, resources.size());
+
+            // test if the result contains all resources that have been used as subject
+            Assert.assertThat(resources, hasItems(
+                    "http://localhost:8080/LMF/resource/hans_meier",
+                    "http://localhost:8080/LMF/resource/sepp_huber",
+                    "http://localhost:8080/LMF/resource/anna_schmidt"
+            ));
+            connection.commit();
+
+
+            // remove a resource and all its triples
+            connection.begin();
+            ResourceUtils.removeResource(connection, connection.getValueFactory().createURI("http://localhost:8080/LMF/resource/hans_meier"));
+            connection.commit();
+
+
+            // check if transaction contains removed triples now
+            Assert.assertNotNull("transaction data was null", listener.transactionData);
+            Assert.assertTrue("transaction did not contain removed triples", listener.transactionData.getRemovedTriples().size() > 0);
+        } finally {
+            connection.commit();
+            connection.close();
+        }
+    }
+
+
+    /**
+     * Mock implementation of a transaction listener
+     */
+    private static class MockListener implements TransactionListener {
+
+        private TransactionData transactionData;
+
+        boolean rolledBack = false;
+
+        @Override
+        public void afterCommit(TransactionData data) {
+            transactionData = data;
+        }
+
+         @Override
+        public void beforeCommit(TransactionData data) {
+        }
+
+        @Override
+        public void rollback(TransactionData data) {
+            rolledBack = true;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/resources/logback.xml
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/resources/logback.xml b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/resources/logback.xml
new file mode 100644
index 0000000..9678d31
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/resources/logback.xml
@@ -0,0 +1,30 @@
+<!--
+  ~ 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.
+  -->
+
+<configuration>
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} %highlight(%level) %cyan(%logger{15}) - %m%n</pattern>
+        </encoder>
+    </appender>
+
+    <logger name="net.sf.ehcache.pool.impl" level="WARN" />
+
+    <root level="${root-level:-INFO}">
+        <appender-ref ref="CONSOLE"/>
+    </root>
+</configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/resources/org/apache/marmotta/kiwi/test/demo-data.foaf
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/resources/org/apache/marmotta/kiwi/test/demo-data.foaf b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/resources/org/apache/marmotta/kiwi/test/demo-data.foaf
new file mode 100644
index 0000000..1b7695a
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/resources/org/apache/marmotta/kiwi/test/demo-data.foaf
@@ -0,0 +1,70 @@
+<?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.
+-->
+<rdf:RDF
+        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+        xmlns:foaf="http://xmlns.com/foaf/0.1/"
+        xmlns:dc="http://purl.org/dc/elements/1.1/">
+
+    <foaf:Person rdf:about="http://localhost:8080/LMF/resource/hans_meier" xmlns:foaf="http://xmlns.com/foaf/0.1/">
+        <foaf:name>Hans Meier</foaf:name>
+        <dc:description>Hans Meier is a software engineer living in Salzburg</dc:description>
+        <foaf:interest rdf:resource="http://rdf.freebase.com/ns/en.software_engineering"/>
+        <foaf:interest rdf:resource="http://rdf.freebase.com/ns/en.linux"/>
+        <foaf:interest rdf:resource="http://dbpedia.org/resource/Java" />
+        <foaf:interest rdf:resource="http://dbpedia.org/resource/Climbing"/>
+        <foaf:based_near rdf:resource="http://sws.geonames.org/2766824/"/>
+        <foaf:depiction rdf:resource="http://localhost:8080/LMF/resource/hans_meier.jpg"/>
+
+        <foaf:knows rdf:resource="http://localhost:8080/LMF/resource/sepp_huber" />
+        <foaf:knows rdf:resource="http://localhost:8080/LMF/resource/anna_schmidt"/>
+
+        <foaf:account>
+            <foaf:OnlineAccount>
+                <foaf:accountName>Example</foaf:accountName>
+                <foaf:accountServiceHomepage>http://www.example.com</foaf:accountServiceHomepage>
+            </foaf:OnlineAccount>
+        </foaf:account>
+    </foaf:Person>
+
+    <foaf:Person rdf:about="http://localhost:8080/LMF/resource/sepp_huber" xmlns:foaf="http://xmlns.com/foaf/0.1/">
+        <foaf:name>Sepp Huber</foaf:name>
+        <dc:description>Sepp Huber is an alpinist living in Traunstein. He is a good climber, but not as famous as his cousin Alexander Huber.</dc:description>
+        <foaf:interest rdf:resource="http://dbpedia.org/resource/Mountaineering"/>
+        <foaf:interest rdf:resource="http://dbpedia.org/resource/Climbing"/>
+        <foaf:interest rdf:resource="http://localhost:8080/LMF/resource/Chess" />
+        <foaf:based_near rdf:resource="http://dbpedia.org/resource/Traunstein"/>
+
+        <foaf:knows rdf:resource="http://dbpedia.org/resource/Alexander_Huber" />
+        <foaf:knows rdf:resource="http://localhost:8080/LMF/resource/hans_meier" />
+    </foaf:Person>
+
+    <foaf:Person rdf:about="http://localhost:8080/LMF/resource/anna_schmidt" xmlns:foaf="http://xmlns.com/foaf/0.1/">
+        <foaf:name>Anna Schmidt</foaf:name>
+        <dc:description>Anna Schmidt is working as PR manager for mountaineers coming from Garmisch-Partenkirchen. She likes mountaineering and is also a Linux enthusiast.</dc:description>
+        <foaf:interest rdf:resource="http://dbpedia.org/resource/Mountaineering"/>
+        <foaf:interest rdf:resource="http://dbpedia.org/resource/Linux"/>
+        <foaf:interest rdf:resource="http://localhost:8080/LMF/resource/Chess" />
+        <foaf:based_near rdf:resource="http://dbpedia.org/resource/Garmisch-Partenkirchen"/>
+        <foaf:depiction rdf:resource="http://localhost:8080/LMF/resource/anna_schmidt.jpg"/>
+
+        <foaf:knows rdf:resource="http://dbpedia.org/resource/Alexander_Huber" />
+        <foaf:knows rdf:resource="http://localhost:8080/LMF/resource/sepp_huber" />
+    </foaf:Person>
+
+
+</rdf:RDF>

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/resources/org/apache/marmotta/kiwi/test/srfg-ontology.rdf
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/resources/org/apache/marmotta/kiwi/test/srfg-ontology.rdf b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/resources/org/apache/marmotta/kiwi/test/srfg-ontology.rdf
new file mode 100644
index 0000000..14e3ed1
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-sail-transactions/src/test/resources/org/apache/marmotta/kiwi/test/srfg-ontology.rdf
@@ -0,0 +1,126 @@
+<?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.
+-->
+<!DOCTYPE rdf:RDF [
+<!ENTITY lmf "http://localhost:8080/LMF/resource/">]>
+<rdf:RDF
+        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+        xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
+        xmlns:foaf="http://xmlns.com/foaf/0.1/"
+        xmlns:lmfc="http://localhost:8080/LMF/resource/concepts/">
+
+
+    <lmfc:NationalProject about="&lmf;SNML-TNG">
+        <rdfs:label>SNML TNG</rdfs:label>
+        <rdfs:comment>Salzburg NewMediaLab - The Next Generation</rdfs:comment>
+        <lmfc:projectFolder>snml-tng</lmfc:projectFolder>
+    </lmfc:NationalProject>
+
+    <lmfc:NationalProject about="&lmf;SNML">
+        <rdfs:label>SNML</rdfs:label>
+        <rdfs:comment>Salzburg NewMediaLab</rdfs:comment>
+        <lmfc:projectFolder>snml</lmfc:projectFolder>
+    </lmfc:NationalProject>
+
+    <lmfc:NationalProject about="&lmf;myTV">
+        <rdfs:label>myTV</rdfs:label>
+        <rdfs:comment>my Semantically Enhanced Personalized TV Experience</rdfs:comment>
+        <lmfc:projectFolder>mytv</lmfc:projectFolder>
+    </lmfc:NationalProject>
+
+    <lmfc:NationalProject about="&lmf;ConnectMe">
+        <rdfs:label>ConnectMe</rdfs:label>
+        <rdfs:comment>Connected Media Experience</rdfs:comment>
+        <lmfc:projectFolder>connectme</lmfc:projectFolder>
+    </lmfc:NationalProject>
+
+    <lmfc:NationalProject about="&lmf;CAPKOM">
+        <rdfs:label>CAPKOM</rdfs:label>
+        <rdfs:comment>CAPKOM - Innovative Benutzeroberflächen für Men-schen mit kognitiver Beeinträchtigung</rdfs:comment>
+        <lmfc:projectFolder>capkom</lmfc:projectFolder>
+    </lmfc:NationalProject>
+
+
+    <lmfc:EUProject about="&lmf;KiWi">
+        <rdfs:label>KiWi</rdfs:label>
+        <rdfs:comment>KiWi - Knowledge in a Wiki</rdfs:comment>
+        <lmfc:projectFolder>kiwi</lmfc:projectFolder>
+    </lmfc:EUProject>
+
+    <lmfc:EUProject about="&lmf;IKS">
+        <rdfs:label>IKS</rdfs:label>
+        <rdfs:comment>IKS - Interactive Knowledge Stack</rdfs:comment>
+        <lmfc:projectFolder>iks</lmfc:projectFolder>
+    </lmfc:EUProject>
+
+    <lmfc:EUProject about="&lmf;Mosep">
+        <rdfs:label>Mosep</rdfs:label>
+        <rdfs:comment>Mosep - More self-esteem with my ePortfolio</rdfs:comment>
+        <lmfc:projectFolder>mosep</lmfc:projectFolder>
+    </lmfc:EUProject>
+
+    <lmfc:EUProject about="&lmf;ImportNET">
+        <rdfs:label>ImportNET</rdfs:label>
+        <rdfs:comment>Intelligent modular open source Platform for intercultural and cross-domain SME Networks</rdfs:comment>
+        <lmfc:projectFolder>importnet</lmfc:projectFolder>
+    </lmfc:EUProject>
+
+
+    <foaf:Project about="&lmf;KMT">
+        <rdfs:label>KMT</rdfs:label>
+        <rdfs:comment>Knowledge and Media Technologies</rdfs:comment>
+    </foaf:Project>
+
+
+    <foaf:Person about="&lmf;gguentner">
+        <foaf:name>Georg Güntner</foaf:name>
+        <foaf:nick>gguentner</foaf:nick>
+        <foaf:nick>georg.guentner@salzburgresearch.at</foaf:nick>
+    </foaf:Person>
+
+    <foaf:Person about="&lmf;sschaffe">
+        <foaf:name>Sebastian Schaffert</foaf:name>
+        <foaf:nick>sschaffe</foaf:nick>
+    </foaf:Person>
+
+    <foaf:Person about="&lmf;wbehrendt">
+        <foaf:name>Wernher Behrendt</foaf:name>
+        <foaf:nick>wbehrendt</foaf:nick>
+    </foaf:Person>
+
+    <foaf:Person about="&lmf;uatzlinger">
+        <foaf:name>Ursula Atzlinger</foaf:name>
+        <foaf:nick>uatzlinger</foaf:nick>
+    </foaf:Person>
+
+    <foaf:Person about="&lmf;awagner">
+        <foaf:name>Alexandra Wagner</foaf:name>
+        <foaf:nick>awagner</foaf:nick>
+    </foaf:Person>
+
+    <foaf:Person about="&lmf;agruber">
+        <foaf:name>Andreas Gruber</foaf:name>
+        <foaf:nick>agruber</foaf:nick>
+    </foaf:Person>
+
+    <foaf:Person about="&lmf;bstroh">
+        <foaf:name>Birgit Strohmeier</foaf:name>
+        <foaf:nick>bstroh</foaf:nick>
+    </foaf:Person>
+
+
+</rdf:RDF>

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-util-facading/pom.xml
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-util-facading/pom.xml b/commons/marmotta-sesame-tools/marmotta-util-facading/pom.xml
new file mode 100644
index 0000000..aa1885f
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-util-facading/pom.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.marmotta</groupId>
+        <artifactId>marmotta-parent</artifactId>
+        <version>3.2.0-SNAPSHOT</version>
+        <relativePath>../../../parent</relativePath>
+    </parent>
+
+    <artifactId>marmotta-util-facading</artifactId>
+    <name>Marmotta Sesame Tools: Facading</name>
+    <description>
+        Allows using annotated Java interfaces (facades) to access an underlying 
+        Sesame repository, similar to JPA.
+    </description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.marmotta</groupId>
+            <artifactId>marmotta-commons</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-model</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-repository-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-query</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-queryparser-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-queryparser-sparql</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-queryalgebra-model</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-queryalgebra-evaluation</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-sail-memory</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-repository-sail</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-rio-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.openrdf.sesame</groupId>
+            <artifactId>sesame-rio-rdfxml</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-library</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.marmotta</groupId>
+            <artifactId>kiwi-triplestore</artifactId>
+            <scope>test</scope>
+        </dependency>
+                <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>test</scope>
+        </dependency>
+        
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/FacadingFactory.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/FacadingFactory.java b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/FacadingFactory.java
new file mode 100644
index 0000000..772a398
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/FacadingFactory.java
@@ -0,0 +1,40 @@
+/*
+ * 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.commons.sesame.facading;
+
+import org.apache.marmotta.commons.sesame.facading.api.Facading;
+import org.apache.marmotta.commons.sesame.facading.impl.FacadingImpl;
+import org.openrdf.repository.RepositoryConnection;
+
+/**
+ * A factory to simplify the creation of facading services.
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public class FacadingFactory {
+
+    /**
+     * Create a facading for an existing repository connection.
+     *
+     * @param connection the repository connection to use for facading
+     * @return a new facading service wrapping the given connection
+     */
+    public static Facading createFacading(RepositoryConnection connection) {
+        return new FacadingImpl(connection);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDF.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDF.java b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDF.java
new file mode 100644
index 0000000..33b7b2a
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDF.java
@@ -0,0 +1,55 @@
+/*
+ * 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.commons.sesame.facading.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/**
+ * This annotation indicates that a certain field should be
+ * persisted to the KiWi triple store using the property URI
+ * passed as annotation parameter.<br>
+ * The TripleStore class checks for <b>RDF</b> annotations
+ * during persist and load. <br>
+ * Classes using this annotation must currently implement the
+ * {@link org.apache.marmotta.platform.core.model.rdf.KiWiEntity} interface, so that the
+ * KnowledgeSpace has access to the resource associated with the
+ * entity.<br>
+ * This is a runtime annotation and it is applicable on fields
+ * and on getter methods.<br>
+ *
+ * @author Sebastian Schaffert
+ * @see org.apache.marmotta.platform.core.model.rdf.KiWiEntity
+ */
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target( {ElementType.FIELD, ElementType.METHOD})
+public @interface RDF {
+
+    /**
+     * Return the URI of the RDF predicate to use for the field
+     * or method.
+     *
+     * @returns URI of the RDF predicate to use for the field or
+     *          method.
+     */
+	String[] value();
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFContext.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFContext.java b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFContext.java
new file mode 100644
index 0000000..15c5d76
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFContext.java
@@ -0,0 +1,36 @@
+/*
+ * 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.commons.sesame.facading.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation indicates that a certain interface should be
+ * persisted to the KiWi triple store using the context uri and type
+ * for the default context for all implementations of this class.<br>
+ *
+ * @author Stefan Robert
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target( { ElementType.TYPE } )
+public @interface RDFContext {
+
+    String value();
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFFilter.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFFilter.java b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFFilter.java
new file mode 100644
index 0000000..95542b8
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFFilter.java
@@ -0,0 +1,41 @@
+/*
+ * 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.commons.sesame.facading.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Specifies a filter for facades that selects the content items that may be facaded based on the
+ * type of the content item. Only of a content item satisfies all types specified here is it accepted in
+ * a result set.
+ * 
+ * @author Sebastian Schaffert
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target( { ElementType.TYPE } )
+public @interface RDFFilter {
+	/**
+	 * The URI of the RDF type to use for the class
+	 * @return
+	 */
+	String[] value();
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFInverse.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFInverse.java b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFInverse.java
new file mode 100644
index 0000000..25e7fc5
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFInverse.java
@@ -0,0 +1,60 @@
+/*
+ * 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.commons.sesame.facading.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation indicates that a certain KiWi facade field should be mapped
+ * inversely to a property in the triple store. It is the inverse of the
+ * <code>@RDF</code> annotation, e.g. when using
+ * <code>@RDFInverse("rdfs:subClassOf")</code>, the annotated method returns the
+ * subclasses, while the annotation <code>@RDF("rdfs:subClassOf")</code> would
+ * return the superclasses. Note that <code>@RDFInverse</code> only works on
+ * ObjectProperties; for all other properties it behaves exactly like
+ * <code>@RDF</code>
+ * <p>
+ * The KiWiEntityManager and TripleStore check for the presence of this
+ * annotation on methods and dynamically maps them to queries on the triple
+ * store, using the resource of the annotated interface or class (which must
+ * implement KiWiEntity to provide a getResource() method) as object.
+ * <p>
+ * This is a runtime annotation and it is applicable on getter methods.<br>
+ * <p>
+ * TODO: currently, only KiWiFacades are supported; also, it is currently not
+ * possible to provide {@link @RDF} and {@link @RDFInverse} on the same method
+ * at the same time.
+ * 
+ * @author Sebastian Schaffert
+ */
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target( {ElementType.METHOD})
+public @interface RDFInverse {
+
+	/**
+	 * Return the URI of the RDF predicate to use for the field
+	 * or method.
+	 *
+	 * @returns URI of the RDF predicate to use for the field or
+	 *          method.
+	 */
+	String[] value();
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFPropertyBuilder.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFPropertyBuilder.java b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFPropertyBuilder.java
new file mode 100644
index 0000000..47688a3
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFPropertyBuilder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.commons.sesame.facading.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.marmotta.commons.sesame.facading.api.FacadingPredicateBuilder;
+
+/**
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface RDFPropertyBuilder {
+
+    Class<? extends FacadingPredicateBuilder> value();
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFType.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFType.java b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFType.java
new file mode 100644
index 0000000..215f3a1
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/annotations/RDFType.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.marmotta.commons.sesame.facading.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/**
+ * This annotation specifies the RDF-type of an object-class
+ * 
+ * @author Stephanie Stroka
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target( { ElementType.TYPE } )
+public @interface RDFType {
+	/**
+	 * The URI of the RDF type to use for the class
+	 * @return
+	 */
+	String[] value();
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/api/Facading.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/api/Facading.java b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/api/Facading.java
new file mode 100644
index 0000000..dc9334b
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/api/Facading.java
@@ -0,0 +1,123 @@
+/*
+ * 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.commons.sesame.facading.api;
+
+import org.apache.marmotta.commons.sesame.facading.model.Facade;
+import org.openrdf.model.Resource;
+import org.openrdf.model.URI;
+
+import java.util.Collection;
+
+/**
+ * Offers methods for loading and proxying KiWiFacades. A KiWi Facade is an interface that defines a Java
+ * object with convenient Java methods around a KiWiResource and makes it possible to use RDF properties like
+ * Java Bean properties from inside Java.
+ * <p/>
+ * The facading service is used by many other services, e.g. ContentItemService and TaggingService, to provide
+ * access on a higher level than raw RDF resources.
+ *
+ *
+ * <p/>
+ * User: sschaffe
+ */
+public interface Facading {
+
+    /**
+     * Create an instance of C that facades the resource given as argument using the @RDF annotations provided
+     * to the getter or setter methods of Cto map to properties of the resource in the triple store.
+     *
+     *
+     * @param r the resource to facade
+     * @param type the facade type as a class
+     * @return
+     */
+    public <C extends Facade> C createFacade(Resource r, Class<C> type);
+
+    /**
+     * Create an instance of C that facades the resource given as argument using the @RDF annotations provided
+     * to the getter or setter methods of Cto map to properties of the resource in the triple store.
+     * Additionally, it puts the facade into the given context.
+     * This is useful if the @RDFContext annotation for Facades is not applicable.
+     * E.g. if the context is dynamically generated.
+     *
+     *
+     * @param r the resource to facade
+     * @param type the facade type as a class
+     * @param context the context into which the facade should be put
+     * @return
+     */
+    public <C extends Facade> C createFacade(Resource r, Class<C> type, URI context);
+
+    /**
+     * Create a collection of instances of C that facade the resources given in the collection passed as argument.
+     * The facade uses the @RDF annotations provided to the getter or setter methods of C. The returned collection
+     * is of the same kind as the passed collection.
+     *
+     *
+     * @param list the collection containing the resources to facade
+     * @param type the facade type as a class
+     * @return
+     */
+    public <C extends Facade> Collection<C> createFacade(Collection<? extends Resource> list, Class<C> type);
+
+    /**
+     * Create an instance of C that facades the resource identified by the uri given as argument, using the @RDF
+     * annotations provided to the getter or setter methods of C to map to properties of the resource in the triple
+     * store.
+     *
+     * @param uri the uri of the resource to facade
+     * @param type the facade type as a class
+     * @param <C> the facade type as a generic parameter
+     * @return
+     */
+    public <C extends Facade> C createFacade(String uri, Class<C> type);
+
+    /**
+     * Check whether the resource fits into the facade.
+     * 
+     *
+     * @param r the resource to check
+     * @param type the facade to check for
+     * @param context limit all checks to this context
+     * @return <code>true</code> if the resource <code>r</code> fulfills all {@link org.apache.marmotta.commons.sesame.facading.annotations.RDFType} and
+     *         {@link org.apache.marmotta.commons.sesame.facading.annotations.RDFFilter} requirements of <code>type</code>
+     */
+    public <C extends Facade> boolean isFacadeable(Resource r, Class<C> type, URI context);
+
+    /**
+     * Check whether the resource fits into the facade.
+     * 
+     *
+     * @param r the resource to check
+     * @param type the facade to check for
+     * @return <code>true</code> if the resource <code>r</code> fulfills all {@link org.apache.marmotta.commons.sesame.facading.annotations.RDFType} and
+     *         {@link org.apache.marmotta.commons.sesame.facading.annotations.RDFFilter} requirements of <code>type</code>
+     */
+    public <C extends Facade> boolean isFacadeable(Resource r, Class<C> type);
+
+    /**
+     * Create a collection of instances of C that facade the resources given in the collection passed as argument.
+     * The facade uses the {@link org.apache.marmotta.commons.sesame.facading.annotations.RDF} annotations provided to the getter or setter methods of C. The returned collection
+     * is of the same kind as the passed collection.
+     *
+     *
+     * @param list the collection containing the resources to facade
+     * @param type the facade type as a class
+     * @return
+     */
+    <C extends Facade> Collection<C> createFacade(Collection<? extends Resource> list, Class<C> type, URI context);
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/api/FacadingPredicateBuilder.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/api/FacadingPredicateBuilder.java b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/api/FacadingPredicateBuilder.java
new file mode 100644
index 0000000..bf29a4a
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/api/FacadingPredicateBuilder.java
@@ -0,0 +1,37 @@
+/*
+ * 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.commons.sesame.facading.api;
+
+
+import java.lang.reflect.Method;
+
+import org.apache.marmotta.commons.sesame.facading.impl.FacadingPredicate;
+import org.apache.marmotta.commons.sesame.facading.model.Facade;
+
+/**
+ * Dynamically create the RDF-property uri for facading.
+ * <p>
+ * <strong>NOTE: All implementations MUST provide either a public no-arg Constructor or a public
+ * static no-arg <code>getInstance()</code>-method!</strong>
+ * <p>
+ * 
+ */
+public interface FacadingPredicateBuilder {
+
+    public FacadingPredicate getFacadingPredicate(String fieldName, Class<? extends Facade> facade, Method method);
+
+}

http://git-wip-us.apache.org/repos/asf/marmotta/blob/00c22e7c/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/impl/FacadingImpl.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/impl/FacadingImpl.java b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/impl/FacadingImpl.java
new file mode 100644
index 0000000..8cfba98
--- /dev/null
+++ b/commons/marmotta-sesame-tools/marmotta-util-facading/src/main/java/org/apache/marmotta/commons/sesame/facading/impl/FacadingImpl.java
@@ -0,0 +1,291 @@
+/*
+ * 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.commons.sesame.facading.impl;
+
+import java.lang.reflect.Proxy;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.apache.marmotta.commons.sesame.facading.annotations.RDF;
+import org.apache.marmotta.commons.sesame.facading.annotations.RDFContext;
+import org.apache.marmotta.commons.sesame.facading.annotations.RDFFilter;
+import org.apache.marmotta.commons.sesame.facading.annotations.RDFType;
+import org.apache.marmotta.commons.sesame.facading.api.Facading;
+import org.apache.marmotta.commons.sesame.facading.model.Facade;
+import org.apache.marmotta.commons.sesame.facading.util.FacadeUtils;
+import org.openrdf.model.Resource;
+import org.openrdf.model.URI;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.repository.RepositoryException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Offers methods for loading and proxying Facades. A {@link Facade} is an interface that defines a
+ * Java object with convenient Java methods around a {@link Resource} and makes it possible to use RDF
+ * properties like Java Bean properties from inside Java.
+ * <p/>
+ * The facading service is to provide access on a higher level than raw RDF resources.
+ * <p/>
+ * @author Sebastian Schaffert <ss...@apache.org>
+ * @author Jakob Frank <ja...@apache.org>
+ */
+public class FacadingImpl implements Facading {
+
+    private static final URI RDF_TYPE = org.openrdf.model.vocabulary.RDF.TYPE;
+
+
+    private static Logger log = LoggerFactory.getLogger(FacadingImpl.class);
+
+
+    private final RepositoryConnection connection;
+
+
+    public FacadingImpl(RepositoryConnection connection) {
+        this.connection = connection;
+    }
+
+    /**
+     * Create an instance of {@code C} that facades the resource given as argument using the {@link RDF} annotations provided
+     * to the getter or setter methods of {@code C} to map to properties of the resource in the triple store.
+     *
+     *
+     * @param r    the resource to facade
+     * @param type the facade type as a class
+     * @return a facading proxy of type {@code C}
+     */
+    @Override
+    public <C extends Facade> C createFacade(Resource r, Class<C> type) {
+        // support @RDFContext annotation in facade
+        URI context = null;
+        if(FacadeUtils.isFacadeAnnotationPresent(type, RDFContext.class)) {
+            String s_context = FacadeUtils.getFacadeAnnotation(type,RDFContext.class).value();
+            context = connection.getValueFactory().createURI(s_context);
+            log.debug("applying context {} for facade {} of {}", context, type.getSimpleName(), r);
+        }
+        return createFacade(r, type, context);
+    }
+
+    /**
+     * Create an instance of {@code C} that facades the resource given as argument using the {@link RDF} annotations provided
+     * to the getter or setter methods of {@code C} to map to properties of the resource in the triple store.
+     * Additionally, it puts the facade into the given context, a present {@link RDFContext} annotation is ignored.
+     * This is useful if the {@link RDFContext} annotation for Facades is not applicable,
+     * e.g. if the context is dynamically generated.
+     *
+     * @param r       the resource to facade
+     * @param type    the facade type as a class
+     * @param context the context of the facade
+     * @return a facading proxy of type {@code C}
+     */
+    @Override
+    public <C extends Facade> C createFacade(Resource r, Class<C> type, URI context) {
+        if(r == null) {
+            log.trace("null facade for null resouce");
+            return null;
+        } else 
+            // if the interface is a Facade, we execute the query and then
+            // create an invocation handler for each result to create proxy objects
+            if(type.isInterface() && FacadeUtils.isFacade(type)) {
+                try {
+                    // support @RDFType annotation in facade
+                    if(FacadeUtils.isFacadeAnnotationPresent(type, RDFType.class)) {
+                        if (!connection.isOpen()) { throw new IllegalStateException("the connection is already closed, cannot access triple-store."); }
+                        if (!connection.isActive()) { throw new IllegalStateException("no active transaction, cannot access triple-store."); }
+
+                        String[] a_type = FacadeUtils.getFacadeAnnotation(type, RDFType.class).value();
+                        for(String s_type : a_type) {
+                            final URI r_type = connection.getValueFactory().createURI(s_type);
+                            connection.add(r, RDF_TYPE, r_type, context);
+                            log.trace("added type {} to {} because of RDFType-Annotation", r_type, r);
+                            if(!connection.hasStatement(r, RDF_TYPE, r_type,true,context)) {
+                                log.error("error adding type for facade!");
+                            }
+                        }
+                    }
+
+                    FacadingInvocationHandler handler = new FacadingInvocationHandler(r, context, type, this, connection);
+                    if (log.isDebugEnabled()) {
+                        if (context != null) {
+                            log.debug("New Facading: {} delegating to {} (@{})", type.getSimpleName(), r, context);
+                        } else {
+                            log.debug("New Facading: {} delegating to {}", type.getSimpleName(), r);
+                        }
+                    }
+                    return type.cast(Proxy.newProxyInstance(type.getClassLoader(), new Class[]{type}, handler));
+                } catch (RepositoryException e) {
+                    log.error("error while accessing triple store", e);
+                    return null;
+                }
+            } else {
+                throw new IllegalArgumentException("interface passed as parameter is not a Facade (" + type.getCanonicalName() + ")");
+            }
+    }
+
+    /**
+     * Create a collection of instances of C that facade the resources given in the collection passed as argument.
+     * The facade uses the {@link RDF} annotations provided to the getter or setter methods of C. The returned collection
+     * is of the same kind as the passed collection.
+     *
+     *
+     * @param list the collection containing the resources to facade
+     * @param type the facade type as a class
+     * @return
+     */
+    @Override
+    public <C extends Facade> Collection<C> createFacade(Collection<? extends Resource> list, Class<C> type) {
+        URI context = null;
+        if(FacadeUtils.isFacadeAnnotationPresent(type, RDFContext.class)) {
+            String s_context = FacadeUtils.getFacadeAnnotation(type,RDFContext.class).value();
+            context = connection.getValueFactory().createURI(s_context);
+            log.debug("applying context {} for facade {} of {}", context, type.getSimpleName(), list);
+        }
+        return createFacade(list, type, context);
+    }
+
+    /**
+     * Create a collection of instances of C that facade the resources given in the collection passed as argument.
+     * The facade uses the {@link RDF} annotations provided to the getter or setter methods of C. The returned collection
+     * is of the same kind as the passed collection.
+     *
+     *
+     * @param list the collection containing the resources to facade
+     * @param type the facade type as a class
+     * @return
+     */
+    @Override
+    public <C extends Facade> Collection<C> createFacade(Collection<? extends Resource> list, Class<C> type, URI context) {
+        log.trace("createFacadeList: creating {} facade over {} content items",type.getName(),list.size());
+        LinkedList<C> result = new LinkedList<C>();
+        if(type.isAnnotationPresent(RDFFilter.class)) {
+            try {
+                if (!connection.isOpen()) { throw new IllegalStateException("the connection is already closed, cannot access triple-store."); }
+                if (!connection.isActive()) { throw new IllegalStateException("no active transaction, cannot access triple-store."); }
+
+                // if the RDFType annotation is present, filter out content items that are of the wrong type
+                LinkedList<URI> acceptable_types = new LinkedList<URI>();
+                if(FacadeUtils.isFacadeAnnotationPresent(type,RDFFilter.class)) {
+                    String[]        a_type = FacadeUtils.getFacadeAnnotation(type,RDFFilter.class).value();
+                    for(String s_type : a_type) {
+                        URI r_type = connection.getValueFactory().createURI(s_type);
+                        acceptable_types.add(r_type);
+                    }
+                }
+
+                // add facades for all content items to the result list
+                for(Resource item : list) {
+                    boolean accept = acceptable_types.size() == 0; // true for empty filter
+                    for(URI rdf_type : acceptable_types) {
+                        if(connection.hasStatement(item, RDF_TYPE, rdf_type, true)) {
+                            accept = true;
+                            log.trace("accepting resource {} because type matches ({})",item.toString(),rdf_type.stringValue());
+                            break;
+                        }
+                    }
+                    if(accept) {
+                        result.add(createFacade(item,type,context));
+                    }
+                }
+                log.debug("createFacadeList: filtered {} content items because they did not match the necessary criteria",list.size()-result.size());
+            } catch (RepositoryException ex) {
+                log.error("error while accessing RDF repository",ex);
+            }
+        } else {
+            // add facades for all content items to the result list
+            for(Resource item : list) {
+                result.add(createFacade(item,type,context));
+            }
+        }
+        return result;
+    }
+
+
+    /**
+     * Create an instance of C that facades the resource identified by the uri given as argument, using the {@link RDF}
+     * annotations provided to the getter or setter methods of C to map to properties of the resource in the triple
+     * store.
+     *
+     * @param uri  the uri of the resource to facade
+     * @param type the facade type as a class
+     * @param <C>  the facade type as a generic parameter
+     * @return
+     */
+    @Override
+    public <C extends Facade> C createFacade(String uri, Class<C> type) {
+        return createFacade(connection.getValueFactory().createURI(uri), type);
+    }
+
+    /**
+     * Check whether the resource fits into the facade.
+     *
+     *
+     * @param r the resource to check
+     * @param type the facade to check for
+     * @return <code>true</code> if the resource <code>r</code> fulfills all {@link RDFType} and
+     *         {@link RDFFilter} requirements of <code>type</code>
+     */
+    @Override
+    public <C extends Facade> boolean isFacadeable(Resource r, Class<C> type) {
+        return isFacadeable(r, type, null);
+    }
+
+    /**
+     * Check whether the resource fits into the facade.
+     *
+     *
+     * @param r the resource to check
+     * @param type the facade to check for
+     * @param context limit all checks to this context
+     * @return <code>true</code> if the resource <code>r</code> fulfills all {@link RDFType} and
+     *         {@link RDFFilter} requirements of <code>type</code>
+     */
+    @Override
+    public <C extends Facade> boolean isFacadeable(Resource r, Class<C> type, URI context) {
+        if (FacadeUtils.isFacadeAnnotationPresent(type, RDFType.class)) {
+            try {
+                if (!connection.isOpen()) { throw new IllegalStateException("the connection is already closed, cannot access triple store."); }
+                if (!connection.isActive()) { throw new IllegalStateException("no active transaction, cannot access triple-store."); }
+
+                String[] rdfTypes = FacadeUtils.getFacadeAnnotation(type, RDFType.class).value();
+                boolean facadeable = true;
+                for (String s_type : rdfTypes) {
+                    if(context != null) {
+                        facadeable &= connection.hasStatement(r, RDF_TYPE, connection.getValueFactory().createURI(s_type), true, context);
+                    } else {
+                        facadeable &= connection.hasStatement(r, RDF_TYPE, connection.getValueFactory().createURI(s_type), true);
+                    }
+                }
+                // also check for @RDFFilter
+                if (FacadeUtils.isFacadeAnnotationPresent(type, RDFFilter.class)) {
+                    String[] filterTypes = FacadeUtils.getFacadeAnnotation(type, RDFFilter.class).value();
+                    for (String s_type : filterTypes) {
+                        if(context != null) {
+                            facadeable &= connection.hasStatement(r, RDF_TYPE, connection.getValueFactory().createURI(s_type), true, context);
+                        } else {
+                            facadeable &= connection.hasStatement(r, RDF_TYPE, connection.getValueFactory().createURI(s_type), true);
+                        }
+                    }
+                }
+                return facadeable;
+            } catch(RepositoryException ex) {
+                log.error("error while accessing RDF repository",ex);
+            }
+        }
+        return false;
+    }
+}