aode.lx.persistence.DynamicSpecifications.java Source code

Java tutorial

Introduction

Here is the source code for aode.lx.persistence.DynamicSpecifications.java

Source

/*******************************************************************************
 * Copyright (c) 2005, 2014 springside.github.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *******************************************************************************/
package aode.lx.persistence;

import aode.lx.utils.Collections3;
import aode.lx.utils.EnumUtils;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.springframework.data.jpa.domain.Specification;

import javax.persistence.criteria.*;
import java.util.Collection;
import java.util.List;

public class DynamicSpecifications {

    public static <T> Specification<T> bySearchFilter(final Collection<SearchFilter> filters,
            final Class<T> entityClazz) {
        return new Specification<T>() {
            @Override
            public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
                if (Collections3.isNotEmpty(filters)) {

                    List<Predicate> predicates = Lists.newArrayList();
                    List<Predicate> ORpredicates = Lists.newArrayList();

                    for (SearchFilter filter : filters) {
                        // nested path translate, Task??"user.name"filedName, ?Task.user.name
                        String[] names = StringUtils.split(filter.fieldName, ".");
                        Path expression = root.get(names[0]);
                        for (int i = 1; i < names.length; i++) {
                            expression = expression.get(names[i]);
                        }

                        Object value = filter.value;

                        if (expression.getJavaType().isEnum()) {
                            value = EnumUtils.valueOf(expression.getJavaType(), filter.value.toString());
                            predicates.add(builder.equal(expression, value));
                        } else {
                            // logic operator
                            switch (filter.operator) {
                            case EQ:
                                predicates.add(builder.equal(expression, filter.value));
                                break;
                            case LIKE:
                                predicates.add(builder.like(expression, "%" + filter.value + "%"));
                                break;
                            case GT:
                                predicates.add(builder.greaterThan(expression, (Comparable) filter.value));
                                break;
                            case LT:
                                predicates.add(builder.lessThan(expression, (Comparable) filter.value));
                                break;
                            case GTE:
                                predicates.add(builder.greaterThanOrEqualTo(expression, (Comparable) filter.value));
                                break;
                            case LTE:
                                predicates.add(builder.lessThanOrEqualTo(expression, (Comparable) filter.value));
                                break;
                            case NEQ:
                                predicates.add(builder.notEqual(expression, filter.value));
                                break;
                            case NOTNULL:
                                predicates.add(builder.isNotNull(expression));
                                break;
                            case ISNULL:
                                predicates.add(builder.isNull(expression));
                                break;
                            case OREQ:
                                ORpredicates.add(builder.equal(expression, filter.value));
                                break;
                            case ORLIKE:
                                ORpredicates.add(builder.like(expression, "%" + filter.value + "%"));
                                break;
                            case ORGT:
                                ORpredicates.add(builder.greaterThan(expression, (Comparable) filter.value));
                                break;
                            case ORLT:
                                ORpredicates.add(builder.lessThan(expression, (Comparable) filter.value));
                                break;
                            case ORGTE:
                                ORpredicates
                                        .add(builder.greaterThanOrEqualTo(expression, (Comparable) filter.value));
                                break;
                            case ORLTE:
                                ORpredicates.add(builder.lessThanOrEqualTo(expression, (Comparable) filter.value));
                                break;
                            case ORNEQ:
                                ORpredicates.add(builder.notEqual(expression, filter.value));
                                break;
                            case ORNOTNULL:
                                ORpredicates.add(builder.isNotNull(expression));
                                break;
                            case ORISNULL:
                                ORpredicates.add(builder.isNull(expression));
                                break;
                            }
                        }

                    }

                    // ? and ???
                    if (!predicates.isEmpty() && !ORpredicates.isEmpty()) {
                        return builder.and(builder.and(predicates.toArray(new Predicate[predicates.size()])),
                                builder.or(ORpredicates.toArray(new Predicate[ORpredicates.size()])));
                    }
                    if (!predicates.isEmpty()) {
                        return builder.and(predicates.toArray(new Predicate[predicates.size()]));
                    }
                    if (!ORpredicates.isEmpty()) {
                        return builder.or(ORpredicates.toArray(new Predicate[ORpredicates.size()]));
                    }
                }
                return builder.conjunction();
            }
        };
    }
}