Skip to content

Commit df0bf81

Browse files
author
talhadilber
committed
folder refactor
1 parent 89da23a commit df0bf81

33 files changed

+865
-867
lines changed

src/main/java/com/beyt/filter/DatabaseFilterManager.java renamed to src/main/java/com/beyt/query/DynamicQueryManager.java

Lines changed: 345 additions & 345 deletions
Large diffs are not rendered by default.

src/main/java/com/beyt/filter/GenericSpecification.java renamed to src/main/java/com/beyt/query/DynamicSpecification.java

Lines changed: 145 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -1,145 +1,145 @@
1-
package com.beyt.filter;
2-
3-
import com.beyt.dto.Criteria;
4-
import com.beyt.dto.enums.CriteriaType;
5-
import com.beyt.dto.enums.JoinType;
6-
import com.beyt.exception.DynamicQueryNoAvailableEnumException;
7-
import com.beyt.exception.DynamicQueryNoAvailableOperationException;
8-
import com.beyt.exception.DynamicQueryNoAvailableOrOperationUsageException;
9-
import com.beyt.exception.DynamicQueryNoAvailableParenthesesOperationUsageException;
10-
import com.beyt.util.ReflectionUtil;
11-
import com.beyt.util.SpecificationUtil;
12-
import org.apache.commons.lang3.tuple.ImmutableTriple;
13-
import org.apache.commons.lang3.tuple.Triple;
14-
import org.springframework.data.jpa.domain.Specification;
15-
import org.springframework.data.util.Pair;
16-
17-
import javax.persistence.criteria.*;
18-
import java.util.*;
19-
import java.util.concurrent.ConcurrentHashMap;
20-
21-
/**
22-
* Created by tdilber at 24-Aug-19
23-
*/
24-
25-
public class GenericSpecification<Entity> implements Specification<Entity> {
26-
27-
protected List<Criteria> criteriaList;
28-
protected Map<Triple<From<?, ?>, String, JoinType>, Join<?, ?>> joinMap = new ConcurrentHashMap<>();
29-
30-
public GenericSpecification(List<Criteria> criteriaList) {
31-
this.criteriaList = criteriaList;
32-
}
33-
34-
@Override
35-
public Predicate toPredicate(Root<Entity> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
36-
List<Predicate> predicateAndList = new ArrayList<>();
37-
List<Predicate> predicateOrList = new ArrayList<>();
38-
for (int i = 0; i < criteriaList.size(); i++) {
39-
if (criteriaList.get(i).operation == CriteriaType.PARENTHES) {
40-
SpecificationUtil.checkHasFirstValue(criteriaList.get(i));
41-
try {
42-
predicateAndList.add(new GenericSpecification<Entity>(((List<Criteria>) (criteriaList.get(i).values.get(0)))).toPredicate(root, query, builder));
43-
} catch (Exception e) {
44-
throw new DynamicQueryNoAvailableParenthesesOperationUsageException(
45-
"There is No Available Paranthes Operation Usage in Criteria Key: " + criteriaList.get(i).key);
46-
}
47-
} else if (criteriaList.get(i).operation == CriteriaType.OR) {
48-
if (i == 0 || i + 1 == criteriaList.size()) {
49-
throw new DynamicQueryNoAvailableOrOperationUsageException(
50-
"There is No Available OR Operation Usage in Criteria Key: " + criteriaList.get(i).key);
51-
}
52-
53-
predicateOrList.add(builder.and(predicateAndList.toArray(new Predicate[0])));
54-
predicateAndList.clear();
55-
} else {
56-
predicateAndList.add(getPredicate(root, builder, criteriaList.get(i)));
57-
}
58-
}
59-
60-
predicateOrList.add(builder.and(predicateAndList.toArray(new Predicate[0])));
61-
62-
return builder.or(predicateOrList.toArray(new Predicate[0]));
63-
}
64-
65-
private Predicate getPredicate(Root<Entity> root, CriteriaBuilder builder, Criteria criteria) {
66-
From<?, ?> localFrom = createLocalFrom(root, criteria.key);
67-
return addPredicate(localFrom, builder, new Criteria(getFieldName(criteria.key), criteria.operation, criteria.values.toArray(new Object[0])));
68-
}
69-
70-
public From<?, ?> createLocalFrom(Root<?> root, String key) {
71-
From<?, ?> localFrom = root;
72-
List<Pair<String, JoinType>> fieldJoins = getFieldJoins(key);
73-
74-
for (Pair<String, JoinType> fieldJoin : fieldJoins) {
75-
localFrom = getJoin(localFrom, fieldJoin.getFirst(), fieldJoin.getSecond());
76-
}
77-
78-
return localFrom;
79-
}
80-
81-
public static List<Pair<String, JoinType>> getFieldJoins(String key) {
82-
List<Pair<String, JoinType>> fieldJoins = new ArrayList<>();
83-
84-
String subKey = key;
85-
JoinType joinType = null;
86-
int index = -1;
87-
88-
89-
while (subKey.chars().anyMatch(c -> Arrays.stream(JoinType.values()).anyMatch(j -> j.getSeparator().charValue() == c))) {
90-
91-
for (JoinType value : JoinType.values()) {
92-
int indexOf = subKey.indexOf(value.getSeparator());
93-
if (indexOf > -1 && (index == -1 || indexOf < index)) {
94-
index = indexOf;
95-
joinType = value;
96-
}
97-
}
98-
99-
if (Objects.nonNull(joinType)) {
100-
fieldJoins.add(Pair.of(subKey.substring(0, index), joinType));
101-
subKey = subKey.substring(index + 1);
102-
}
103-
104-
index = -1;
105-
joinType = null;
106-
}
107-
108-
return fieldJoins;
109-
}
110-
111-
public static String getFieldName(String key) {
112-
String[] splitedKey = key.split(">|<|\\.");
113-
return splitedKey[splitedKey.length - 1];
114-
}
115-
116-
private Predicate addPredicate(Path<?> root, CriteriaBuilder builder, Criteria criteria) {
117-
if (!criteria.operation.equals(CriteriaType.SPECIFIED)) {
118-
try {
119-
criteria.values = ReflectionUtil.convertObjectArrayToIfNotAvailable(root.get(criteria.key).getJavaType(), criteria.values);
120-
} catch (Exception e) {
121-
throw new DynamicQueryNoAvailableEnumException("There is a "
122-
+ root.get(criteria.key).getJavaType().getSimpleName() + " Enum Problem in Criteria Key: "
123-
+ criteria.key, e);
124-
}
125-
}
126-
127-
if (DatabaseFilterManager.specificationRuleMap.containsKey(criteria.operation)) {
128-
return DatabaseFilterManager.specificationRuleMap
129-
.get(criteria.operation).generatePredicate(root, builder, criteria);
130-
} else {
131-
throw new DynamicQueryNoAvailableOperationException("There is No Available Operation in Criteria Key: "
132-
+ criteria.key);
133-
}
134-
}
135-
136-
protected Join<?, ?> getJoin(From<?, ?> from, String key, JoinType joinType) {
137-
Triple<From<?, ?>, String, JoinType> joinMapKey = new ImmutableTriple<>(from, key, joinType);
138-
if (joinMap.containsKey(joinMapKey)) {
139-
return joinMap.get(joinMapKey);
140-
}
141-
Join<?, ?> join = from.join(key, joinType.getJoinType());
142-
joinMap.put(joinMapKey, join);
143-
return join;
144-
}
145-
}
1+
package com.beyt.query;
2+
3+
import com.beyt.dto.Criteria;
4+
import com.beyt.dto.enums.CriteriaType;
5+
import com.beyt.dto.enums.JoinType;
6+
import com.beyt.exception.DynamicQueryNoAvailableEnumException;
7+
import com.beyt.exception.DynamicQueryNoAvailableOperationException;
8+
import com.beyt.exception.DynamicQueryNoAvailableOrOperationUsageException;
9+
import com.beyt.exception.DynamicQueryNoAvailableParenthesesOperationUsageException;
10+
import com.beyt.util.ReflectionUtil;
11+
import com.beyt.util.SpecificationUtil;
12+
import org.apache.commons.lang3.tuple.ImmutableTriple;
13+
import org.apache.commons.lang3.tuple.Triple;
14+
import org.springframework.data.jpa.domain.Specification;
15+
import org.springframework.data.util.Pair;
16+
17+
import javax.persistence.criteria.*;
18+
import java.util.*;
19+
import java.util.concurrent.ConcurrentHashMap;
20+
21+
/**
22+
* Created by tdilber at 24-Aug-19
23+
*/
24+
25+
public class DynamicSpecification<Entity> implements Specification<Entity> {
26+
27+
protected List<Criteria> criteriaList;
28+
protected Map<Triple<From<?, ?>, String, JoinType>, Join<?, ?>> joinMap = new ConcurrentHashMap<>();
29+
30+
public DynamicSpecification(List<Criteria> criteriaList) {
31+
this.criteriaList = criteriaList;
32+
}
33+
34+
@Override
35+
public Predicate toPredicate(Root<Entity> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
36+
List<Predicate> predicateAndList = new ArrayList<>();
37+
List<Predicate> predicateOrList = new ArrayList<>();
38+
for (int i = 0; i < criteriaList.size(); i++) {
39+
if (criteriaList.get(i).operation == CriteriaType.PARENTHES) {
40+
SpecificationUtil.checkHasFirstValue(criteriaList.get(i));
41+
try {
42+
predicateAndList.add(new DynamicSpecification<Entity>(((List<Criteria>) (criteriaList.get(i).values.get(0)))).toPredicate(root, query, builder));
43+
} catch (Exception e) {
44+
throw new DynamicQueryNoAvailableParenthesesOperationUsageException(
45+
"There is No Available Paranthes Operation Usage in Criteria Key: " + criteriaList.get(i).key);
46+
}
47+
} else if (criteriaList.get(i).operation == CriteriaType.OR) {
48+
if (i == 0 || i + 1 == criteriaList.size()) {
49+
throw new DynamicQueryNoAvailableOrOperationUsageException(
50+
"There is No Available OR Operation Usage in Criteria Key: " + criteriaList.get(i).key);
51+
}
52+
53+
predicateOrList.add(builder.and(predicateAndList.toArray(new Predicate[0])));
54+
predicateAndList.clear();
55+
} else {
56+
predicateAndList.add(getPredicate(root, builder, criteriaList.get(i)));
57+
}
58+
}
59+
60+
predicateOrList.add(builder.and(predicateAndList.toArray(new Predicate[0])));
61+
62+
return builder.or(predicateOrList.toArray(new Predicate[0]));
63+
}
64+
65+
private Predicate getPredicate(Root<Entity> root, CriteriaBuilder builder, Criteria criteria) {
66+
From<?, ?> localFrom = createLocalFrom(root, criteria.key);
67+
return addPredicate(localFrom, builder, new Criteria(getFieldName(criteria.key), criteria.operation, criteria.values.toArray(new Object[0])));
68+
}
69+
70+
public From<?, ?> createLocalFrom(Root<?> root, String key) {
71+
From<?, ?> localFrom = root;
72+
List<Pair<String, JoinType>> fieldJoins = getFieldJoins(key);
73+
74+
for (Pair<String, JoinType> fieldJoin : fieldJoins) {
75+
localFrom = getJoin(localFrom, fieldJoin.getFirst(), fieldJoin.getSecond());
76+
}
77+
78+
return localFrom;
79+
}
80+
81+
public static List<Pair<String, JoinType>> getFieldJoins(String key) {
82+
List<Pair<String, JoinType>> fieldJoins = new ArrayList<>();
83+
84+
String subKey = key;
85+
JoinType joinType = null;
86+
int index = -1;
87+
88+
89+
while (subKey.chars().anyMatch(c -> Arrays.stream(JoinType.values()).anyMatch(j -> j.getSeparator().charValue() == c))) {
90+
91+
for (JoinType value : JoinType.values()) {
92+
int indexOf = subKey.indexOf(value.getSeparator());
93+
if (indexOf > -1 && (index == -1 || indexOf < index)) {
94+
index = indexOf;
95+
joinType = value;
96+
}
97+
}
98+
99+
if (Objects.nonNull(joinType)) {
100+
fieldJoins.add(Pair.of(subKey.substring(0, index), joinType));
101+
subKey = subKey.substring(index + 1);
102+
}
103+
104+
index = -1;
105+
joinType = null;
106+
}
107+
108+
return fieldJoins;
109+
}
110+
111+
public static String getFieldName(String key) {
112+
String[] splitedKey = key.split(">|<|\\.");
113+
return splitedKey[splitedKey.length - 1];
114+
}
115+
116+
private Predicate addPredicate(Path<?> root, CriteriaBuilder builder, Criteria criteria) {
117+
if (!criteria.operation.equals(CriteriaType.SPECIFIED)) {
118+
try {
119+
criteria.values = ReflectionUtil.convertObjectArrayToIfNotAvailable(root.get(criteria.key).getJavaType(), criteria.values);
120+
} catch (Exception e) {
121+
throw new DynamicQueryNoAvailableEnumException("There is a "
122+
+ root.get(criteria.key).getJavaType().getSimpleName() + " Enum Problem in Criteria Key: "
123+
+ criteria.key, e);
124+
}
125+
}
126+
127+
if (DynamicQueryManager.specificationRuleMap.containsKey(criteria.operation)) {
128+
return DynamicQueryManager.specificationRuleMap
129+
.get(criteria.operation).generatePredicate(root, builder, criteria);
130+
} else {
131+
throw new DynamicQueryNoAvailableOperationException("There is No Available Operation in Criteria Key: "
132+
+ criteria.key);
133+
}
134+
}
135+
136+
protected Join<?, ?> getJoin(From<?, ?> from, String key, JoinType joinType) {
137+
Triple<From<?, ?>, String, JoinType> joinMapKey = new ImmutableTriple<>(from, key, joinType);
138+
if (joinMap.containsKey(joinMapKey)) {
139+
return joinMap.get(joinMapKey);
140+
}
141+
Join<?, ?> join = from.join(key, joinType.getJoinType());
142+
joinMap.put(joinMapKey, join);
143+
return join;
144+
}
145+
}

