All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.n2oapp.framework.boot.mongodb.MongoDbDataProviderEngine Maven / Gradle / Ivy
package net.n2oapp.framework.boot.mongodb;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.BasicDBObject;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import lombok.Setter;
import net.n2oapp.framework.api.PlaceHoldersResolver;
import net.n2oapp.framework.api.StringUtils;
import net.n2oapp.framework.api.data.MapInvocationEngine;
import net.n2oapp.framework.api.exception.N2oException;
import net.n2oapp.framework.api.metadata.dataprovider.N2oMongoDbDataProvider;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Filters.in;
import static com.mongodb.client.model.Projections.include;
import static com.mongodb.client.model.Sorts.*;
import static net.n2oapp.framework.api.PlaceHoldersResolver.replaceOptional;
/**
* Сервис для выполнения запросов к MongoDb
*/
@Setter
public class MongoDbDataProviderEngine implements MapInvocationEngine {
public static final String SELECT = "select";
public static final String SORTING = "sorting";
public static final String FILTERS = "filters";
@Autowired
private MongoClient mongoClient;
@Value("${n2o.engine.mongodb.database_name:}")
private String databaseName;
@Value("${spring.data.mongodb.database:}")
private String springDatabaseName;
private ObjectMapper mapper;
private static final Function defaultSuffixIdx = str -> {
if (str.startsWith("."))
return 0;
String[] ends = str.split("[^A-Za-z0-9_\\.]");
return ends[0].replaceAll("\\.+$", "").length();
};
public MongoDbDataProviderEngine(ObjectMapper objectMapper) {
this.mapper = objectMapper;
}
@Override
public Object invoke(N2oMongoDbDataProvider invocation, Map inParams) {
String dbName = invocation.getDatabaseName() != null ? invocation.getDatabaseName() : !StringUtils.isEmpty(databaseName) ? databaseName : springDatabaseName;
if (invocation.getConnectionUrl() == null) {
MongoCollection collection = mongoClient
.getDatabase(dbName)
.getCollection(invocation.getCollectionName());
return execute(invocation, inParams, collection);
} else {
ConnectionString connectionString = new ConnectionString(invocation.getConnectionUrl());
MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.build();
try (MongoClient mongoClient = MongoClients.create(mongoClientSettings)) {
MongoCollection collection = mongoClient
.getDatabase(dbName)
.getCollection(invocation.getCollectionName());
return execute(invocation, inParams, collection);
}
}
}
@Override
public Class extends N2oMongoDbDataProvider> getType() {
return N2oMongoDbDataProvider.class;
}
private Object execute(N2oMongoDbDataProvider invocation, Map inParams, MongoCollection collection) {
if (invocation.getOperation() == null)
return find(inParams, collection);
switch (invocation.getOperation()) {
case find:
return find(inParams, collection);
case insertOne:
return insertOne(inParams, collection);
case updateOne:
return updateOne(inParams, collection);
case deleteOne:
return deleteOne(inParams, collection);
case deleteMany:
return deleteMany(inParams, collection);
case countDocuments:
return countDocument(inParams, collection);
default:
throw new N2oException("Unsupported invocation's operation");
}
}
private Object find(Map inParams, MongoCollection collection) {
Bson order = getSorting(inParams);
Bson projection = inParams.containsKey(SELECT) && inParams.get(SELECT) != null ?
include((List) inParams.get(SELECT)) : null;
int limit = inParams.containsKey("limit") ? (int) inParams.get("limit") : 10;
int offset = inParams.containsKey("offset") ? (int) inParams.get("offset") : 0;
Bson filter = getFilters(inParams);
if (filter == null)
filter = new Document();
List result = new ArrayList<>();
for (Document document : collection.find(filter).projection(projection).sort(order).limit(limit).skip(offset))
result.add(document);
return result;
}
private Integer countDocument(Map inParams, MongoCollection collection) {
Bson filter = getFilters(inParams);
if (filter == null)
filter = new Document();
return (int) collection.countDocuments(filter);
}
private Bson getSorting(Map inParams) {
Bson order = null;
if (inParams.containsKey(SORTING) && inParams.get(SORTING) != null) {
List sortings = (List) inParams.get(SORTING);
List sortFields = new ArrayList<>();
for (String sort : sortings) {
String[] str = sort.replace(" ", "").split(":");
if ("desc".equals(inParams.get(str[1])))
sortFields.add(descending(str[0]));
else
sortFields.add(ascending(str[0]));
}
order = orderBy(sortFields);
}
return order;
}
private Bson getFilters(Map inParams) {
Bson filters = null;
if (inParams.containsKey(FILTERS) && inParams.get(FILTERS) != null) {
PlaceHoldersResolver resolver = new PlaceHoldersResolver("#", "", false, defaultSuffixIdx);
List filterList = (List) inParams.get(FILTERS);
List filtersByFields = new ArrayList<>();
for (String filter : filterList) {
Bson f = BasicDBObject.parse(resolver.resolve(filter, PlaceHoldersResolver.replaceByJson(replaceOptional(inParams::get), mapper)));
filtersByFields.add(f);
}
filters = filtersByFields.isEmpty() ? null : Filters.and(filtersByFields);
}
return filters;
}
private Object insertOne(Map inParams, MongoCollection collection) {
Document document = new Document(inParams);
collection.insertOne(document);
return document.get("_id").toString();
}
private Object updateOne(Map inParams, MongoCollection collection) {
if (!inParams.containsKey("id"))
throw new N2oException("Id is required for operation \"updateOne\"");
String id = (String) inParams.get("id");
Map data = new HashMap<>(inParams);
data.remove("id");
collection.updateOne(eq("_id", new ObjectId(id)), new Document("$set", new Document(data)));
return null;
}
private Object deleteOne(Map inParams, MongoCollection collection) {
if (!inParams.containsKey("id"))
throw new N2oException("Id is required for operation \"deleteOne\"");
collection.deleteOne(eq("_id", new ObjectId((String) inParams.get("id"))));
return null;
}
private Object deleteMany(Map inParams, MongoCollection collection) {
if (!inParams.containsKey("ids"))
throw new N2oException("Ids is required for operation \"deleteMany\"");
Object[] ids = ((List) inParams.get("ids")).stream().map(id -> new ObjectId((String) id)).toArray();
collection.deleteMany(in("_id", ids));
return null;
}
}