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
		log.debug(String.format("RequestFilter:'%s', RequestSort:'%s', RequestSortOrder:'%s'", requestFilter, requestSortBy, order));
28
		return (ds, query, cb) -> {
29
			final Predicate p = cb.conjunction();
30
			if (requestFilter != null) {
31
				final List<Expression<Boolean>> expressions = p.getExpressions();
32
				requestFilter.entrySet().stream()
33
						.forEach(e -> {
34
							switch (FilterName.type(e.getKey())) {
35

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

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

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

    
70
			return p;
71
		};
72
	}
73

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

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

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

    
101
	// HELPERS
102

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

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

    
116
	private static Object getValue(final Entry<FilterName, Object> e) {
117
		if (e.getValue() instanceof String) {
118
			final String s = ((String) e.getValue());
119

    
120
			if (!e.getKey().equals(FilterName.country)) {
121
				Boolean b = BooleanUtils.toBooleanObject(s);
122
				if (b != null) {
123
					return b;
124
				}
125
			}
126
			return e.getKey().equals(FilterName.id) ? s : StringUtils.lowerCase(s);
127
		}
128
		if (e.getValue() instanceof Boolean) {
129
			return e.getValue();
130
		}
131

    
132
		return e.getValue();
133
	}
134

    
135
}
(9-9/16)