All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.krud.crudframework.mongo.dao.AbstractMongoBaseDao Maven / Gradle / Ivy

There is a newer version: 1.7.0
Show newest version
package dev.krud.crudframework.mongo.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import dev.krud.crudframework.model.BaseCrudEntity;
import dev.krud.crudframework.modelfilter.DynamicModelFilter;
import dev.krud.crudframework.modelfilter.FilterField;
import dev.krud.crudframework.modelfilter.OrderDTO;
import dev.krud.crudframework.modelfilter.enums.FilterFieldOperation;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

public abstract class AbstractMongoBaseDao {

	@Autowired
	protected MongoTemplate mongoTemplate;

	private static final Set> primitiveAndBoxedTypes = new HashSet<>();

	static {
		primitiveAndBoxedTypes.add(boolean.class);
		primitiveAndBoxedTypes.add(byte.class);
		primitiveAndBoxedTypes.add(short.class);
		primitiveAndBoxedTypes.add(char.class);
		primitiveAndBoxedTypes.add(int.class);
		primitiveAndBoxedTypes.add(long.class);
		primitiveAndBoxedTypes.add(float.class);
		primitiveAndBoxedTypes.add(double.class);
		primitiveAndBoxedTypes.add(Boolean.class);
		primitiveAndBoxedTypes.add(Character.class);
		primitiveAndBoxedTypes.add(Byte.class);
		primitiveAndBoxedTypes.add(Short.class);
		primitiveAndBoxedTypes.add(String.class);
		primitiveAndBoxedTypes.add(Integer.class);
		primitiveAndBoxedTypes.add(Long.class);
		primitiveAndBoxedTypes.add(Float.class);
		primitiveAndBoxedTypes.add(Double.class);
	}

	/**
	 * Return entity by given class and UUID.
	 *
	 * @param clazz required class
	 * @param id unique identificator
	 * @return entity with given class and UUID.
	 */
	public  T findObject(Class clazz, Serializable id) {
		Criteria criteria = Criteria.where("id").is(id);
		return mongoTemplate.findOne(new Query().addCriteria(criteria), clazz);
	}

	/**
	 * Return entity list by given class and a list of UUIDs.
	 *
	 * @param clazz required class
	 * @param ids a list of UUIDs
	 * @return a list of entities with given class and matching UUID
	 */
	public  List findObjectByIds(Class clazz, Serializable ids[]) {
		Criteria criteria = Criteria.where("id").in(ids);
		return mongoTemplate.find(new Query().addCriteria(criteria), clazz);
	}

	/**
	 * Delete entity with given class and UUID from DB
	 *
	 * @param clazz required class
	 * @param id unique identificator
	 */
	public void deleteObject(Class clazz, Serializable id) {
		deleteObject(findObject(clazz, id));
	}

	/**
	 * Delete entity from DB.
	 *
	 * @param object entity for removing.
	 */
	public void deleteObject(Object object) {
		if(null != object) {
			mongoTemplate.remove(object);
		}
	}

	protected Query buildQuery(DynamicModelFilter filter) {
		Query query = new Query();

		if(filter != null) {
			if(filter.getFilterFields() != null && !filter.getFilterFields().isEmpty()) {
				Criteria criteria = new Criteria();
				for(FilterField filterField : filter.getFilterFields()) {
					buildCriterion(criteria, filterField);
				}
				query.addCriteria(criteria);
			}

		}
		return query;
	}


