Skip to content
This repository has been archived by the owner on Sep 20, 2021. It is now read-only.

Commit

Permalink
Added support for dynamic repositories.
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas Meingast committed Apr 13, 2014
1 parent 7f2d8fa commit b6cd09a
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 111 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package org.openrdf.spring;

import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.config.RepositoryConfig;
import org.openrdf.repository.config.RepositoryConfigException;
import org.openrdf.repository.config.RepositoryImplConfig;
import org.openrdf.repository.manager.RepositoryManager;
import org.springframework.beans.factory.DisposableBean;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* <p>{@link RepositoryManagerConnectionFactory} handles connections to a multiple corresponding
* {@link org.openrdf.repository.Repository}s managed by a {@link org.openrdf.repository.manager.RepositoryManager}
* and manages the transaction state (represented by {@link SesameTransactionObject}).</p>
*
* @author ameingast@gmail.com
*/
public class DynamicRepositoryManagerConnectionFactory implements SesameConnectionFactory, DisposableBean {
private final RepositoryManager repositoryManager;

private final RepositoryIdProvider repositoryIdProvider;

private final RepositoryImplConfig repositoryImplConfig;

private final Map<String, RepositoryConnectionFactory> repositoryConnectionFactoryMap;

/**
* <p>Creates a new {@link DynamicRepositoryManagerConnectionFactory} for the {@link org.openrdf.repository.Repository}
* identified by the provided {@link org.openrdf.spring.DynamicRepositoryManagerConnectionFactory.RepositoryIdProvider}
* in the {@link RepositoryManager} <code>repositoryManager</code>.</p>
* <p/>
* <p>For example, a <code>repositoryIdProvider</code> that fetches IDs based on a thread-local, user-specific variable
* can be used to create <i>dynamic</i> repositories for multiple users.</p>
*
* @param repositoryManager The {@link RepositoryManager} that holds the {@link org.openrdf.repository.Repository} to which connections
* will be opened.
* @param repositoryIdProvider The id of the {@link org.openrdf.repository.Repository} which is used by the {@link RepositoryManager} to
* identify the {@link org.openrdf.repository.Repository} to which connections will be opened is retrieved
* from via a call-back from <code>repositoryIdProvider</code>.
*/
public DynamicRepositoryManagerConnectionFactory(RepositoryManager repositoryManager,
RepositoryIdProvider repositoryIdProvider) {
this(repositoryManager, null, repositoryIdProvider);
}

public DynamicRepositoryManagerConnectionFactory(RepositoryManager repositoryManager,
RepositoryImplConfig repositoryImplConfig,
RepositoryIdProvider repositoryIdProvider) {
this.repositoryManager = repositoryManager;
this.repositoryImplConfig = repositoryImplConfig;
this.repositoryIdProvider = repositoryIdProvider;
this.repositoryConnectionFactoryMap = new ConcurrentHashMap<String, RepositoryConnectionFactory>();
}

/**
* @inheritDoc
*/
@Override
public RepositoryConnection getConnection() {
return getRepositoryConnectionFactory().getConnection();
}

/**
* @inheritDoc
*/
@Override
public void closeConnection() {
getRepositoryConnectionFactory().closeConnection();
}

/**
* @inheritDoc
*/
@Override
public SesameTransactionObject createTransaction() throws RepositoryException {
return getRepositoryConnectionFactory().createTransaction();
}

/**
* @inheritDoc
*/
@Override
public void endTransaction(boolean rollback) throws RepositoryException {
getRepositoryConnectionFactory().endTransaction(rollback);
}

/**
* @inheritDoc
*/
@Override
public SesameTransactionObject getLocalTransactionObject() {
return getRepositoryConnectionFactory().getLocalTransactionObject();
}

private RepositoryConnectionFactory getRepositoryConnectionFactory() {
String repositoryId = repositoryIdProvider.getRepositoryId();
RepositoryConnectionFactory repositoryConnectionFactory = repositoryConnectionFactoryMap.get(repositoryId);

if (repositoryConnectionFactory == null) {
repositoryConnectionFactory = initializeRepositoryConnectionFactory(repositoryId);
repositoryConnectionFactoryMap.put(repositoryId, repositoryConnectionFactory);
}

return repositoryConnectionFactory;
}

private RepositoryConnectionFactory initializeRepositoryConnectionFactory(String repositoryId) {
RepositoryConnectionFactory repositoryConnectionFactory = repositoryConnectionFactoryMap.get(repositoryId);

if (repositoryConnectionFactory != null) {
return repositoryConnectionFactory;
}

try {
Repository repository = repositoryManager.getRepository(repositoryId);

if (repository == null) {
if (repositoryImplConfig != null) {
RepositoryConfig repositoryConfig = new RepositoryConfig(repositoryId, repositoryImplConfig);

repositoryManager.addRepositoryConfig(repositoryConfig);
repository = repositoryManager.getRepository(repositoryId);
} else {
throw new SesameTransactionException("No such repository: " + repositoryId);
}
}

return new RepositoryConnectionFactory(repository);
} catch (RepositoryException e) {
throw new SesameTransactionException(e);
} catch (RepositoryConfigException e) {
throw new SesameTransactionException(e);
}
}

/**
* <p>Shuts down the associated {@link Repository}s if they were initialized before.</p>
*
* @throws Exception {@see Repository#shutDown}
*/
@Override
public void destroy() throws Exception {
for (RepositoryConnectionFactory repositoryConnectionFactory : repositoryConnectionFactoryMap.values()) {
repositoryConnectionFactory.destroy();
}
}

@Override
public String toString() {
return "DynamicRepositoryManagerConnectionFactory{" +
"repositoryManager=" + repositoryManager +
", repositoryIdProvider=" + repositoryIdProvider +
", repositoryConnectionFactoryMap=" + repositoryConnectionFactoryMap +
'}';
}

/**
* Call-back helper to provide runtime-dynamic repository-ids for
* {@link org.openrdf.spring.DynamicRepositoryManagerConnectionFactory}.
*/
public static interface RepositoryIdProvider {
String getRepositoryId();
}
}
123 changes: 12 additions & 111 deletions src/main/java/org/openrdf/spring/RepositoryManagerConnectionFactory.java
Original file line number Diff line number Diff line change
@@ -1,125 +1,26 @@
package org.openrdf.spring;

