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

com.jaxio.jpa.querybyexample.ByFullTextUtil Maven / Gradle / Ivy

There is a newer version: 1.0.1
Show newest version
/*
 * Copyright 2015 JAXIO http://www.jaxio.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jaxio.jpa.querybyexample;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.persistence.Embeddable;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.SingularAttribute;
import java.io.Serializable;
import java.util.List;

import static com.google.common.collect.Lists.newArrayList;
import static java.util.Collections.emptyList;

/**
 * @author Nicolas Romanetti
 * @author Florent Ramière
 * @author Sébastien Péralta
 * @author Jean-Louis Boudart
 */
@Named
@Singleton
public class ByFullTextUtil {
    @PersistenceContext
    private EntityManager em;

    @Inject
    protected HibernateSearchUtil hibernateSearchUtil;
    @Inject
    private JpaUtil jpaUtil;

    public > Predicate byFullText(Root root, CriteriaBuilder builder, SearchParameters sp, T entity,
                                                            List> indexedAttributes) {
        if (!hasNonEmptyTerms(sp)) {
            return null;
        }

        if (jpaUtil.hasSimplePk(entity)) {
            return onSimplePrimaryKey(root, builder, sp, indexedAttributes);
        } else {
            return onCompositePrimaryKeys(root, builder, sp, indexedAttributes);
        }
    }

    private boolean hasNonEmptyTerms(SearchParameters sp) {
        for (TermSelector termSelector : sp.getTerms()) {
            if (termSelector.isNotEmpty()) {
                return true;
            }
        }
        return false;
    }

    private > Predicate onCompositePrimaryKeys(Root root, CriteriaBuilder builder, SearchParameters sp,
                                                                         List> properties) {
        List found = hibernateSearchUtil.find(root.getJavaType(), sp, properties);
        if (found == null) {
            return null;
        } else if (found.isEmpty()) {
            return builder.disjunction();
        }

        List predicates = newArrayList();
        for (T t : found) {
            predicates.add(byExampleOnEntity(root, t, sp, builder));
        }
        return jpaUtil.concatPredicate(sp, builder, jpaUtil.orPredicate(builder, predicates));
    }

    private  Predicate onSimplePrimaryKey(Root root, CriteriaBuilder builder, SearchParameters sp, List> properties) {
        List ids = hibernateSearchUtil.findId(root.getJavaType(), sp, properties);
        if (ids == null) {
            return null;
        } else if (ids.isEmpty()) {
            return builder.disjunction();
        }

        return jpaUtil.concatPredicate(sp, builder, root.get("id").in(ids));
    }

    public > Predicate byExampleOnEntity(Root rootPath, T entityValue, SearchParameters sp, CriteriaBuilder builder) {
        if (entityValue == null) {
            return null;
        }

        Class type = rootPath.getModel().getBindableJavaType();
        ManagedType mt = em.getMetamodel().entity(type);

        List predicates = newArrayList();
        predicates.addAll(byExample(mt, rootPath, entityValue, sp, builder));
        predicates.addAll(byExampleOnCompositePk(rootPath, entityValue, sp, builder));
        return jpaUtil.orPredicate(builder, predicates);
    }

    protected > List byExampleOnCompositePk(Root root, T entity, SearchParameters sp, CriteriaBuilder builder) {
        String compositePropertyName = jpaUtil.compositePkPropertyName(entity);
        if (compositePropertyName == null) {
            return emptyList();
        } else {
            return newArrayList(byExampleOnEmbeddable(root.get(compositePropertyName), entity.getId(), sp, builder));
        }
    }

    public  Predicate byExampleOnEmbeddable(Path embeddablePath, E embeddableValue, SearchParameters sp, CriteriaBuilder builder) {
        if (embeddableValue == null) {
            return null;
        }

        Class type = embeddablePath.getModel().getBindableJavaType();
        ManagedType mt = em.getMetamodel().embeddable(type); // note: calling .managedType() does not work
        return jpaUtil.orPredicate(builder, byExample(mt, embeddablePath, embeddableValue, sp, builder));
    }

    /*
     * Add a predicate for each simple property whose value is not null.
     */
    public  List byExample(ManagedType mt, Path mtPath, T mtValue, SearchParameters sp, CriteriaBuilder builder) {
        List predicates = newArrayList();
        for (SingularAttribute attr : mt.getSingularAttributes()) {
            if (!isPrimaryKey(mt, attr)) {
                continue;
            }

            Object attrValue = jpaUtil.getValue(mtValue, attr);
            if (attrValue != null) {
                predicates.add(builder.equal(mtPath.get(jpaUtil.attribute(mt, attr)), attrValue));
            }
        }
        return predicates;
    }

    private  boolean isPrimaryKey(ManagedType mt, SingularAttribute attr) {
        if (mt.getJavaType().getAnnotation(Embeddable.class) != null) {
            return true;
        }
        return jpaUtil.isPk(mt, attr);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy