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

com.github.brunodutr.persistence.criteria.service.CriteriaProcessor Maven / Gradle / Ivy

There is a newer version: 2.0.2
Show newest version
package com.github.brunodutr.persistence.criteria.service;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;

import com.github.brunodutr.persistence.criteria.annotations.CriteriaOrderBy;

public class CriteriaProcessor {

	private CriteriaBuilder criteriaBuilder;
	private Root root;
	private Object object;
	private CriteriaQuery criteriaQuery;
	private EntityManager entityManager;
	
	private Predicate[] where() {

		Field[] fields = object.getClass().getDeclaredFields();

		return Stream.of(fields).map(field -> {

			try {

				ICriteriaProcessor processor = CriteriaProcessorFactory.getProcessor(field);
				
				if(processor != null) {
					return processor.process(criteriaBuilder, root, object, field);
				} else {
					return null;
				}
							
			} catch (Exception e) {
				e.printStackTrace();
			}

			return null;
		}).filter(Objects::nonNull).toArray(Predicate[]::new);

	}

	private Order[] orderBy() {

		if (object.getClass().isAnnotationPresent(CriteriaOrderBy.class)) {

			CriteriaOrderBy criteriaOrderBy = object.getClass().getAnnotation(CriteriaOrderBy.class);

			String sort = criteriaOrderBy.sort();

			if ((!sort.equalsIgnoreCase("asc")) && (!sort.equalsIgnoreCase("desc"))) {
				throw new IllegalArgumentException("Sort deve ser 'asc' ou 'desc'");
			}

			return Stream.of(criteriaOrderBy.columns()).filter(StringUtils::isNotBlank).map(column -> {

				Path path = root.get(column);

				if (sort.equals("asc")) {
					return criteriaBuilder.asc(path);
				} else {
					return criteriaBuilder.desc(path);
				}

			}).toArray(Order[]::new);

		}

		return new Order[] {};

	}

	private CriteriaProcessor(EntityManager entityManager, Class entityClass) {
		super();
		this.entityManager = entityManager;
		this.criteriaBuilder = entityManager.getCriteriaBuilder();
		this.criteriaQuery = criteriaBuilder.createQuery(entityClass);
		this.root = criteriaQuery.from(entityClass);
	}
	
	public static  CriteriaProcessor create(EntityManager entityManager, Class entityClass) {
		return new CriteriaProcessor(entityManager, entityClass);
	}
	
	public CriteriaProcessor filter(Object filter){
		this.object = filter;
		return this;
	}
	
	public List getResultList() {

		criteriaQuery.where(where());
		criteriaQuery.orderBy(orderBy());
		criteriaQuery.select(root);
		
		TypedQuery query = entityManager.createQuery(criteriaQuery);
		
		return query.getResultList();
	}
	
	

}