/*******************************************************************************
* Copyright (c) 2014 antoniomariasanchez at gmail.com.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* antoniomaria - initial API and implementation
******************************************************************************/
/*
* (c) Copyright 2005-2012 JAXIO, www.jaxio.com Source code generated by Celerio, a Jaxio product Want to use Celerio
* within your company? email us at info@jaxio.com Follow us on twitter: @springfuse Template
* pack-backend-sd:src/main/java/project/repository/support/RangeSpecification.p.vm.java
*/
package net.sf.gazpachoquest.qbe;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.apache.commons.lang3.Validate;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications;
/**
* Helper to create {@link Specification} out of {@link Range}s.
*/
@SuppressWarnings("unchecked")
public class RangeSpecification {
public static <E,D extends Comparable<? super D>> Specifications<E> andRangeIfSet(Specifications<E> specifications, final List<Range<?, ?>> ranges) {
for (Range<?, ?> r : ranges) {
if (r.isSet()) {
Range<E, D> range = (Range<E, D>) r;
specifications = specifications.and(toSpecification(range));
}
}
return specifications;
}
public static <E, D extends Comparable<? super D>> Specification<E> toSpecification(final Range<E, D> range) {
Validate.isTrue(range.isSet(), "You must pass an exploitable range");
return new Specification<E>() {
@Override
public Predicate toPredicate(final Root<E> root, final CriteriaQuery<?> query, final CriteriaBuilder builder) {
Predicate rangePredicate = null;
if (range.isBetween()) {
rangePredicate = builder.between(root.get(range.getField()), range.getFrom(), range.getTo());
} else if (range.isFromSet()) {
// rangePredicate =
// builder.greaterThanOrEqualTo(root.get(range.getField()),
// range.getFrom());
rangePredicate = builder.greaterThan(root.get(range.getField()), range.getFrom());
} else if (range.isToSet()) {
// rangePredicate =
// builder.lessThanOrEqualTo(root.get(range.getField()),
// range.getTo());
rangePredicate = builder.lessThan(root.get(range.getField()), range.getTo());
}
if (rangePredicate != null) {
if (!range.isIncludeNullSet() || Boolean.FALSE.equals(range.getIncludeNull())) {
return rangePredicate;
} else {
return builder.or(rangePredicate, builder.isNull(root.get(range.getField())));
}
}
// no range at all
// take the opportunity to keep only null...
if (Boolean.TRUE.equals(range.getIncludeNull())) {
return builder.isNull(root.get(range.getField()));
}
// ... or non-null only...
if (Boolean.FALSE.equals(range.getIncludeNull())) {
return builder.isNotNull(root.get(range.getField()));
}
throw new IllegalStateException("You must pass an exploitable range (should not happen here)");
}
};
}
}