SHOW:
|
|
- or go back to the newest paste.
1 | - | package com.blog.repo; |
1 | + | package com.project.repo; |
2 | ||
3 | import java.util.Collection; | |
4 | import java.util.HashMap; | |
5 | import java.util.Map; | |
6 | ||
7 | import javax.persistence.criteria.CriteriaBuilder; | |
8 | import javax.persistence.criteria.CriteriaQuery; | |
9 | import javax.persistence.criteria.Expression; | |
10 | import javax.persistence.criteria.Path; | |
11 | import javax.persistence.criteria.Predicate; | |
12 | import javax.persistence.criteria.Root; | |
13 | ||
14 | public abstract class RefineableDao { | |
15 | private final Map<String,Refinement> allowedRefinements = new HashMap<String,Refinement>(); | |
16 | ||
17 | protected enum RefineType{ | |
18 | STRING, | |
19 | LIST, | |
20 | GREATER, | |
21 | LESSER, | |
22 | } | |
23 | ||
24 | public class Refinement{ | |
25 | protected final String field; | |
26 | protected final RefineType enumType; | |
27 | ||
28 | public Refinement(final String field, final RefineType enumType){ | |
29 | this.field = field; | |
30 | this.enumType = enumType; | |
31 | } | |
32 | ||
33 | public RefineType getEnum(){ | |
34 | return enumType; | |
35 | } | |
36 | ||
37 | public String getField(){ | |
38 | return field; | |
39 | } | |
40 | } | |
41 | ||
42 | /** | |
43 | * Create refined query with unspecified root. | |
44 | * @param refine | |
45 | * @param cb | |
46 | * @param query | |
47 | * @param cls | |
48 | * @return | |
49 | */ | |
50 | @SuppressWarnings("unchecked") | |
51 | protected <T> Predicate refineQuery(final Map<String,Object> refine, final CriteriaBuilder cb, final CriteriaQuery<T> query, final Class<T> cls){ | |
52 | Root<T> root = null; | |
53 | for(Root<?> tempRoot : query.getRoots()){ | |
54 | //Check if a root already exists for incoming class. Assume we're intending to refine that one. | |
55 | if(tempRoot.getJavaType().equals(cls)){ | |
56 | root = (Root<T>)tempRoot; | |
57 | break; | |
58 | } | |
59 | } | |
60 | if(root == null){ | |
61 | //Create new root. | |
62 | root = query.from(cls); | |
63 | } | |
64 | return this.refineQuery(refine, cb, query, root); | |
65 | } | |
66 | ||
67 | /** | |
68 | * Create refined query with specified root. | |
69 | * @param refine | |
70 | * @param cb | |
71 | * @param query | |
72 | * @param root | |
73 | * @return | |
74 | */ | |
75 | @SuppressWarnings("unchecked") | |
76 | protected <T> Predicate refineQuery(final Map<String,Object> refine, final CriteriaBuilder cb, final CriteriaQuery<T> query, final Root<?> root){ | |
77 | Predicate predicate = cb.conjunction(); | |
78 | for(String key : refine.keySet()){ | |
79 | Object refineObj = refine.get(key); | |
80 | Object[] iterable; | |
81 | //Convert to an array of objects. Make sure it's iterable. | |
82 | if(allowedRefinements.get(key).getEnum() != RefineType.LIST && refineObj instanceof Collection){ | |
83 | iterable = ((Collection<Object>)refineObj).toArray(); | |
84 | }else if(refineObj instanceof Object[]){ | |
85 | iterable = (Object[])refineObj; | |
86 | }else{ | |
87 | iterable = new Object[]{refineObj}; | |
88 | } | |
89 | for(Object obj : iterable){ | |
90 | Refinement refinement = allowedRefinements.get(key); | |
91 | ||
92 | switch(allowedRefinements.get(key).getEnum()){ | |
93 | case STRING: | |
94 | Expression<String> path = root.get(refinement.getField()); | |
95 | //Lower case to make searching case insensitive. | |
96 | path = cb.lower(path); | |
97 | predicate = cb.and(predicate,cb.like(path, "%".concat(((String)obj).toLowerCase()).concat("%"))); | |
98 | break; | |
99 | case LIST: | |
100 | String[] fields = refinement.getField().split("\\."); | |
101 | if(fields.length == 0){ | |
102 | fields = new String[]{refinement.getField()}; | |
103 | } | |
104 | Path<?> pathList = null; | |
105 | for(String field : fields){ | |
106 | pathList = pathList == null ? root.get(field) : pathList.get(field); | |
107 | } | |
108 | predicate = cb.and(predicate,pathList.in(obj)); | |
109 | break; | |
110 | case GREATER: | |
111 | Expression<Double> pathNum = root.get(refinement.getField()); | |
112 | predicate = cb.and(predicate,cb.greaterThanOrEqualTo(pathNum, Double.parseDouble(obj.toString()))); | |
113 | break; | |
114 | case LESSER: | |
115 | pathNum = root.get(refinement.getField()); | |
116 | predicate = cb.and(predicate,cb.lessThanOrEqualTo(pathNum, Double.parseDouble(obj.toString()))); | |
117 | break; | |
118 | } | |
119 | } | |
120 | } | |
121 | return predicate; | |
122 | } | |
123 | ||
124 | public Map<String, Refinement> getAllowedRefinements() { | |
125 | return allowedRefinements; | |
126 | } | |
127 | } |