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 dsRegisteredbyNotNullSpec() { return (ds, query, cb) -> cb.and( cb.isNull(ds.get(FilterName.registeredby.name())).not(), cb.isNull(ds.get("registrationdate")).not()); } public static Specification 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> 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 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 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> 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 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 e) { return cb.equal(r.get(e.getKey().name()), getValue(e)); } private static Object getValue(final Entry 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(); } }