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

paa.coder.noodleCriteriaBuilder.queryBuilder.NoodleAbstractQuery Maven / Gradle / Ivy

package paa.coder.noodleCriteriaBuilder.queryBuilder;

import paa.coder.noodleCriteriaBuilder.NoodleFactory;
import paa.coder.noodleCriteriaBuilder.NoodleUtils;
import paa.coder.noodleCriteriaBuilder.exceptions.NoodleException;
import paa.coder.noodleCriteriaBuilder.interfaces.NoodlePredicate;
import paa.coder.noodleCriteriaBuilder.interfaces.PathFinder;
import paa.coder.noodleCriteriaBuilder.queryBuilder.expressions.SelectStore;
import paa.coder.noodleCriteriaBuilder.queryBuilder.specifications.NoodleSpecificationBuilder;

import javax.persistence.criteria.*;
import javax.persistence.metamodel.SingularAttribute;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public abstract class NoodleAbstractQuery {

    protected final NoodleFactory noodleFactory;
    protected List where = new ArrayList<>();
    public boolean distinct = false;

    public NoodleAbstractQuery(NoodleFactory noodleFactory){
        this.noodleFactory = noodleFactory;
    }

    public NoodleAbstractQuery where(Function fPred){
        Optional.ofNullable(fPred.apply(new NoodleSpecificationBuilder.Builder(noodleFactory))).ifPresent(where::add);
        return this;
    }

    public NoodleAbstractQuery itDistinct(Boolean d){
        distinct=d;
        return this;
    }


    public List getWhere(){
        return where;
    }

    protected Optional alias(){
        return Optional.empty();
    }

    protected Optional parentFinder(){
        return Optional.empty();
    }

    protected final PathFinder pathFinder (Root root) {
        return field->{
            NoodleUtils.StrShift shift = new NoodleUtils.StrShift(field);
            if(alias().flatMap(a->shift.getLeft().map(_a->_a.equals(a))).orElse(false)){
                return Optional.ofNullable(NoodleUtils.pathFinder(root, shift.getRight().orElse("")));
            }
            return parentFinder()
                    .orElseGet(()->str->Optional.ofNullable(NoodleUtils.pathFinder(root,field)))
                    .apply(field);
        };
    }

    protected final Optional getWherePredicates(Rootroot, CommonAbstractCriteria commonAbstractCriteria,CriteriaBuilder criteriaBuilder){
        List wherePredicates = getWhere()
                .stream()
                .map(s -> s.apply(pathFinder(root), commonAbstractCriteria, criteriaBuilder))
                .filter(Objects::nonNull).collect(Collectors.toList());
        return Optional.of(wherePredicates).filter(i->!i.isEmpty()).map(i->i.toArray(Predicate[]::new));
    }

    public static abstract class Select extends NoodleAbstractQuery {

        protected List having = new ArrayList<>();
        protected SelectStore groupBy;

        public Select(NoodleFactory noodleFactory){
            super(noodleFactory);
            this.groupBy = new SelectStore();
        }

        public NoodleAbstractQuery having(Function fPred){
            having.add(fPred.apply(new NoodleSpecificationBuilder.Builder(noodleFactory)));
            return this;
        }

        public NoodleAbstractQuery group(Consumer action){
            action.accept(groupBy);
            return this;
        }

        @Override
        public Select where(Function fPred){
            return (Select) super.where(fPred);
        }

        public List getHaving(){
            return having;
        }

        public SelectStore getGroupBy(){
            return groupBy;
        }

        public  > void build(Root root, X criteriaQuery, CriteriaBuilder criteriaBuilder){

            Optional.ofNullable(getGroupBy()).map(i->i.apply(pathFinder(root),criteriaQuery,criteriaBuilder)).filter(i -> ! i.isEmpty()).ifPresent(group->{
                criteriaQuery.groupBy(group);
                List havingPredicates = getHaving()
                        .stream()
                        .map(s -> s.apply(pathFinder(root), criteriaQuery, criteriaBuilder))
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList());
                if(! havingPredicates.isEmpty()){
                    criteriaQuery.having(havingPredicates.toArray(new Predicate[0]));
                }
            });
            if(distinct){
                criteriaQuery.distinct(true);
            }
            getWherePredicates(root,criteriaQuery,criteriaBuilder).ifPresent(criteriaQuery::where);
        }
    }

    protected   Set getIds(SingularAttribute singularAttribute,Class from){
        CriteriaQuery criteriaQuery = noodleFactory.getSession().getCriteriaBuilder().createQuery(singularAttribute.getJavaType());
        Root root = criteriaQuery.from(from);
        getWherePredicates(root, criteriaQuery, noodleFactory.getSession().getCriteriaBuilder()).ifPresentOrElse(criteriaQuery::where, () -> {
            throw new NoodleException("not found where predicates! To update all use method updateAll()");
        });
        criteriaQuery.select(root.get(singularAttribute));
        return noodleFactory.getSession().createQuery(criteriaQuery).stream().collect(Collectors.toSet());
    }

    protected   Stream find(Class from){
        CriteriaQuery criteriaQuery = noodleFactory.getSession().getCriteriaBuilder().createQuery(from);
        Root root = criteriaQuery.from(from);
        getWherePredicates(root, criteriaQuery, noodleFactory.getSession().getCriteriaBuilder()).ifPresentOrElse(criteriaQuery::where, () -> {
            throw new NoodleException("not found where predicates! To update all use method updateAll()");
        });
        criteriaQuery.select(root);
        return noodleFactory.getSession().createQuery(criteriaQuery).stream();
    }

    protected  Stream findBySingularAttribute(Class from, SingularAttribute singularAttribute, Set ids){
        CriteriaQuery selectQuery = noodleFactory.getSession().getCriteriaBuilder().createQuery(from);
        Root sRoot = selectQuery.from(from);
        selectQuery.select(sRoot);
        selectQuery.where(sRoot.get(singularAttribute).in(ids));

        return noodleFactory.getSession().createQuery(selectQuery).stream();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy