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;
+ }
+}