dnet-applications/apps/dnet-exporter-api/src/main/java/eu/dnetlib/openaire/dsm/dao/DatasourceSpecs.java

142 lines
4.2 KiB
Java

package eu.dnetlib.openaire.dsm.dao;
import eu.dnetlib.enabling.datasources.common.DsmRuntimeException;
import eu.dnetlib.openaire.dsm.domain.FilterName;
import eu.dnetlib.openaire.dsm.domain.RequestFilter;
import eu.dnetlib.openaire.dsm.domain.RequestSort;
import eu.dnetlib.openaire.dsm.domain.RequestSortOrder;
import eu.dnetlib.openaire.dsm.domain.db.DatasourceApiDbEntry;
import eu.dnetlib.openaire.dsm.domain.db.DatasourceDbEntry;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.data.jpa.domain.Specification;
import javax.persistence.criteria.*;
import java.util.List;
import java.util.Map.Entry;
public class DatasourceSpecs {
private static final Log log = LogFactory.getLog(DatasourceSpecs.class);
public static final String WILDCARD = "%";
public static Specification<DatasourceDbEntry> dsRegisteredbyNotNullSpec() {
return (ds, query, cb) -> cb.and(
cb.isNull(ds.get(FilterName.registeredby.name())).not(),
cb.isNull(ds.get("registrationdate")).not());
}
public static Specification<DatasourceDbEntry> dsSpec(final RequestSort requestSortBy, final RequestSortOrder order, final RequestFilter requestFilter) {
log.debug(String.format("RequestFilter:'%s', RequestSort:'%s', RequestSortOrder:'%s'", requestFilter, requestSortBy, order));
return (ds, query, cb) -> {
final Predicate p = cb.conjunction();
if (requestFilter != null) {
final List<Expression<Boolean>> expressions = p.getExpressions();
requestFilter.entrySet().stream()
.forEach(e -> {
switch (FilterName.type(e.getKey())) {
case exact:
expressions.add(exactSearch(ds, cb, e));
break;
case search:
expressions.add(likeSearch(ds, cb, e));
break;
case searchOrgs:
// search by case insensitive organization's country
expressions.add(
cb.equal(
cb.lower(
ds.join("organizations").get(FilterName.country.name())),
getValue(e)));
break;
}
});
}
if (requestSortBy != null) {
if (order != null) {
final Path<Object> orderField = ds.get(requestSortBy.name());
switch (order) {
case ASCENDING:
query.orderBy(cb.asc(orderField));
break;
case DESCENDING:
query.orderBy(cb.desc(orderField));
break;
}
}
}
query.distinct(true);
return p;
};
}
public static Specification<DatasourceApiDbEntry> apiSpec(final RequestFilter requestFilter) {
log.debug(String.format("RequestFilter:'%s'", requestFilter));
return (api, query, cb) -> {
final Predicate p = cb.conjunction();
if (requestFilter != null) {
final List<Expression<Boolean>> expressions = p.getExpressions();
requestFilter.entrySet().stream()
.forEach(e -> {
switch (FilterName.type(e.getKey())) {
case exact:
expressions.add(exactSearch(api, cb, e));
break;
case search:
expressions.add(likeSearch(api, cb, e));
break;
case searchOrgs:
throw new DsmRuntimeException("not implemented");
}
});
}
query.distinct(true);
return p;
};
}
// HELPERS
// substring, case insensitive, like based search
private static Predicate likeSearch(final Root<?> r, final CriteriaBuilder cb, final Entry<FilterName, Object> e) {
return cb.like(
cb.lower(
r.get(e.getKey().name())),
WILDCARD + getValue(e) + WILDCARD);
}
// search by ID, managed. exact match
private static Predicate exactSearch(final Root<?> r, final CriteriaBuilder cb, final Entry<FilterName, Object> e) {
return cb.equal(r.get(e.getKey().name()), getValue(e));
}
private static Object getValue(final Entry<FilterName, Object> e) {
if (e.getValue() instanceof String) {
final String s = ((String) e.getValue());
if (!e.getKey().equals(FilterName.country)) {
Boolean b = BooleanUtils.toBooleanObject(s);
if (b != null) {
return b;
}
}
return e.getKey().equals(FilterName.id) ? s : StringUtils.lowerCase(s);
}
if (e.getValue() instanceof Boolean) {
return e.getValue();
}
return e.getValue();
}
}