com.mxep.web.common.persistence.DynamicSpecifications.java Source code

Java tutorial

Introduction

Here is the source code for com.mxep.web.common.persistence.DynamicSpecifications.java

Source

/*******************************************************************************
 * Copyright (c) 2005, 2014 springside.github.io
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 *******************************************************************************/
package com.mxep.web.common.persistence;

import com.mxep.core.utils.Collections3;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;

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

public class DynamicSpecifications {

    private static List<Predicate> getPredicate(Collection<SearchFilter> filters, Root<?> root,
            CriteriaQuery<?> query, CriteriaBuilder builder) {
        List<Predicate> predicates = 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]);
            }

            /*????*/
            if (expression.getJavaType().equals(Integer.class)
                    && !filter.operator.equals(SearchFilter.Operator.IN)) {
                filter.value = Integer.parseInt(filter.value.toString());
            }

            // 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 IN:
                In in = builder.in(expression);
                String value = filter.value.toString();
                String[] values = StringUtils.split(value, ",");
                for (int i = 0; i < values.length; i++) {
                    /*????*/
                    if (expression.getJavaType().equals(Integer.class) || expression.getJavaType().equals(int.class)
                            || expression.getJavaType().equals(byte.class)) {
                        in.value(Integer.valueOf(values[i]));
                    } else {
                        in.value(values[i]);
                    }

                }
                predicates.add(in);
                break;
            case NULL:
                predicates.add(builder.isNull(expression));
                break;
            case NOTNULL:
                predicates.add(builder.isNotNull(expression));
                break;
            }
        }
        return predicates;
    }

    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 = getPredicate(filters, root, query, builder);
                    // ? and ???
                    if (!predicates.isEmpty()) {
                        return builder.and(predicates.toArray(new Predicate[predicates.size()]));
                    }
                }
                return builder.conjunction();
            }
        };
    }

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

                    List<Predicate> predicates = getPredicate(filters, root, query, builder);

                    if (null != callback) {
                        predicates.addAll(callback.addPredicate(root, query, builder));
                    }

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

                return builder.conjunction();
            }
        };
    }

    public interface SpecificationCallback<T> {
        List<Predicate> addPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder);
    }
}