org.mongojack.DbReferenceManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mongojack Show documentation
Show all versions of mongojack Show documentation
Maps MongoDB objects to POJOs using Jackson
The newest version!
package org.mongojack;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoCollection;
import org.bson.UuidRepresentation;
import org.bson.conversions.Bson;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
public class DbReferenceManager {
private final Map, JacksonMongoCollection>> referencedCollectionCache = new ConcurrentHashMap<>();
private final MongoClient mongoClient;
private final ObjectMapper objectMapper;
private final String defaultDatabaseName;
private final UuidRepresentation uuidRepresentation;
public DbReferenceManager(
final MongoClient mongoClient,
final ObjectMapper objectMapper,
final String defaultDatabaseName,
final UuidRepresentation uuidRepresentation
) {
this.mongoClient = mongoClient;
this.objectMapper = objectMapper;
this.defaultDatabaseName = defaultDatabaseName;
this.uuidRepresentation = uuidRepresentation;
}
public DbReferenceManager(
final MongoClient mongoClient,
final String defaultDatabaseName,
final UuidRepresentation uuidRepresentation
) {
this(mongoClient, null, defaultDatabaseName, uuidRepresentation);
}
/**
* Get a collection for loading a reference of the given type
*
* @param databaseName Name of the DB that holds the collection
* @param collectionName The name of the collection
* @param valueClass The type of the values in the collection
* @param The type of the values in the collection
* @return The collection
*/
@SuppressWarnings("unused")
public JacksonMongoCollection getReferenceCollection(
String databaseName, String collectionName, Class valueClass
) {
return getReferenceCollection(new JacksonCollectionKey<>(databaseName, collectionName, valueClass));
}
/**
* Get a collection for loading a reference of the given type
*
* @param collectionKey The key for the collection
* @param The type of values in the collection
* @return The collection
*/
@SuppressWarnings("unchecked")
public JacksonMongoCollection getReferenceCollection(
JacksonCollectionKey collectionKey
) {
return (JacksonMongoCollection) referencedCollectionCache.computeIfAbsent(
collectionKey,
(k) -> {
final String databaseName = Optional.ofNullable(k.getDatabaseName()).orElse(defaultDatabaseName);
return JacksonMongoCollection.builder()
.withObjectMapper(objectMapper)
.build(
(MongoCollection) mongoClient.getDatabase(databaseName).getCollection(k.getCollectionName()).withDocumentClass(k.getValueType()),
(Class) k.getValueType(),
uuidRepresentation
);
}
);
}
/**
* Fetches the underlying value for a single DBRef.
*
* @param ref The reference
* @param The type the ref points to.
* @param The type of ID the ref points to
* @return A ref, or null if the underlying value is nto found
*/
public R fetch(DBRef ref) {
return fetch(ref, null);
}
/**
* Fetches the underlying value for a single DBRef.
*
* @param ref The reference
* @param The type the ref points to.
* @param The type of ID the ref points to
* @param fields A Bson representing the projection to be used.
* @return A ref, or null if the underlying value is nto found
*/
public R fetch(DBRef ref, Bson fields) {
final JacksonMongoCollection collection = getReferenceCollection(ref.getCollectionKey());
return collection.find(collection.createIdQuery(ref.getId())).projection(fields).first();
}
/**
* Fetch a refs of dbrefs. This is more efficient than fetching one at
* a time.
*
* @param refs the refs to fetch
* @param The type of the reference
* @param The identifier type
* @return The refs of referenced objcets
*/
public List fetch(
Collection> refs
) {
return fetch(refs, null);
}
/**
* Fetch a refs of dbrefs. This is more efficient than fetching one at
* a time.
*
* @param refs the refs to fetch
* @param fields The fields to retrieve for each of the documents
* @param The type of the reference
* @param The identifier type
* @return The refs of referenced objects
*/
@SuppressWarnings("unchecked")
public List fetch(
Collection> refs,
Bson fields
) {
final Map, List> groupedIdentifiers = refs.stream()
.collect(Collectors.groupingBy(org.mongojack.DBRef::getCollectionKey, Collectors.mapping(DBRef::getId, Collectors.toList())));
return (List) groupedIdentifiers.entrySet().stream()
.map((entry) -> {
final JacksonMongoCollection> collection = getReferenceCollection(entry.getKey());
return collection.find(collection.createIdInQuery(entry.getValue())).projection(fields).into(new ArrayList<>());
})
.flatMap(List::stream)
.collect(Collectors.toList());
}
/**
* Register a collection so that it will be used (as opposed to an internally built one) when retrieving references.
*
* @param collection The collection to register
*/
@SuppressWarnings("unused")
public void registerCollection(JacksonMongoCollection> collection) {
referencedCollectionCache.put(collection.getCollectionKey(), collection);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy