
org.revenj.LocatorDataContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of revenj-core Show documentation
Show all versions of revenj-core Show documentation
DSL Platform compatible backend (https://dsl-platform.com)
The newest version!
package org.revenj;
import org.revenj.extensibility.Container;
import org.revenj.patterns.*;
import org.revenj.patterns.DataSource;
import rx.Observable;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
final class LocatorDataContext implements UnitOfWork {
private final Container scope;
private ConcurrentHashMap, SearchableRepository> searchRepositories;
private ConcurrentHashMap, Repository> lookupRepositories;
private ConcurrentHashMap, PersistableRepository> persistableRepositories;
private ConcurrentHashMap, Repository> historyRepositories;
private ConcurrentHashMap, DomainEventStore> eventStores;
private GlobalEventStore globalEventStore;
private DataChangeNotification changes;
private final boolean manageConnection;
private final Connection connection;
private boolean hasChanges;
private boolean closed;
LocatorDataContext(Container scope, boolean manageConnection, Connection connection) {
this.scope = scope;
this.manageConnection = manageConnection;
this.connection = connection;
}
static DataContext asDataContext(Container container) {
return new LocatorDataContext(container, false, null);
}
static DataContext asDataContext(Container container, Connection connection) {
Container scope = container.createScope();
scope.registerInstance(Connection.class, connection, false);
return new LocatorDataContext(scope, false, connection);
}
static UnitOfWork asUnitOfWork(Container container) {
javax.sql.DataSource dataSource = container.resolve(javax.sql.DataSource.class);
java.sql.Connection connection = null;
try {
connection = dataSource.getConnection();
connection.setAutoCommit(false);
} catch (SQLException e) {
try {
if (connection != null) connection.close();
} catch (SQLException ignore) {
}
try {
connection = dataSource.getConnection();
connection.setAutoCommit(false);
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
Container scope = container.createScope();
scope.registerInstance(Connection.class, connection, false);
return new LocatorDataContext(scope, true, connection);
}
private SearchableRepository getSearchableRepository(Class manifest) {
if (closed) throw new RuntimeException("Unit of work has been closed");
if (searchRepositories == null) searchRepositories = new ConcurrentHashMap<>();
return searchRepositories.computeIfAbsent(manifest, clazz ->
{
if (persistableRepositories != null) {
PersistableRepository repository = persistableRepositories.get(manifest);
if (repository != null) return repository;
}
try {
return (SearchableRepository) scope.resolve(Utils.makeGenericType(SearchableRepository.class, manifest));
} catch (ReflectiveOperationException ex) {
throw new RuntimeException("Repository is not registered for: " + manifest, ex);
}
});
}
private Repository getLookupRepository(Class> manifest) {
if (closed) throw new RuntimeException("Unit of work has been closed");
if (lookupRepositories == null) lookupRepositories = new ConcurrentHashMap<>();
return lookupRepositories.computeIfAbsent(manifest, clazz ->
{
if (persistableRepositories != null) {
PersistableRepository repository = persistableRepositories.get(manifest);
if (repository != null) return repository;
}
try {
return (Repository) scope.resolve(Utils.makeGenericType(Repository.class, manifest));
} catch (ReflectiveOperationException ex) {
throw new RuntimeException("Repository is not registered for: " + manifest, ex);
}
});
}
private Repository getHistoryRepository(Class> manifest) {
if (closed) throw new RuntimeException("Unit of work has been closed");
if (historyRepositories == null) historyRepositories = new ConcurrentHashMap<>();
return historyRepositories.computeIfAbsent(manifest, clazz ->
{
try {
return (Repository) scope.resolve(Utils.makeGenericType(Repository.class, Utils.makeGenericType(History.class, manifest)));
} catch (ReflectiveOperationException ex) {
throw new RuntimeException("Repository is not registered for: " + manifest, ex);
}
});
}
private PersistableRepository getPersistableRepository(Class> manifest) {
if (closed) throw new RuntimeException("Unit of work has been closed");
if (persistableRepositories == null) persistableRepositories = new ConcurrentHashMap<>();
return persistableRepositories.computeIfAbsent(manifest, clazz ->
{
try {
return (PersistableRepository) scope.resolve(Utils.makeGenericType(PersistableRepository.class, manifest));
} catch (ReflectiveOperationException ex) {
throw new RuntimeException("Repository is not registered for: " + manifest, ex);
}
});
}
private DomainEventStore getEventStore(Class> manifest) {
if (closed) throw new RuntimeException("Unit of work has been closed");
if (eventStores == null) eventStores = new ConcurrentHashMap<>();
return eventStores.computeIfAbsent(manifest, clazz ->
{
try {
return (DomainEventStore) scope.resolve(Utils.makeGenericType(SearchableRepository.class, manifest));
} catch (ReflectiveOperationException ex) {
throw new RuntimeException("Domain event store is not registered for: " + manifest, ex);
}
});
}
@Override
public Optional find(Class manifest, String uri) {
return getLookupRepository(manifest).find(uri);
}
@Override
public List find(Class manifest, Collection uris) {
return getLookupRepository(manifest).find(uris);
}
@Override
public Query query(Class manifest, Specification filter) {
return getSearchableRepository(manifest).query(filter);
}
@Override
public List search(Class manifest, Specification filter, Integer limit, Integer offset) {
return getSearchableRepository(manifest).search(filter, limit, offset);
}
@Override
public long count(Class manifest, Specification filter) {
return getSearchableRepository(manifest).count(filter);
}
@Override
public boolean exists(Class manifest, Specification filter) {
return getSearchableRepository(manifest).exists(filter);
}
@Override
public void create(Collection aggregates) throws IOException {
if (aggregates.size() == 0) {
return;
}
Class> manifest = aggregates.iterator().next().getClass();
getPersistableRepository(manifest).insert(aggregates);
hasChanges = true;
}
@Override
public void updatePairs(Collection> pairs) throws IOException {
if (pairs.size() == 0) {
return;
}
Class> manifest = pairs.iterator().next().getValue().getClass();
getPersistableRepository(manifest).persist(null, pairs, null);
hasChanges = true;
}
@Override
public void delete(Collection aggregates) throws IOException {
if (aggregates.size() == 0) {
return;
}
Class> manifest = aggregates.iterator().next().getClass();
getPersistableRepository(manifest).delete(aggregates);
hasChanges = true;
}
@Override
public void submit(Collection events) {
if (events.size() == 0) {
return;
}
Class> manifest = events.iterator().next().getClass();
getEventStore(manifest).submit(events);
hasChanges = true;
}
@Override
public void queue(Collection events) {
if (globalEventStore == null) {
globalEventStore = scope.resolve(GlobalEventStore.class);
}
for (T e : events) {
globalEventStore.queue(e);
}
}
@Override
public T populate(Report report) {
return report.populate(scope);
}
@Override
public List> history(Class manifest, Collection uris) {
return getHistoryRepository(manifest).find(uris);
}
@Override
public Observable> track(Class manifest) {
if (changes == null) changes = scope.resolve(DataChangeNotification.class);
return changes.track(manifest);
}
@Override
public void commit() {
if (hasChanges) {
try {
connection.commit();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
hasChanges = false;
}
@Override
public void rollback() {
try {
connection.rollback();
} catch (SQLException e) {
throw new RuntimeException(e);
}
hasChanges = false;
}
@Override
public void close() throws IOException {
if (closed) {
return;
}
if (connection != null && manageConnection) {
if (hasChanges) {
rollback();
}
try {
connection.setAutoCommit(true);
connection.close();
} catch (SQLException e) {
throw new IOException(e);
}
}
if (connection != null) {
closed = true;
try {
scope.close();
} catch (Exception e) {
throw new IOException(e);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy