
com.enterprisemath.dao.big.MongoBigEntityDao Maven / Gradle / Ivy
package com.enterprisemath.dao.big;
import com.enterprisemath.dao.filter.Criterium;
import com.enterprisemath.dao.filter.Direction;
import com.enterprisemath.dao.filter.Filter;
import com.enterprisemath.dao.filter.Operator;
import com.enterprisemath.dao.filter.Order;
import com.enterprisemath.utils.DomainUtils;
import com.enterprisemath.utils.ValidationUtils;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.bson.BsonDocument;
import org.bson.BsonInt32;
import org.bson.Document;
import org.bson.conversions.Bson;
/**
* Big entity data access layer implemented with MongoDB.
*
* @author radek.hecl
*/
public class MongoBigEntityDao implements BigEntityDao {
/**
* Builder object.
*/
public static class Builder {
/**
* Client for the MongoDB.
*/
private MongoClient mongoClient;
/**
* Database name.
*/
private String databaseName;
/**
* Mapper from entity type to the collection.
*/
private TypeCollectionMapper typeCollectionMapper;
/**
* Sets client for MongoDB.
*
* @param mongoClient client
* @return this instance
*/
public Builder setMongoClient(MongoClient mongoClient) {
this.mongoClient = mongoClient;
return this;
}
/**
* Sets database name.
*
* @param databaseName database name
* @return this instance
*/
public Builder setDatabaseName(String databaseName) {
this.databaseName = databaseName;
return this;
}
/**
* Sets mapper from entity type to the collection.
*
* @param typeCollectionMapper mapper from entity type to the collection
* @return this instance
*/
public Builder setTypeCollectionMapper(TypeCollectionMapper typeCollectionMapper) {
this.typeCollectionMapper = typeCollectionMapper;
return this;
}
/**
* Builds the result object.
*
* @return created object
*/
public MongoBigEntityDao build() {
return new MongoBigEntityDao(this);
}
}
/**
* Client for the MongoDB.
*/
private MongoClient mongoClient;
/**
* Database name.
*/
private String databaseName;
/**
* Mapper from entity type to the collection.
*/
private TypeCollectionMapper typeCollectionMapper;
/**
* Creates new instance.
*
* @param builder builder object
*/
public MongoBigEntityDao(Builder builder) {
mongoClient = builder.mongoClient;
databaseName = builder.databaseName;
typeCollectionMapper = builder.typeCollectionMapper;
guardInvariants();
}
/**
* Guards this object to be consistent. Throws exception if this is not the case.
*/
private void guardInvariants() {
ValidationUtils.guardNotNull(mongoClient, "mongoClient cannot be null");
ValidationUtils.guardNotEmpty(databaseName, "databaseName cannot be empty");
ValidationUtils.guardNotNull(typeCollectionMapper, "typeCollectionMapper cannot be null");
}
@Override
public void insertBigEntity(String type, BigEntity entity, InsertOptions options) {
MongoCollection collection = getCollection(type);
Map vals = DomainUtils.softCopyMap(entity.getFields());
vals.put("_id", entity.getCode());
collection.insertOne(new Document(vals));
}
@Override
public void insertBigEntities(String type, List entities, InsertOptions options) {
for (BigEntity ent : entities) {
insertBigEntity(type, ent, options);
}
}
@Override
public BigEntityIterator selectBigEntities(String type, Filter filter, Set fields, SelectOptions options) {
MongoCollection collection = getCollection(type);
BsonDocument projection = new BsonDocument();
for (String field : fields) {
projection.append(field, new BsonInt32(1));
}
BsonDocument sort = new BsonDocument();
for (Order order : filter.getOrders()) {
String fld = order.getColumn();
if (fld.equals("code")) {
fld = "_id";
}
if (order.getDirection().equals(Direction.ASCENDANT)) {
sort.append(fld, new BsonInt32(1));
}
else if (order.getDirection().equals(Direction.DESCENDANT)) {
sort.append(fld, new BsonInt32(-1));
}
else {
throw new RuntimeException("unknown order direction: " + order);
}
}
FindIterable mongoIterable = collection.find(convertCriteria(filter.getCriteria())).
projection(projection).
sort(sort);
if (filter.getFrom() > 0) {
mongoIterable.skip((int) filter.getFrom());
}
if (filter.getLimit() != null) {
mongoIterable.limit(filter.getLimit());
}
return new EntIterator(mongoIterable.iterator(), fields);
}
@Override
public long countBigEntities(String type, List> criteria, CountOptions options) {
MongoCollection collection = getCollection(type);
return collection.count(convertCriteria(criteria));
}
@Override
public void updateBigEntity(String type, String code, BigEntityUpdate update, UpdateOptions options) {
if (update.getUpdateFields().isEmpty() && update.getDropFields().isEmpty()) {
return;
}
MongoCollection collection = getCollection(type);
List> crit = Arrays.asList(Criterium.createEqual("code", code));
Document mdbupdate = new Document();
if (!update.getUpdateFields().isEmpty()) {
Document setUpdate = new Document();
for (String fld : update.getUpdateFields().keySet()) {
setUpdate.append(fld, update.getUpdateFields().get(fld));
}
mdbupdate.append("$set", setUpdate);
}
if (!update.getDropFields().isEmpty()) {
Document unsetUpdate = new Document();
for (String fld : update.getDropFields()) {
unsetUpdate.append(fld, 1);
}
mdbupdate.append("$unset", unsetUpdate);
}
collection.updateOne(convertCriteria(crit), mdbupdate);
}
@Override
public void deleteBigEntity(String type, String code, DeleteOptions options) {
MongoCollection collection = getCollection(type);
List> crit = Arrays.asList(Criterium.createEqual("code", code));
collection.deleteOne(convertCriteria(crit));
}
/**
* Converts criteria to BSON object.
*
* @param criteria criteria
* @return BSON criteria object
*/
private Bson convertCriteria(List> criteria) {
if (criteria.isEmpty()) {
return new BsonDocument();
}
List andCrits = new ArrayList();
for (Criterium crit : criteria) {
Object value = crit.getValue();
if (value != null) {
if (value instanceof Enum>) {
value = ((Enum>) value).name();
}
else if (value instanceof Collection>) {
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy