From bea1d80f1e951912d22e9808e0ba1ff2e23f05dc Mon Sep 17 00:00:00 2001 From: Joern Muehlencord Date: Sun, 27 Oct 2019 03:15:38 +0100 Subject: [PATCH] extended search by SearchFilter --- .../shared/db/AbstractController.java | 6 +- .../shared/db/CommonAbstractController.java | 66 ++++++++++++++++--- .../de/muehlencord/shared/db/Comparator.java | 6 +- .../shared/db/StandardController.java | 36 +++++++++- 4 files changed, 99 insertions(+), 15 deletions(-) diff --git a/db/src/main/java/de/muehlencord/shared/db/AbstractController.java b/db/src/main/java/de/muehlencord/shared/db/AbstractController.java index cdf9212..859df50 100644 --- a/db/src/main/java/de/muehlencord/shared/db/AbstractController.java +++ b/db/src/main/java/de/muehlencord/shared/db/AbstractController.java @@ -85,7 +85,7 @@ public abstract class AbstractController extends CommonA * @return a list of all entities. */ @Lock(LockType.READ) - public List findAll() { + public List findAll() throws ControllerException { return findAll(new ArrayList<>()); } @@ -96,7 +96,7 @@ public abstract class AbstractController extends CommonA * @return a list of all entities. */ @Lock(LockType.READ) - public List findAll(String... orderFields) { + public List findAll(String... orderFields) throws ControllerException { return findAll(Arrays.asList(orderFields)); } @@ -106,7 +106,7 @@ public abstract class AbstractController extends CommonA * @return a list of all entities. */ @Lock(LockType.READ) - public List findAll(List orderFields) { + public List findAll(List orderFields) throws ControllerException { return findAll(entityClass, orderFields); } diff --git a/db/src/main/java/de/muehlencord/shared/db/CommonAbstractController.java b/db/src/main/java/de/muehlencord/shared/db/CommonAbstractController.java index 65981cd..671d1c1 100644 --- a/db/src/main/java/de/muehlencord/shared/db/CommonAbstractController.java +++ b/db/src/main/java/de/muehlencord/shared/db/CommonAbstractController.java @@ -19,7 +19,7 @@ import de.muehlencord.shared.util.DateUtil; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; +import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Map; @@ -57,9 +57,10 @@ public abstract class CommonAbstractController { * @param the type of the entity to search for * @param entityClass the entity class to return * @return a list of all entities found + * @throws ControllerException if the search cannot be executed. */ @Lock(LockType.READ) - public List findAll(Class entityClass) { + public List findAll(Class entityClass) throws ControllerException { return findAll(entityClass, new ArrayList<>()); } @@ -69,9 +70,10 @@ public abstract class CommonAbstractController { * @param entityClass the entity class to return * @param orderFields the fields to order the result by. * @return a list of all entities found + * @throws ControllerException if the search cannot be executed. */ @Lock(LockType.READ) - public List findAll(Class entityClass, String... orderFields) { + public List findAll(Class entityClass, String... orderFields) throws ControllerException { return findAll(entityClass, Arrays.asList(orderFields)); } @@ -81,20 +83,21 @@ public abstract class CommonAbstractController { * @param entityClass the entity class to return * @param orderFields the fields to order the result by. * @return a list of all entities found + * @throws ControllerException if the search cannot be executed. */ @Lock(LockType.READ) - public List findAll(Class entityClass, List orderFields) { + public List findAll(Class entityClass, List orderFields) throws ControllerException { final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaQuery criteria = cb.createQuery(entityClass); final Root r = criteria.from(entityClass); if (EndDateable.class.isAssignableFrom(entityClass.getClass())) { - List filterList = new ArrayList<>(); - Map filters = new HashMap<>(); - // FIXME - add filter to validFrom / validTo - // need to support different conditions, currently only equals supported, need to support e.g. gt, lt, ... - Predicate filterCondition = getFilterCondition(cb, r, filters); + Date now = DateUtil.getCurrentTimeInUTC(); + List searchFilter = new ArrayList<>(); + searchFilter.add(new DefaultSearchFilter("validFrom", Comparator.GREATER_OR_EQUAL_THAN, now)); + searchFilter.add(new DefaultSearchFilter("validTo", Comparator.LESS_THAN, now)); + Predicate filterCondition = getFilterCondition(cb, r, searchFilter); criteria.where(filterCondition); } @@ -464,8 +467,51 @@ public abstract class CommonAbstractController { default: throw new ControllerException(ControllerException.INTERNAL_ERROR, currentFilter.getComparator() + "not support for searchValue " + searchValue); } + returnCondition = addFilterCondition(cb, returnCondition, predicate); + } else if (currentFilter.getSearchValue() instanceof Date) { + Date searchValue = (Date) currentFilter.getSearchValue(); + Predicate predicate; + Path datePath = root.get(currentFilter.getFieldName()); + switch (currentFilter.getComparator()) { + case EQUAL: + predicate = cb.equal(datePath, searchValue); + break; + case NOT_EQUAL: + predicate = cb.notEqual(datePath, searchValue); + break; + case LESS_THAN: + predicate = cb.lessThan(datePath, searchValue); + break; + case LESS_OR_EQUAL_THAN: + predicate = cb.lessThanOrEqualTo(datePath, searchValue); + break; + case GREATER_THAN: + predicate = cb.greaterThan(datePath, searchValue); + break; + case GREATER_OR_EQUAL_THAN: + predicate = cb.greaterThanOrEqualTo(datePath, searchValue); + break; + default: + throw new ControllerException(ControllerException.INTERNAL_ERROR, currentFilter.getComparator() + "not support for searchValue " + searchValue); + } + returnCondition = addFilterCondition(cb, returnCondition, predicate); + } else if (currentFilter.getSearchValue() instanceof Boolean) { + Boolean searchValue = (Boolean) currentFilter.getSearchValue(); + Path booleanPath = root.get(currentFilter.getFieldName()); + Predicate predicate; + switch (currentFilter.getComparator()) { + case EQUAL: + predicate = cb.equal(booleanPath, searchValue); + break; + case NOT_EQUAL: + predicate = cb.notEqual(booleanPath, searchValue); + break; + default: + throw new ControllerException(ControllerException.INTERNAL_ERROR, currentFilter.getComparator() + "not support for searchValue " + searchValue); + } + returnCondition = addFilterCondition(cb, returnCondition, predicate); } else { - throw new ControllerException(ControllerException.INTERNAL_ERROR, "Not yet implemented"); + throw new ControllerException(ControllerException.INTERNAL_ERROR, "Filter for " + currentFilter.getSearchValue().getClass().getSimpleName() + " not yet implemented"); } } // for all filters diff --git a/db/src/main/java/de/muehlencord/shared/db/Comparator.java b/db/src/main/java/de/muehlencord/shared/db/Comparator.java index bed3f61..ef1e145 100644 --- a/db/src/main/java/de/muehlencord/shared/db/Comparator.java +++ b/db/src/main/java/de/muehlencord/shared/db/Comparator.java @@ -23,7 +23,11 @@ public enum Comparator { EQUAL, NOT_EQUAL, - CONTAINS; + CONTAINS, + LESS_THAN, + LESS_OR_EQUAL_THAN, + GREATER_THAN, + GREATER_OR_EQUAL_THAN; diff --git a/db/src/main/java/de/muehlencord/shared/db/StandardController.java b/db/src/main/java/de/muehlencord/shared/db/StandardController.java index ec48346..adb573f 100644 --- a/db/src/main/java/de/muehlencord/shared/db/StandardController.java +++ b/db/src/main/java/de/muehlencord/shared/db/StandardController.java @@ -59,6 +59,11 @@ public class StandardController extends CommonAbstractController { @Lock(LockType.READ) public List find(Class clazz, Map filters, List orderFields) { + return find(clazz, filters, orderFields, 0, 0); + } + + @Lock(LockType.READ) + public List find(Class clazz, Map filters, List orderFields, int limit, int offset) { final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaQuery criteria = cb.createQuery(clazz); @@ -69,7 +74,36 @@ public class StandardController extends CommonAbstractController { } List orderList = new ArrayList<>(); orderFields.stream().forEachOrdered(field -> orderList.add(cb.asc(r.get(field)))); - final TypedQuery query = em.createQuery(criteria.orderBy(orderList)); + final TypedQuery query = em.createQuery(criteria.orderBy(orderList)) + .setFirstResult(offset); + if (limit > 0) { + query.setMaxResults(limit); + } + + return query.getResultList(); + } + + @Lock(LockType.READ) + public List find(Class clazz, List filters, List orderFields) throws ControllerException { + return find(clazz, filters, orderFields, 0, 0); + } + + @Lock(LockType.READ) + public List find(Class clazz, List filters, List orderFields, int limit, int offset) throws ControllerException { + final CriteriaBuilder cb = em.getCriteriaBuilder(); + final CriteriaQuery criteria = cb.createQuery(clazz); + + final Root r = criteria.from(clazz); + Predicate filterCondition = getFilterCondition(cb, r, filters); + if (filterCondition != null) { + criteria.where(filterCondition); + } + List orderList = new ArrayList<>(); + orderFields.stream().forEachOrdered(field -> orderList.add(cb.asc(r.get(field)))); + final TypedQuery query = em.createQuery(criteria.orderBy(orderList)).setFirstResult(offset); + if (limit > 0) { + query.setMaxResults(limit); + } return query.getResultList(); }