package org.baeldung.um.persistence.util; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import javax.persistence.metamodel.SingularAttribute; import org.baeldung.common.persistence.model.IEntity; import org.baeldung.common.search.ClientOperation; import org.baeldung.common.util.QueryConstants; import org.baeldung.um.persistence.model.Principal; import org.baeldung.um.persistence.model.Principal_; import org.baeldung.um.persistence.model.Privilege; import org.baeldung.um.persistence.model.Privilege_; import org.baeldung.um.persistence.model.Role; import org.baeldung.um.persistence.model.Role_; import org.springframework.data.jpa.domain.Specification; /** * The query specifications are built manually here; this is a limitation and should be contained to this only class */ @SuppressWarnings("unchecked") public final class QuerySpecificationSec { private QuerySpecificationSec() { throw new UnsupportedOperationException(); } // API - retrieve specifications for all OPs and all supported classes public static <T extends IEntity> Specification<T> getByNameSpecification(final Class<T> clazz, final ClientOperation op, final String name, final boolean negated) { switch (op) { case EQ: return getByNameSpecificationEq(clazz, name, negated); case NEG_EQ: return getByNameSpecificationEq(clazz, name, negated); case CONTAINS: return getByNameSpecificationContains(clazz, name, negated); case STARTS_WITH: return getByNameSpecificationStartsWith(clazz, name, negated); case ENDS_WITH: return getByNameSpecificationEndsWith(clazz, name, negated); case NEG_CONTAINS: return getByNameSpecificationContains(clazz, name, negated); case NEG_STARTS_WITH: return getByNameSpecificationStartsWith(clazz, name, negated); case NEG_ENDS_WITH: return getByNameSpecificationEndsWith(clazz, name, negated); default: break; } throw new UnsupportedOperationException("Received invalid operator: " + op); } // in between // id public static <T extends IEntity> Specification<T> getByIdSpecification(final Class<T> clazz, final Long id, final boolean negated) { if (clazz.equals(Role.class)) { return (Specification<T>) roleByIdEq(id, negated); } if (clazz.equals(Principal.class)) { return (Specification<T>) userByIdEq(id, negated); } if (clazz.equals(Privilege.class)) { return (Specification<T>) privilegeByIdEq(id, negated); } return null; } // name static <T extends IEntity> Specification<T> getByNameSpecificationEq(final Class<T> clazz, final String name, final boolean negated) { if (clazz.equals(Role.class)) { return (Specification<T>) roleByNameEq(name, negated); } if (clazz.equals(Principal.class)) { return (Specification<T>) userByNameEq(name, negated); } if (clazz.equals(Privilege.class)) { return (Specification<T>) privilegeByNameEq(name, negated); } return null; } static <T extends IEntity> Specification<T> getByNameSpecificationContains(final Class<T> clazz, final String name, final boolean negated) { if (clazz.equals(Role.class)) { return (Specification<T>) roleByNameContains(name, negated); } if (clazz.equals(Principal.class)) { return (Specification<T>) userByNameContains(name, negated); } if (clazz.equals(Privilege.class)) { return (Specification<T>) privilegeByNameContains(name, negated); } return null; } static <T extends IEntity> Specification<T> getByNameSpecificationStartsWith(final Class<T> clazz, final String name, final boolean negated) { if (clazz.equals(Role.class)) { return (Specification<T>) roleByNameStartsWith(name, negated); } if (clazz.equals(Principal.class)) { return (Specification<T>) userByNameStartsWith(name, negated); } if (clazz.equals(Privilege.class)) { return (Specification<T>) privilegeByNameStartsWith(name, negated); } return null; } static <T extends IEntity> Specification<T> getByNameSpecificationEndsWith(final Class<T> clazz, final String name, final boolean negated) { if (clazz.equals(Role.class)) { return (Specification<T>) roleByNameEndsWith(name, negated); } if (clazz.equals(Principal.class)) { return (Specification<T>) userByNameEndsWith(name, negated); } if (clazz.equals(Privilege.class)) { return (Specification<T>) privilegeByNameEndsWith(name, negated); } return null; } // individual specifications // user private static Specification<Principal> userByIdEq(final Long id, final boolean negated) { return new Specification<Principal>() { @Override public final Predicate toPredicate(final Root<Principal> root, final CriteriaQuery<?> query, final CriteriaBuilder builder) { if (negated) { return builder.notEqual(root.get(Principal_.id), id); } return builder.equal(root.get(Principal_.id), id); } }; } private static Specification<Principal> userByNameEq(final String name, final boolean negated) { return QuerySpecificationSec.<Principal> entityByKeyEq(name, negated, Principal_.name); } private static Specification<Principal> userByNameContains(final String name, final boolean negated) { return QuerySpecificationSec.<Principal> entityByKeyContains(name, negated, Principal_.name); } private static Specification<Principal> userByNameStartsWith(final String name, final boolean negated) { return QuerySpecificationSec.<Principal> entityByKeyStartsWith(name, negated, Principal_.name); } private static Specification<Principal> userByNameEndsWith(final String name, final boolean negated) { return QuerySpecificationSec.<Principal> entityByKeyEndsWith(name, negated, Principal_.name); } // role private static Specification<Role> roleByIdEq(final Long id, final boolean negated) { return new Specification<Role>() { @Override public final Predicate toPredicate(final Root<Role> root, final CriteriaQuery<?> query, final CriteriaBuilder builder) { if (negated) { return builder.notEqual(root.get(Role_.id), id); } return builder.equal(root.get(Role_.id), id); } }; } private static Specification<Role> roleByNameEq(final String name, final boolean negated) { return QuerySpecificationSec.<Role> entityByKeyEq(name, negated, Role_.name); } private static Specification<Role> roleByNameContains(final String name, final boolean negated) { return QuerySpecificationSec.<Role> entityByKeyContains(name, negated, Role_.name); } private static Specification<Role> roleByNameEndsWith(final String name, final boolean negated) { return QuerySpecificationSec.<Role> entityByKeyEndsWith(name, negated, Role_.name); } private static Specification<Role> roleByNameStartsWith(final String name, final boolean negated) { return QuerySpecificationSec.<Role> entityByKeyStartsWith(name, negated, Role_.name); } // privilege private static Specification<Privilege> privilegeByIdEq(final Long id, final boolean negated) { return new Specification<Privilege>() { @Override public final Predicate toPredicate(final Root<Privilege> root, final CriteriaQuery<?> query, final CriteriaBuilder builder) { if (negated) { return builder.notEqual(root.get(Privilege_.id), id); } return builder.equal(root.get(Privilege_.id), id); } }; } private static Specification<Privilege> privilegeByNameEq(final String name, final boolean negated) { return QuerySpecificationSec.<Privilege> entityByKeyEq(name, negated, Privilege_.name); } private static Specification<Privilege> privilegeByNameContains(final String name, final boolean negated) { return QuerySpecificationSec.<Privilege> entityByKeyContains(name, negated, Privilege_.name); } private static Specification<Privilege> privilegeByNameStartsWith(final String name, final boolean negated) { return QuerySpecificationSec.<Privilege> entityByKeyStartsWith(name, negated, Privilege_.name); } private static Specification<Privilege> privilegeByNameEndsWith(final String name, final boolean negated) { return QuerySpecificationSec.<Privilege> entityByKeyEndsWith(name, negated, Privilege_.name); } private static Specification<Privilege> privilegeByDescriptionEq(final String description, final boolean negated) { return QuerySpecificationSec.<Privilege> entityByKeyEq(description, negated, Privilege_.description); } private static Specification<Privilege> privilegeByDescriptionContains(final String description, final boolean negated) { return QuerySpecificationSec.<Privilege> entityByKeyContains(description, negated, Privilege_.description); } private static Specification<Privilege> privilegeByDescriptionStartsWith(final String description, final boolean negated) { return QuerySpecificationSec.<Privilege> entityByKeyStartsWith(description, negated, Privilege_.description); } private static Specification<Privilege> privilegeByDescriptionEndsWith(final String description, final boolean negated) { return QuerySpecificationSec.<Privilege> entityByKeyEndsWith(description, negated, Privilege_.description); } // generic private static <T extends IEntity> Specification<T> entityByKeyEndsWith(final String value, final boolean negated, final SingularAttribute<T, String> metaField) { return new Specification<T>() { @Override public final Predicate toPredicate(final Root<T> root, final CriteriaQuery<?> query, final CriteriaBuilder builder) { if (negated) { return builder.notLike(builder.lower(root.get(metaField)), QueryConstants.ANY_SERVER + value.toLowerCase()); } return builder.like(builder.lower(root.get(metaField)), QueryConstants.ANY_SERVER + value.toLowerCase()); } }; } private static <T extends IEntity> Specification<T> entityByKeyStartsWith(final String value, final boolean negated, final SingularAttribute<T, String> metaField) { return new Specification<T>() { @Override public final Predicate toPredicate(final Root<T> root, final CriteriaQuery<?> query, final CriteriaBuilder builder) { if (negated) { return builder.notLike(builder.lower(root.get(metaField)), value.toLowerCase() + QueryConstants.ANY_SERVER); } return builder.like(builder.lower(root.get(metaField)), value.toLowerCase() + QueryConstants.ANY_SERVER); } }; } private static <T extends IEntity> Specification<T> entityByKeyContains(final String value, final boolean negated, final SingularAttribute<T, String> metaField) { return new Specification<T>() { @Override public final Predicate toPredicate(final Root<T> root, final CriteriaQuery<?> query, final CriteriaBuilder builder) { if (negated) { return builder.notLike(builder.lower(root.get(metaField)), QueryConstants.ANY_SERVER + value.toLowerCase() + QueryConstants.ANY_SERVER); } return builder.like(builder.lower(root.get(metaField)), QueryConstants.ANY_SERVER + value.toLowerCase() + QueryConstants.ANY_SERVER); } }; } private static <T extends IEntity> Specification<T> entityByKeyEq(final String value, final boolean negated, final SingularAttribute<T, String> metaField) { return new Specification<T>() { @Override public final Predicate toPredicate(final Root<T> root, final CriteriaQuery<?> query, final CriteriaBuilder builder) { if (negated) { return builder.notEqual(builder.lower(root.get(metaField)), value.toLowerCase()); } return builder.equal(builder.lower(root.get(metaField)), value.toLowerCase()); } }; } }