diff --git a/src/main/java/com/kodgemisi/specification/CriteriaOperation.java b/src/main/java/com/kodgemisi/specification/CriteriaOperation.java index 2bcbaba..3df32fd 100644 --- a/src/main/java/com/kodgemisi/specification/CriteriaOperation.java +++ b/src/main/java/com/kodgemisi/specification/CriteriaOperation.java @@ -5,11 +5,10 @@ * * @author Destan Sarpkaya * @author Ersan Ceylan + * @author Sedat Gokcen */ -enum CriteriaOperation { +enum CriteriaOperation implements Operation { - JOIN, - JOIN_FETCH, EQUAL, EQUAL_TO_MANY, EQUAL_TO_ONE, diff --git a/src/main/java/com/kodgemisi/specification/FilterCriteria.java b/src/main/java/com/kodgemisi/specification/FilterCriteria.java index 0b04ae3..87d0982 100644 --- a/src/main/java/com/kodgemisi/specification/FilterCriteria.java +++ b/src/main/java/com/kodgemisi/specification/FilterCriteria.java @@ -4,14 +4,13 @@ import lombok.Setter; import org.springframework.lang.NonNull; -import javax.persistence.criteria.JoinType; - /** * Created on October, 2018 * * @author Destan Sarpkaya * @author Ersan Ceylan * @author Gökhan Birinci + * @author Sedat Gokcen */ /** @@ -28,38 +27,25 @@ class FilterCriteria { private final T value; @NonNull - private final CriteriaOperation operation; - - private final JoinType joinType; + private final Operation operation; private final Class clazz; private final RelationType relationType; - FilterCriteria(String key, T value, CriteriaOperation operation, Class clazz) { + FilterCriteria(String key, T value, Operation operation, Class clazz, RelationType relationType) { this.key = key; this.value = value; this.operation = operation; - this.joinType = null; this.clazz = clazz; - this.relationType = RelationType.NO_RELATION; + this.relationType = relationType; } - FilterCriteria(String key, T value, CriteriaOperation operation, Class clazz, RelationType relationType) { - this.key = key; - this.value = value; - this.operation = operation; - this.joinType = null; - this.clazz = clazz; - this.relationType = relationType; + FilterCriteria(String key, T value, Operation operation, Class clazz) { + this(key, value, operation, clazz, RelationType.NO_RELATION); } - FilterCriteria(String key, CriteriaOperation operation, JoinType joinType, Class clazz) { - this.key = key; - this.operation = operation; - this.joinType = joinType; - this.clazz = clazz; - this.value = null; - this.relationType = RelationType.NO_RELATION; + FilterCriteria(String key, Operation operation, Class clazz) { + this(key, null, operation, clazz, RelationType.NO_RELATION); } } \ No newline at end of file diff --git a/src/main/java/com/kodgemisi/specification/GenericSpecification.java b/src/main/java/com/kodgemisi/specification/GenericSpecification.java index 391b0d2..4f4a5b9 100644 --- a/src/main/java/com/kodgemisi/specification/GenericSpecification.java +++ b/src/main/java/com/kodgemisi/specification/GenericSpecification.java @@ -20,6 +20,7 @@ * @author Destan Sarpkaya * @author Ersan Ceylan * @author Gökhan Birinci + * @author Sedat Gokcen */ @SuppressWarnings({"rawtypes", "unchecked"}) @@ -31,70 +32,78 @@ class GenericSpecification> implements Spe @Override public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) { - final CriteriaOperation operation = filterCriteria.getOperation(); + final Operation operation = filterCriteria.getOperation(); final String key = filterCriteria.getKey(); - switch (operation) { - case JOIN: { - final JoinType joinType = filterCriteria.getJoinType(); - root.join(key, joinType); + if (operation instanceof JoinOperation) { + JoinOperation joinOperation = (JoinOperation) operation; + processJoinOperation(joinOperation, key, root, query); return null; } - case JOIN_FETCH: { - final Class clazz = query.getResultType(); - final JoinType joinType = filterCriteria.getJoinType(); - if (clazz.equals(Long.class) || clazz.equals(long.class)) { - // If clazz is long then it's a count query for pageable - root.join(key, joinType); - return null; + final CriteriaOperation criteriaOperation = (CriteriaOperation) operation; + + switch (criteriaOperation) { + case EQUAL: { + final Path path = resolvePath(root, filterCriteria.getKey(), filterCriteria.getRelationType()); + return criteriaBuilder.equal(path, filterCriteria.getValue()); } - else { - root.fetch(key, joinType); - return null; + + case LIKE: { + final Path path = resolvePath(root, filterCriteria.getKey(), filterCriteria.getRelationType()); + return criteriaBuilder.like(path.as(String.class), "%" + filterCriteria.getValue() + "%"); } - } - case EQUAL: { - final Path path = resolvePath(root, filterCriteria.getKey(), filterCriteria.getRelationType()); - return criteriaBuilder.equal(path, filterCriteria.getValue()); - } - case LIKE: { - final Path path = resolvePath(root, filterCriteria.getKey(), filterCriteria.getRelationType()); - return criteriaBuilder.like(path.as(String.class), "%" + filterCriteria.getValue() + "%"); - } + case IN: { + final Path path = resolvePath(root, filterCriteria.getKey(), filterCriteria.getRelationType()); + return path.in(filterCriteria.getValue()); + } - case IN: { - final Path path = resolvePath(root, filterCriteria.getKey(), filterCriteria.getRelationType()); - return path.in(filterCriteria.getValue()); - } + case GREATER_THAN: { + final ComparableFilterCriteria comparableFilterCriteria = getComparableFilterCriteria(); + final Path path = resolvePath(root, filterCriteria.getKey(), filterCriteria.getRelationType()); + return criteriaBuilder.greaterThan(path.as(comparableFilterCriteria.getClazz()), comparableFilterCriteria.getValue()); + } - case GREATER_THAN: { - final ComparableFilterCriteria comparableFilterCriteria = getComparableFilterCriteria(); - final Path path = resolvePath(root, filterCriteria.getKey(), filterCriteria.getRelationType()); - return criteriaBuilder.greaterThan(path.as(comparableFilterCriteria.getClazz()), comparableFilterCriteria.getValue()); - } + case GREATER_THAN_OR_EQUAL_TO: { + final ComparableFilterCriteria comparableFilterCriteria = getComparableFilterCriteria(); + final Path path = resolvePath(root, filterCriteria.getKey(), filterCriteria.getRelationType()); + return criteriaBuilder.greaterThanOrEqualTo(path.as(comparableFilterCriteria.getClazz()), comparableFilterCriteria.getValue()); + } - case GREATER_THAN_OR_EQUAL_TO: { - final ComparableFilterCriteria comparableFilterCriteria = getComparableFilterCriteria(); - final Path path = resolvePath(root, filterCriteria.getKey(), filterCriteria.getRelationType()); - return criteriaBuilder.greaterThanOrEqualTo(path.as(comparableFilterCriteria.getClazz()), comparableFilterCriteria.getValue()); - } + case LESS_THAN: { + final ComparableFilterCriteria comparableFilterCriteria = getComparableFilterCriteria(); + final Path path = resolvePath(root, filterCriteria.getKey(), filterCriteria.getRelationType()); + return criteriaBuilder.lessThan(path.as(comparableFilterCriteria.getClazz()), comparableFilterCriteria.getValue()); + } + + case LESS_THAN_OR_EQUAL_TO: { + final ComparableFilterCriteria comparableFilterCriteria = getComparableFilterCriteria(); + final Path path = resolvePath(root, filterCriteria.getKey(), filterCriteria.getRelationType()); + return criteriaBuilder.lessThanOrEqualTo(path.as(comparableFilterCriteria.getClazz()), comparableFilterCriteria.getValue()); + } - case LESS_THAN: { - final ComparableFilterCriteria comparableFilterCriteria = getComparableFilterCriteria(); - final Path path = resolvePath(root, filterCriteria.getKey(), filterCriteria.getRelationType()); - return criteriaBuilder.lessThan(path.as(comparableFilterCriteria.getClazz()), comparableFilterCriteria.getValue()); + default: + return null; } + } + + private void processJoinOperation(JoinOperation joinOperation, String key, Root root, CriteriaQuery query) { + final JoinType joinType = joinOperation.getType(); - case LESS_THAN_OR_EQUAL_TO: { - final ComparableFilterCriteria comparableFilterCriteria = getComparableFilterCriteria(); - final Path path = resolvePath(root, filterCriteria.getKey(), filterCriteria.getRelationType()); - return criteriaBuilder.lessThanOrEqualTo(path.as(comparableFilterCriteria.getClazz()), comparableFilterCriteria.getValue()); + if (joinOperation == JoinOperation.JOIN) { + root.join(key, joinType); + return; } - default: - return null; + final Class clazz = query.getResultType(); + + if (clazz.equals(Long.class) || clazz.equals(long.class)) { + // If clazz is long then it's a count query for pageable + root.join(key, joinType); + } + else { + root.fetch(key, joinType); } } diff --git a/src/main/java/com/kodgemisi/specification/GenericSpecificationBuilder.java b/src/main/java/com/kodgemisi/specification/GenericSpecificationBuilder.java index 2e0b288..77437ce 100644 --- a/src/main/java/com/kodgemisi/specification/GenericSpecificationBuilder.java +++ b/src/main/java/com/kodgemisi/specification/GenericSpecificationBuilder.java @@ -27,6 +27,7 @@ * @author Destan Sarpkaya * @author Ersan Ceylan * @author Gökhan Birinci + * @author Sedat Gokcen */ public class GenericSpecificationBuilder { @@ -55,8 +56,8 @@ public static GenericSpecificationBuilder of(Class clazz) { return new GenericSpecificationBuilder<>(); } - private GenericSpecificationBuilder addCriteria(String key, CriteriaOperation operation, JoinType joinType) { - filterCriteriaList.add(new FilterCriteria(key, operation, joinType, Void.class)); + private GenericSpecificationBuilder addCriteria(String key, Operation operation) { + filterCriteriaList.add(new FilterCriteria(key, operation, Void.class)); return this; } @@ -82,7 +83,7 @@ private > GenericSpecificationBuilder addCom * @return */ public GenericSpecificationBuilder join(String key) { - return addCriteria(key, CriteriaOperation.JOIN, JoinType.INNER); + return addCriteria(key, JoinOperation.JOIN.type(JoinType.INNER)); } /** @@ -92,7 +93,7 @@ public GenericSpecificationBuilder join(String key) { * @return */ public GenericSpecificationBuilder join(String key, JoinType joinType) { - return addCriteria(key, CriteriaOperation.JOIN, joinType); + return addCriteria(key, JoinOperation.JOIN.type(joinType)); } /** @@ -101,7 +102,7 @@ public GenericSpecificationBuilder join(String key, JoinType joinType) { * @return */ public GenericSpecificationBuilder joinFetch(String key) { - return addCriteria(key, CriteriaOperation.JOIN_FETCH, JoinType.INNER); + return addCriteria(key, JoinOperation.JOIN_FETCH.type(JoinType.INNER)); } /** @@ -111,7 +112,7 @@ public GenericSpecificationBuilder joinFetch(String key) { * @return */ public GenericSpecificationBuilder joinFetch(String key, JoinType joinType) { - return addCriteria(key, CriteriaOperation.JOIN_FETCH, joinType); + return addCriteria(key, JoinOperation.JOIN_FETCH.type(joinType)); } /** diff --git a/src/main/java/com/kodgemisi/specification/JoinOperation.java b/src/main/java/com/kodgemisi/specification/JoinOperation.java new file mode 100644 index 0000000..5c00b25 --- /dev/null +++ b/src/main/java/com/kodgemisi/specification/JoinOperation.java @@ -0,0 +1,24 @@ +package com.kodgemisi.specification; + +import javax.persistence.criteria.JoinType; + +/** + * Created on November, 2018 + * + * @author Sedat Gokcen + */ +public enum JoinOperation implements Operation { + JOIN, + JOIN_FETCH; + + private JoinType type = JoinType.INNER; + + public JoinOperation type(JoinType type) { + this.type = type; + return this; + } + + public JoinType getType() { + return type; + } +} \ No newline at end of file diff --git a/src/main/java/com/kodgemisi/specification/Operation.java b/src/main/java/com/kodgemisi/specification/Operation.java new file mode 100644 index 0000000..9b376df --- /dev/null +++ b/src/main/java/com/kodgemisi/specification/Operation.java @@ -0,0 +1,9 @@ +package com.kodgemisi.specification; + +/** + * Created on November, 2018 + * + * @author Sedat Gokcen + */ +interface Operation { +}