Project

General

Profile

1
package eu.dnetlib.openaire.dsm.dao;
2

    
3
import java.util.List;
4
import java.util.Map.Entry;
5
import javax.persistence.criteria.*;
6

    
7
import eu.dnetlib.enabling.datasources.common.DsmRuntimeException;
8
import eu.dnetlib.openaire.dsm.domain.FilterName;
9
import eu.dnetlib.openaire.dsm.domain.RequestFilter;
10
import eu.dnetlib.openaire.dsm.domain.RequestSort;
11
import eu.dnetlib.openaire.dsm.domain.RequestSortOrder;
12
import eu.dnetlib.openaire.dsm.domain.db.DatasourceApiDbEntry;
13
import eu.dnetlib.openaire.dsm.domain.db.DatasourceDbEntry;
14
import org.apache.commons.lang3.BooleanUtils;
15
import org.apache.commons.lang3.StringUtils;
16
import org.apache.commons.logging.Log;
17
import org.apache.commons.logging.LogFactory;
18
import org.springframework.data.jpa.domain.Specification;
19

    
20
public class DatasourceSpecs {
21

    
22
	private static final Log log = LogFactory.getLog(DatasourceSpecs.class);
23

    
24
	public static final String WILDCARD = "%";
25

    
26
	public static Specification<DatasourceDbEntry> dsSpec(final RequestSort requestSortBy, final RequestSortOrder order, final RequestFilter requestFilter) {
27
		return (ds, query, cb) -> {
28
			final Predicate p = cb.conjunction();
29
			if (requestFilter != null) {
30
				final List<Expression<Boolean>> expressions = p.getExpressions();
31
				requestFilter.entrySet().stream()
32
						.forEach(e -> {
33
							switch (FilterName.type(e.getKey())) {
34

    
35
							case exact:
36
								expressions.add(exactSearch(ds, cb, e));
37

    
38
								break;
39
							case search:
40
								expressions.add(likeSearch(ds, cb, e));
41

    
42
								break;
43
							case searchOrgs:
44
								// search by case insensitive organization's country
45
								expressions.add(
46
										cb.equal(
47
												cb.lower(
48
														ds.join("organizations").get(FilterName.country.name())),
49
												getValue(e)));
50
								break;
51
							}
52
						});
53
			}
54
			if (requestSortBy != null) {
55
				if (order != null) {
56
					final Path<Object> orderField = ds.get(requestSortBy.name());
57
					switch (order) {
58
					case ASCENDING:
59
						query.orderBy(cb.asc(orderField));
60
						break;
61
					case DESCENDING:
62
						query.orderBy(cb.desc(orderField));
63
						break;
64
					}
65
				}
66
			}
67
			query.distinct(true);
68

    
69
			return p;
70
		};
71
	}
72

    
73
	public static Specification<DatasourceApiDbEntry> apiSpec(final RequestFilter requestFilter) {
74
		return (api, query, cb) -> {
75
			final Predicate p = cb.conjunction();
76
			if (requestFilter != null) {
77
				final List<Expression<Boolean>> expressions = p.getExpressions();
78
				requestFilter.entrySet().stream()
79
						.forEach(e -> {
80
							switch (FilterName.type(e.getKey())) {
81

    
82
							case exact:
83
								expressions.add(exactSearch(api, cb, e));
84
								break;
85
							case search:
86

    
87
								expressions.add(likeSearch(api, cb, e));
88
								break;
89
							case searchOrgs:
90
								throw new DsmRuntimeException("not implemented");
91
							}
92
						});
93
			}
94
			query.distinct(true);
95
			return p;
96
		};
97
	}
98

    
99
	// HELPERS
100

    
101
	// substring, case insensitive, like based search
102
	private static Predicate likeSearch(final Root<?> r, final CriteriaBuilder cb, final Entry<FilterName, Object> e) {
103
		return cb.like(
104
				cb.lower(
105
						r.get(e.getKey().name())),
106
				WILDCARD + getValue(e) + WILDCARD);
107
	}
108

    
109
	 // search by ID, managed. exact match
110
	private static Predicate exactSearch(final Root<?> r, final CriteriaBuilder cb, final Entry<FilterName, Object> e) {
111
		return cb.equal(r.get(e.getKey().name()), getValue(e));
112
	}
113

    
114
	private static Object getValue(final Entry<FilterName, Object> e) {
115
		if (e.getValue() instanceof String) {
116
			final String s = ((String) e.getValue());
117
			Boolean b = BooleanUtils.toBooleanObject(s);
118
			if (b != null) {
119
				return b;
120
			}
121
			return e.getKey().equals(FilterName.id) ? s : StringUtils.lowerCase(s);
122
		}
123
		if (e.getValue() instanceof Boolean) {
124
			return e.getValue();
125
		}
126

    
127
		return e.getValue();
128
	}
129

    
130
}
(9-9/16)