diff --git a/README.markdown b/README.markdown
index 9abb91a..2b1913a 100644
--- a/README.markdown
+++ b/README.markdown
@@ -2,15 +2,16 @@
[![Build Status](https://api.travis-ci.org/ameingast/sesame-spring.png)](https://travis-ci.org/ameingast/sesame-spring)
-
-Sesame Spring provides Spring integration for the Openrdf/Sesame library.
+Sesame Spring provides Spring integration for the OpenRDF/Sesame library.
## Spring Transactions
The library provides a simple PlatformTransactionManager with thread-local scope for Sesame.
-## Usage
+## Examples
+
+### Creating a transaction manager for a single repository
-Wiring up a simple in-memory repository to the transaction manager:
+You should use this approach, if you only deal with a single repository.
```xml
{@link RepositoryConnectionFactory} handles connections to the corresponding {@link Repository} and manages
+ * {@link RepositoryConnectionFactory} handles connections to a single corresponding {@link Repository} and manages
* the transaction state (represented by {@link SesameTransactionObject}). This class provides methods to access transactional connections from the outside and is typically
- * the only class that library users interact with. This class provides methods to access transactional connections from the outside and is typically the
+ * only class that library users interact with. Creates a new {@link RepositoryConnectionFactory} for the provided {@link Repository}. Retrieves the connection for the current transaction. This method may be called at any time as long as a
- * transaction is active and will return the same connection-handle to the repository in the same
- * transaction context (which is thread-local). Closes the connection and cleans up the (thread-local) state for the current transaction. This method should not be called manually, since the connection is managed by the
- * {@link SesameTransactionManager}. Shuts down the {@link Repository} if it was initialized before. Creates a new {@link SesameTransactionObject}, connects the created object
- * to the corresponding {@link Repository} and disables auto-commit on the connection. This method should only be called by {@link SesameTransactionManager}. Ends the active transaction by either rolling-back or committing the changes to the {@link Repository}
- * depending on the rollback-flag. This method should only be called by {@link SesameTransactionManager}. Retrieves the current transaction state. This method should only be called by {@link SesameTransactionManager}. Shuts down the associated {@link Repository} if it was initialized before. {@link RepositoryManagerConnectionFactory} handles connections to a {@link RepositoryManager} and manages
- * the transaction state (represented by {@link SesameTransactionObject}). {@link RepositoryManagerConnectionFactory} handles connections to a single {@link Repository} managed by a
+ * {@link RepositoryManager}. It also manages transaction state (represented by {@link SesameTransactionObject}). The {@link RepositoryManager}'s repository-id is set via the property
- * {@link RepositoryManagerConnectionFactory#setLocalRepositoryId(String)}/
- * {@link org.openrdf.spring.RepositoryManagerConnectionFactory#getLocalRepositoryId()}.
+ * A {@link RepositoryManager} can hold multiple {@link Repository}s. To identify the {@link Repository} to
+ * which connections will be opened, a repository-id has to be provided as a constructor argument.
- *
+ * @inheritDoc
*/
@Override
public RepositoryConnection getConnection() {
@@ -58,17 +56,7 @@ public RepositoryConnection getConnection() {
}
/**
- *
- *
+ * @inheritDoc
*/
@Override
public void closeConnection() {
@@ -105,29 +93,7 @@ public void closeConnection() {
}
/**
- * true
the current transaction is rolled back, if false
the pending
- * changes on the connection are committed to the {@link Repository}.
- * @throws RepositoryException if
- *
- *
- * @throws SesameTransactionException if
- *
- *
+ * @inheritDoc
*/
@Override
public void endTransaction(boolean rollback) throws RepositoryException {
@@ -181,17 +131,25 @@ public void endTransaction(boolean rollback) throws RepositoryException {
}
/**
- *
This class provides methods to access transactional connections from the outside and is typically - * the only class that library users interact with.
* * @author ameingast@gmail.com + * @see RepositoryConnectionFactory */ -public class RepositoryManagerConnectionFactory implements SesameConnectionFactory { +public class RepositoryManagerConnectionFactory implements SesameConnectionFactory, DisposableBean { private final RepositoryManager repositoryManager; - private ThreadLocalCreates a new {@link RepositoryManagerConnectionFactory} for the {@link Repository} identified by the
+ * provided repositoryId
in the {@ink RepositoryManager} repositoryManager
.
Shuts down the associated {@link Repository} if it was initialized before.
+ * + * @throws Exception {@see Repository#shutDown} + */ + @Override + public void destroy() throws Exception { + if (repositoryConnectionFactory != null) { + repositoryConnectionFactory.destroy(); + } } @Override public String toString() { return "RepositoryManagerConnectionFactory{" + "repositoryManager=" + repositoryManager + - ", repositoryId='" + localRepositoryId + '\'' + - ", connectionFactory=" + localConnectionFactory + + ", repositoryId='" + repositoryId + '\'' + + ", repositoryConnectionFactory=" + repositoryConnectionFactory + '}'; } } diff --git a/src/main/java/org/openrdf/spring/SesameConnectionFactory.java b/src/main/java/org/openrdf/spring/SesameConnectionFactory.java index 8c882c6..8f5a349 100644 --- a/src/main/java/org/openrdf/spring/SesameConnectionFactory.java +++ b/src/main/java/org/openrdf/spring/SesameConnectionFactory.java @@ -2,15 +2,88 @@ import org.openrdf.repository.RepositoryConnection; import org.openrdf.repository.RepositoryException; +import org.springframework.beans.factory.DisposableBean; -public interface SesameConnectionFactory { - RepositoryConnection getConnection(); +/** + *{@link SesameConnectionFactory} handles connections to a single corresponding {@link org.openrdf.repository.Repository} and manages + * the transaction state (represented by {@link SesameTransactionObject}).
+ * + * @author ameingast@gmail.com + */ +public interface SesameConnectionFactory extends DisposableBean { + /** + *Retrieves the connection for the current transaction. This method may be called at any time as long as a + * transaction is active and it will return the same connection-handle to the repository in the current transaction + * context (which is thread-local).
+ * + * @return the {@link RepositoryConnection} + * + * @throws SesameTransactionException if + *Closes the connection and cleans up the (thread-local) state for the current transaction.
+ * + *This method should not be called manually, but rather by the associated {@link + * SesameTransactionManager} which handles the current transaction.
+ * + * @throws SesameTransactionException if + *Creates a new {@link SesameTransactionObject}, connects the created object to the corresponding {@link + * org.openrdf.repository.Repository} and disables auto-commit on the connection.
+ * + *This method should not be called manually, but rather by the associated {@link + * SesameTransactionManager} which handles the current transaction.
+ * + * @return the created transaction object representing the transaction state. + * + * @throws RepositoryException if the transaction object could not be created. + */ SesameTransactionObject createTransaction() throws RepositoryException; + /** + *Ends the active transaction by either rolling-back or committing the changes to the associated + * {@link org.openrdf.repository.Repository} depending on the rollback-flag.
+ * + *This method should not be called manually, but rather by the associated {@link + * SesameTransactionManager} which handles the current transaction.
+ * + * @param rollback iftrue
the current transaction is rolled back, if false
the pending
+ * changes on the connection are committed to the {@link org.openrdf.repository.Repository}.
+ *
+ * @throws RepositoryException if
+ * Retrieves the current (thread-local) transaction state.
+ * + *This method should not be called manually, but rather by the associated {@link + * SesameTransactionManager} which handles the current transaction.
+ * + * @return The current transaction state in form of a {@link SesameTransactionObject}. + */ SesameTransactionObject getLocalTransactionObject(); } diff --git a/src/main/java/org/openrdf/spring/SesameTransactionManager.java b/src/main/java/org/openrdf/spring/SesameTransactionManager.java index 9bf9fcc..af7bcc9 100644 --- a/src/main/java/org/openrdf/spring/SesameTransactionManager.java +++ b/src/main/java/org/openrdf/spring/SesameTransactionManager.java @@ -10,18 +10,23 @@ /** *{@link SesameTransactionManager} manages the transaction lifecycle of a {@link SesameTransactionObject}.
* - *The transaction-manager works in co-operation with {@link SesameConnectionFactory}. - * The manager is operated by Spring and steers transactions.
+ *The transaction-manager works in co-operation with {@link SesameConnectionFactory}. The manager is operated by + * Spring and steers transactions.
*It creates and destroys the transaction-state which is held by the {@link SesameConnectionFactory}.
* - *When the transaction finishes, the changes are either committed or rolled back by - * the Spring framework.
+ *When the transaction finishes, the changes are either committed or rolled back by Spring.
* * @author ameingast@gmail.com */ public class SesameTransactionManager extends AbstractPlatformTransactionManager { private final SesameConnectionFactory sesameConnectionFactory; + /** + *Creates a new {@link SesameTransactionManager} for the provided {@link SesameConnectionFactory} which + * handles connection-management to a single {@link org.openrdf.repository.Repository}.
+ * + * @param sesameConnectionFactory The {@link SesameConnectionFactory} providing connections for the repository. + */ public SesameTransactionManager(SesameConnectionFactory sesameConnectionFactory) { this.sesameConnectionFactory = sesameConnectionFactory; } @@ -47,37 +52,35 @@ protected Object doGetTransaction() throws TransactionException { } /** - * {@see AbstractPlatformTransactionManager#doCommit} + * {@see AbstractPlatformTransactionManager#isExistingTransaction} */ @Override - protected void doCommit(DefaultTransactionStatus status) throws TransactionException { - SesameTransactionObject sesameTransactionObject = (SesameTransactionObject) status.getTransaction(); + protected boolean isExistingTransaction(Object transaction) throws TransactionException { + SesameTransactionObject sesameTransactionObject = (SesameTransactionObject) transaction; - try { - sesameConnectionFactory.endTransaction(sesameTransactionObject.isRollbackOnly()); - } catch (RepositoryException e) { - throw new TransactionSystemException(e.getMessage(), e); - } + return sesameTransactionObject.isExisting(); } /** - * {@see AbstractPlatformTransactionManager#isExistingTransaction} + * {@see AbstractPlatformTransactionManager#doBegin} */ @Override - protected boolean isExistingTransaction(Object transaction) throws TransactionException { - SesameTransactionObject sesameTransactionObject = (SesameTransactionObject) transaction; + protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException { - return sesameTransactionObject.isExisting(); } /** - * {@see AbstractPlatformTransactionManager#doSetRollbackOnly} + * {@see AbstractPlatformTransactionManager#doCommit} */ @Override - public void doSetRollbackOnly(DefaultTransactionStatus status) throws TransactionException { + protected void doCommit(DefaultTransactionStatus status) throws TransactionException { SesameTransactionObject sesameTransactionObject = (SesameTransactionObject) status.getTransaction(); - sesameTransactionObject.setRollbackOnly(true); + try { + sesameConnectionFactory.endTransaction(sesameTransactionObject.isRollbackOnly()); + } catch (RepositoryException e) { + throw new TransactionSystemException(e.getMessage(), e); + } } /** @@ -93,19 +96,21 @@ protected void doRollback(DefaultTransactionStatus status) throws TransactionExc } /** - * {@see AbstractPlatformTransactionManager#doCleanupAfterCompletion} + * {@see AbstractPlatformTransactionManager#doSetRollbackOnly} */ @Override - public void doCleanupAfterCompletion(Object transaction) { - sesameConnectionFactory.closeConnection(); + public void doSetRollbackOnly(DefaultTransactionStatus status) throws TransactionException { + SesameTransactionObject sesameTransactionObject = (SesameTransactionObject) status.getTransaction(); + + sesameTransactionObject.setRollbackOnly(true); } /** - * {@see AbstractPlatformTransactionManager#doBegin} + * {@see AbstractPlatformTransactionManager#doCleanupAfterCompletion} */ @Override - protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException { - + public void doCleanupAfterCompletion(Object transaction) { + sesameConnectionFactory.closeConnection(); } @Override diff --git a/src/main/java/org/openrdf/spring/package-info.java b/src/main/java/org/openrdf/spring/package-info.java index 1a6dc91..8027f31 100644 --- a/src/main/java/org/openrdf/spring/package-info.java +++ b/src/main/java/org/openrdf/spring/package-info.java @@ -1,14 +1,14 @@ /** *Sesame-Spring provides a simple Spring {@link org.springframework.transaction.PlatformTransactionManager} for - * sesame {@link org.openrdf.repository.Repository}s.
- * + * sesame {@link org.openrdf.repository.Repository}s and {@link org.openrdf.repository.manager.RepositoryManager}s. + * *The transaction scope is thread-local.
- * + * *{@link org.openrdf.repository.RepositoryConnection}s to the underlying repository are automatically * opened when the transaction begins and they are always closed when the transaction terminates.
- * + * *Nested transactions are not supported; in case of re-opening a transaction, the current transaction will - * be re-used instead.
+ * be re-used. * * @author ameingast@gmail.com */ diff --git a/src/test/java/org/openrdf/spring/RepositoryManagerTest.java b/src/test/java/org/openrdf/spring/RepositoryConnectionFactoryTest.java similarity index 97% rename from src/test/java/org/openrdf/spring/RepositoryManagerTest.java rename to src/test/java/org/openrdf/spring/RepositoryConnectionFactoryTest.java index d51fb09..33835d0 100644 --- a/src/test/java/org/openrdf/spring/RepositoryManagerTest.java +++ b/src/test/java/org/openrdf/spring/RepositoryConnectionFactoryTest.java @@ -20,8 +20,8 @@ import java.util.Arrays; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations = "/applicationContext.xml") -public class RepositoryManagerTest { +@ContextConfiguration(locations = "/repositoryTestContext.xml") +public class RepositoryConnectionFactoryTest { @Autowired protected SesameConnectionFactory repositoryConnectionFactory; diff --git a/src/test/java/org/openrdf/spring/SesameResultHandlers.java b/src/test/java/org/openrdf/spring/SesameResultHandlers.java index 411a13a..36b102f 100644 --- a/src/test/java/org/openrdf/spring/SesameResultHandlers.java +++ b/src/test/java/org/openrdf/spring/SesameResultHandlers.java @@ -1,17 +1,8 @@ package org.openrdf.spring; -import org.openrdf.query.GraphQueryResult; import org.openrdf.query.TupleQueryResult; public class SesameResultHandlers { - public static interface TupleQueryResultHandler { - void handle(TupleQueryResult tupleQueryResult) throws Exception; - } - - public static interface GraphQueryResultHandler { - void handle(GraphQueryResult graphQueryResult) throws Exception; - } - public static void withTupleQueryResult(TupleQueryResult tupleQueryResult, TupleQueryResultHandler tupleQueryResultHandler) throws Exception { try { @@ -21,12 +12,7 @@ public static void withTupleQueryResult(TupleQueryResult tupleQueryResult, } } - public static void withGraphQueryResult(GraphQueryResult graphQueryResult, - GraphQueryResultHandler graphQueryResultHandler) throws Exception { - try { - graphQueryResultHandler.handle(graphQueryResult); - } finally { - graphQueryResult.close(); - } + public static interface TupleQueryResultHandler { + void handle(TupleQueryResult tupleQueryResult) throws Exception; } } diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties index 4384abf..e0c521e 100644 --- a/src/test/resources/log4j.properties +++ b/src/test/resources/log4j.properties @@ -1,4 +1,4 @@ -logformat=[%d{yyyy-MM-dd HH:mm:ss,SSS}] [%p] %c: %m%n +logformat=[%d{yyyy-MM-dd HH:mm:ss,SSS}] [%t] [%p] %c: %m%n log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out @@ -8,4 +8,7 @@ log4j.appender.stdout.layout.ConversionPattern=${logformat} log4j.logger.org.springframework=WARN, stdout log4j.additivity.org.springframework=false +log4j.logger.org.openrdf.spring=TRACE, stdout +log4j.additivity.org.openrdf.spring=false + log4j.rootLogger=INFO, stdout \ No newline at end of file diff --git a/src/test/resources/applicationContext.xml b/src/test/resources/repositoryTestContext.xml similarity index 88% rename from src/test/resources/applicationContext.xml rename to src/test/resources/repositoryTestContext.xml index 88432a7..20610c9 100644 --- a/src/test/resources/applicationContext.xml +++ b/src/test/resources/repositoryTestContext.xml @@ -26,11 +26,8 @@