	private Criteria buildCriterion(Criteria criteria, FilterField filterField) {
		if(filterField.getChildren() != null || isValidSimpleFilterField(filterField)) {

			switch(filterField.getOperation()) {
				case Equal:
					criteria.and(filterField.getFieldName()).is(filterField.value1());
					break;
				case NotEqual:
					criteria.and(filterField.getFieldName()).ne(filterField.value1());
					break;
				case In:
					criteria.and(filterField.getFieldName()).in(filterField.getValues());
					break;
				case NotIn:
					criteria.and(filterField.getFieldName()).nin(filterField.getValues());
					break;
				case GreaterEqual:
					criteria.and(filterField.getFieldName()).gte(filterField.value1());
					break;
				case GreaterThan:
					criteria.and(filterField.getFieldName()).gt(filterField.value1());
					break;
				case LowerEqual:
					criteria.and(filterField.getFieldName()).lte(filterField.value1());
					break;
				case LowerThan:
					criteria.and(filterField.getFieldName()).lt(filterField.value1());
					break;
				case Between:
					criteria.and(filterField.getFieldName())
									.gte(filterField.value1())
									.and(filterField.getFieldName())
									.lte(filterField.value2());
					break;
				case Contains:
					if(filterField.value1() != null && !filterField.value1().toString().trim().isEmpty()) {
						criteria.and(filterField.getFieldName()).regex(Pattern.compile(filterField.value1().toString(), Pattern.LITERAL & Pattern.CASE_INSENSITIVE));
					}
					break;
				case IsNull:
					criteria.orOperator(
							Criteria.where(filterField.getFieldName()).exists(false),
							Criteria.where(filterField.getFieldName()).is(null)
					);
					break;
				case IsNotNull:
					criteria.and(filterField.getFieldName()).ne(null);
					break;
				case And:
					if(filterField.getChildren() != null && !filterField.getChildren().isEmpty()) {
						List criterias = new ArrayList<>();
						for(FilterField child : filterField.getChildren()) {
							criterias.add(buildCriterion(criteria, child));
						}

						criteria.andOperator(criterias.toArray(new Criteria[]{}));
					}
					break;
				case Or:
					if(filterField.getChildren() != null && !filterField.getChildren().isEmpty()) {
						List criterias = new ArrayList<>();
						for(FilterField child : filterField.getChildren()) {
							criterias.add(buildCriterion(criteria, child));
						}

						criteria.orOperator(criterias.toArray(new Criteria[]{}));
					}
					break;
				case Not:
					if(filterField.getChildren() != null && !filterField.getChildren().isEmpty()) {
						FilterField child = filterField.getChildren().get(0);
						criteria.not().andOperator(buildCriterion(criteria, child));
					}
					break;
				case Noop:
					criteria.and("id").in();
                    break;
                default:
                    throw new UnsupportedOperationException("Unsupported filter operation: " + filterField.getOperation());
			}
		}

		return criteria;
	}

	private boolean isValidSimpleFilterField(FilterField filterField) {
		return filterField.getFieldName() != null && !filterField.getFieldName().trim().isEmpty() &&
				filterField.getOperation() != null && areValuesValid(filterField);
	}

	private boolean areValuesValid(FilterField filterField) {
		List simpleOperationsWithoutValue = Arrays.asList(FilterFieldOperation.IsNotNull, FilterFieldOperation.IsNull);
		if(simpleOperationsWithoutValue.contains(filterField.getOperation())) {
			return true;
		} else {
			return filterField.getValues() != null && filterField.getValues().length > 0;
		}
	}

	protected void setOrder(Query query, Set orders) {
		List sortOrders = new ArrayList<>();
		for (OrderDTO order : orders) {
			if(order.getBy() != null && !order.getBy().trim().isEmpty()) {
				sortOrders.add(new Sort.Order(order.getDescending() ? Sort.Direction.DESC : Sort.Direction.ASC, order.getBy()));
			}
		}
		if(!sortOrders.isEmpty()) {
			query.with(Sort.by(sortOrders));
		} else {
			query.with(Sort.by(
					Sort.Direction.DESC,
					"id"
			));
		}
	}

	protected void setBoundaries(Query query, Integer start, Integer limit) {
		if(start != null) {
			query.skip(start);
		}

		if(limit != null) {
			query.limit(limit);
		}
	}

	protected String replaceSpecialCharacters(String string) {
		return string.replace("_", "\\_").replace("%", "\\%");
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy