View difference between Paste ID: QJnkYRRh and cAt1zCrc
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
}