import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.config.RepositoryConfigException;
import org.openrdf.repository.manager.RepositoryManager;
import org.springframework.beans.factory.DisposableBean;

/**
* <p>{@link RepositoryManagerConnectionFactory} handles connections to a single {@link Repository} managed by a
* {@link RepositoryManager}. It also manages transaction state (represented by {@link SesameTransactionObject}).</p>
* <p/>
* <p>A {@link RepositoryManager} can hold multiple {@link Repository}s. To identify the {@link Repository} to
* which connections will be opened, a <i>repository-id</i> has to be provided as a constructor argument.</p>
* <p/>
*
* @author ameingast@gmail.com
* @see RepositoryConnectionFactory
*/
public class RepositoryManagerConnectionFactory implements SesameConnectionFactory, DisposableBean {
private final RepositoryManager repositoryManager;

private final String repositoryId;

private RepositoryConnectionFactory repositoryConnectionFactory;

public class RepositoryManagerConnectionFactory extends DynamicRepositoryManagerConnectionFactory {
/**
* <p>Creates a new {@link RepositoryManagerConnectionFactory} for the {@link Repository} identified by the
* provided <code>repositoryId</code> in the {@ink RepositoryManager} <code>repositoryManager</code>.</p>
* <p>Creates a new {@link RepositoryManagerConnectionFactory} for the {@link org.openrdf.repository.Repository} identified by the
* provided <code>repositoryId</code> in the {@link RepositoryManager} <code>repositoryManager</code>.</p>
*
* @param repositoryManager The {@link RepositoryManager} that holds the {@link Repository} to which connections
* @param repositoryManager The {@link RepositoryManager} that holds the {@link org.openrdf.repository.Repository} to which connections
* will be opened.
* @param repositoryId The id of the {@link Repository} which is used by the {@link RepositoryManager} to
* identify the {@link Repository} to which connections will be opened.
* @param repositoryId The id of the {@link org.openrdf.repository.Repository} which is used by the {@link RepositoryManager} to
* identify the {@link org.openrdf.repository.Repository} to which connections will be opened.
*/
public RepositoryManagerConnectionFactory(RepositoryManager repositoryManager, String repositoryId) {
this.repositoryManager = repositoryManager;
this.repositoryId = repositoryId;
}

/**
* @inheritDoc
*/
@Override
public RepositoryConnection getConnection() {
initializeRepository();
return repositoryConnectionFactory.getConnection();
}

/**
* @inheritDoc
*/
@Override
public void closeConnection() {
initializeRepository();
repositoryConnectionFactory.closeConnection();
}

/**
* @inheritDoc
*/
@Override
public SesameTransactionObject createTransaction() throws RepositoryException {
initializeRepository();
return repositoryConnectionFactory.createTransaction();
}

/**
* @inheritDoc
*/
@Override
public void endTransaction(boolean rollback) throws RepositoryException {
initializeRepository();
repositoryConnectionFactory.endTransaction(rollback);
}

/**
* @inheritDoc
*/
@Override
public SesameTransactionObject getLocalTransactionObject() {
initializeRepository();
return repositoryConnectionFactory.getLocalTransactionObject();
}

private void initializeRepository() {
if (repositoryConnectionFactory != null) {
return;
}

try {
Repository repository = repositoryManager.getRepository(repositoryId);
if (repository == null) {
throw new SesameTransactionException("No such repository: " + repositoryId);
public RepositoryManagerConnectionFactory(RepositoryManager repositoryManager, final String repositoryId) {
super(repositoryManager, new RepositoryIdProvider() {
@Override
public String getRepositoryId() {
return repositoryId;
}
repositoryConnectionFactory = new RepositoryConnectionFactory(repository);
} catch (RepositoryConfigException e) {
throw new SesameTransactionException(e);
} catch (RepositoryException e) {
throw new SesameTransactionException(e);
}
}

/**
* <p>Shuts down the associated {@link Repository} if it was initialized before.</p>
*
* @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='" + repositoryId + '\'' +
", repositoryConnectionFactory=" + repositoryConnectionFactory +
'}';
});
}
}

0 comments on commit b6cd09a

Please sign in to comment.