src/main/java/com/beyt/filter/query/builder/QueryBuilder.java renamed to src/main/java/com/beyt/query/builder/QueryBuilder.java

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
1-
package com.beyt.filter.query.builder;
1+
package com.beyt.query.builder;
22

33
import com.beyt.dto.Criteria;
44
import com.beyt.dto.DynamicQuery;
5-
import com.beyt.filter.DatabaseFilterManager;
6-
import com.beyt.filter.query.builder.interfaces.*;
7-
import com.beyt.filter.query.simplifier.QuerySimplifier;
8-
import com.beyt.repository.GenericSpecificationRepository;
5+
import com.beyt.query.DynamicQueryManager;
6+
import com.beyt.query.builder.interfaces.*;
7+
import com.beyt.repository.DynamicSpecificationRepository;
98
import org.springframework.data.domain.Page;
109
import org.springframework.data.util.Pair;
1110

1211
import java.util.Arrays;
1312
import java.util.List;
1413
import java.util.stream.Collectors;
1514

16-
@SuppressWarnings("unchecked")
1715
public class QueryBuilder<T, ID> implements DistinctWhereOrderByPage<T, ID>, WhereOrderByPage<T, ID>, OrderByPage<T, ID>, PageableResult<T, ID>, Result<T, ID> {
18-
protected final GenericSpecificationRepository<T, ID> genericSpecificationRepository;
16+
protected final DynamicSpecificationRepository<T, ID> dynamicSpecificationRepository;
1917
protected final DynamicQuery dynamicQuery;
2018

21-
public QueryBuilder(GenericSpecificationRepository<T, ID> genericSpecificationRepository) {
22-
this.genericSpecificationRepository = genericSpecificationRepository;
19+
public QueryBuilder(DynamicSpecificationRepository<T, ID> dynamicSpecificationRepository) {
20+
this.dynamicSpecificationRepository = dynamicSpecificationRepository;
2321
dynamicQuery = new DynamicQuery();
2422
}
2523

@@ -52,18 +50,18 @@ public Result<T, ID> page(int pageNumber, int pageSize) {
5250
}
5351

5452
public List<T> getResult() {
55-
return DatabaseFilterManager.getEntityListBySelectableFilterAsList(genericSpecificationRepository, dynamicQuery);
53+
return DynamicQueryManager.getEntityListBySelectableFilterAsList(dynamicSpecificationRepository, dynamicQuery);
5654
}
5755

5856
public <ResultValue> List<ResultValue> getResult(Class<ResultValue> resultValueClass) {
59-
return DatabaseFilterManager.getEntityListBySelectableFilterWithReturnTypeAsList(genericSpecificationRepository, dynamicQuery, resultValueClass);
57+
return DynamicQueryManager.getEntityListBySelectableFilterWithReturnTypeAsList(dynamicSpecificationRepository, dynamicQuery, resultValueClass);
6058
}
6159

6260
public Page<T> getResultAsPage() {
63-
return DatabaseFilterManager.getEntityListBySelectableFilterAsPage(genericSpecificationRepository, dynamicQuery);
61+
return DynamicQueryManager.getEntityListBySelectableFilterAsPage(dynamicSpecificationRepository, dynamicQuery);
6462
}
6563

6664
public <ResultValue> Page<ResultValue> getResultAsPage(Class<ResultValue> resultValueClass) {
67-
return DatabaseFilterManager.getEntityListBySelectableFilterWithReturnTypeAsPage(genericSpecificationRepository, dynamicQuery, resultValueClass);
65+
return DynamicQueryManager.getEntityListBySelectableFilterWithReturnTypeAsPage(dynamicSpecificationRepository, dynamicQuery, resultValueClass);
6866
}
6967
}

src/main/java/com/beyt/filter/query/simplifier/QuerySimplifier.java renamed to src/main/java/com/beyt/query/builder/QuerySimplifier.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
package com.beyt.filter.query.simplifier;
1+
package com.beyt.query.builder;
22

33
import com.beyt.dto.Criteria;
44
import com.beyt.dto.enums.CriteriaType;
55
import com.beyt.dto.enums.Order;
6-
import com.beyt.filter.GenericSpecification;
6+
import com.beyt.query.DynamicSpecification;
77
import lombok.AllArgsConstructor;
88
import lombok.Data;
99
import lombok.NoArgsConstructor;
@@ -30,7 +30,7 @@ public static SelectRule Select(String fieldName, String alias) {
3030
}
3131

3232
public static SelectRule Select(String fieldName) {
33-
return new SelectRule(fieldName, GenericSpecification.getFieldName(fieldName));
33+
return new SelectRule(fieldName, DynamicSpecification.getFieldName(fieldName));
3434
}
3535

3636
@Data

src/main/java/com/beyt/filter/query/builder/interfaces/DistinctWhereOrderByPage.java renamed to src/main/java/com/beyt/query/builder/interfaces/DistinctWhereOrderByPage.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
package com.beyt.filter.query.builder.interfaces;
1+
package com.beyt.query.builder.interfaces;
22

33
import com.beyt.dto.Criteria;
4-
import com.beyt.filter.query.simplifier.QuerySimplifier;
4+
import com.beyt.query.builder.QuerySimplifier;
55
import org.springframework.data.domain.Page;
66

77
import java.util.List;

src/main/java/com/beyt/filter/query/builder/interfaces/OrderByPage.java renamed to src/main/java/com/beyt/query/builder/interfaces/OrderByPage.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
package com.beyt.filter.query.builder.interfaces;
1+
package com.beyt.query.builder.interfaces;
22

3-
import com.beyt.filter.query.simplifier.QuerySimplifier;
3+
import com.beyt.query.builder.QuerySimplifier;
44
import org.springframework.data.domain.Page;
55

66
import java.util.List;

src/main/java/com/beyt/filter/query/builder/interfaces/PageableResult.java renamed to src/main/java/com/beyt/query/builder/interfaces/PageableResult.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.beyt.filter.query.builder.interfaces;
1+
package com.beyt.query.builder.interfaces;
22

33
import org.springframework.data.domain.Page;
44

src/main/java/com/beyt/filter/query/builder/interfaces/Result.java renamed to src/main/java/com/beyt/query/builder/interfaces/Result.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.beyt.filter.query.builder.interfaces;
1+
package com.beyt.query.builder.interfaces;
22

33
import org.springframework.data.domain.Page;
44

0 commit comments

Comments
 (0)