edu.pitt.dbmi.ccd.db.specification.VocabularySpecification.java Source code

Java tutorial

Introduction

Here is the source code for edu.pitt.dbmi.ccd.db.specification.VocabularySpecification.java

Source

/*
 * Copyright (C) 2015 University of Pittsburgh.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301  USA
 */
package edu.pitt.dbmi.ccd.db.specification;

import edu.pitt.dbmi.ccd.db.entity.Vocabulary;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.data.jpa.domain.Specification;
import static org.springframework.util.StringUtils.isEmpty;

/**
 * @author Mark Silvis (marksilvis@pitt.edu)
 */
public final class VocabularySpecification {

    // columns
    private static final String NAME = "name";
    private static final String DESC = "description";

    private VocabularySpecification() {
    }

    /**
     * find vocabularies that contain search terms
     *
     * @param matches search terms
     * @param nots negated search terms
     * @return specification
     */
    public static Specification<Vocabulary> searchSpec(Set<String> matches, Set<String> nots) {
        return (root, query, cb) -> {
            return buildSearchSpec(root, cb, matches, nots);
        };
    }

    // build search predicates
    private static Predicate buildSearchSpec(Root<Vocabulary> root, CriteriaBuilder cb, Set<String> matches,
            Set<String> nots) {
        List<Predicate> predicates = new ArrayList<>(0);
        if (!isEmpty(matches)) {
            predicates.addAll(inNameOrDescription(root, cb, matches));
        }
        if (!isEmpty(nots)) {
            predicates.addAll(notInNameOrDescription(root, cb, nots));
        }
        return cb.and(predicates.toArray(new Predicate[predicates.size()]));
    }

    // build (name or description contains term) predicate for each search term
    private static List<Predicate> inNameOrDescription(Root<Vocabulary> root, CriteriaBuilder cb,
            Set<String> terms) {
        return terms.stream().map(t -> containsLike(t))
                .map(t -> cb.or(nameContains(root, cb, t), descriptionContains(root, cb, t)))
                .collect(Collectors.toList());
    }

    // build (neither name or description contains term) predicate for each search term
    private static List<Predicate> notInNameOrDescription(Root<Vocabulary> root, CriteriaBuilder cb,
            Set<String> terms) {
        return terms.stream().map(t -> containsLike(t))
                .map(t -> cb.not(cb.or(nameContains(root, cb, t), descriptionContains(root, cb, t))))
                .collect(Collectors.toList());
    }

    // build name contains term predicate
    private static Predicate nameContains(Root<Vocabulary> root, CriteriaBuilder cb, String term) {
        return cb.like(cb.lower(root.get(NAME)), term);
    }

    // build description contains term predicate
    private static Predicate descriptionContains(Root<Vocabulary> root, CriteriaBuilder cb, String term) {
        return cb.like(cb.lower(root.get(DESC)), term);
    }

    // wrap term in wildcards
    private static String containsLike(String term) {
        if (isEmpty(term)) {
            return "%";
        } else {
            return "%" + term.toLowerCase() + "%";
        }
    }
}