/* * 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.criteria.CriteriaBuilder; import javax.persistence.criteria.Path; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import java.util.List; import static com.google.common.collect.Lists.newArrayList; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; /** * Helper to create a predicate out of {@link Range}s. */ @SuppressWarnings("unchecked") @Named @Singleton public class ByRangeUtil { @Inject private JpaUtil jpaUtil; public <E> Predicate byRanges(Root<E> root, CriteriaBuilder builder, SearchParameters sp, Class<E> type) { List<Range<?, ?>> ranges = sp.getRanges(); List<Predicate> predicates = newArrayList(); for (Range<?, ?> r : ranges) { Range<E, ?> range = (Range<E, ?>) r; if (range.isSet()) { Predicate rangePredicate = buildRangePredicate(range, root, builder); if (rangePredicate != null) { predicates.add(rangePredicate); } } } return jpaUtil.concatPredicate(sp, builder, predicates); } private static <D extends Comparable<? super D>, E> Predicate buildRangePredicate(Range<E, D> range, Root<E> root, CriteriaBuilder builder) { Predicate rangePredicate = null; Path<D> path = JpaUtil.getInstance().getPath(root, range.getAttributes()); if (range.isBetween()) { rangePredicate = builder.between(path, range.getFrom(), range.getTo()); } else if (range.isFromSet()) { rangePredicate = builder.greaterThanOrEqualTo(path, range.getFrom()); } else if (range.isToSet()) { rangePredicate = builder.lessThanOrEqualTo(path, range.getTo()); } if (rangePredicate != null) { if (!range.isIncludeNullSet() || range.getIncludeNull() == FALSE) { return rangePredicate; } else { return builder.or(rangePredicate, builder.isNull(path)); } } else { // no from/to is set, but include null or not could be: if (TRUE == range.getIncludeNull()) { return builder.isNull(path); } else if (FALSE == range.getIncludeNull()) { return builder.isNotNull(path); } } return null; } }