Commit 55857a54 authored by Matija Obreza's avatar Matija Obreza
Browse files

Filtering: Using new AND/OR filters

parent 86a87b27
......@@ -59,7 +59,7 @@
<snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory>
<junit.version>4.13.2</junit.version>
<application.blocks.version>3.2-SNAPSHOT</application.blocks.version>
<application.blocks.version>4.0-SNAPSHOT</application.blocks.version>
<commons.beanutils.version>1.9.4</commons.beanutils.version>
<commons.io.version>2.11.0</commons.io.version>
<commons.lang.version>3.12.0</commons.lang.version>
......
......@@ -15,17 +15,19 @@
*/
package org.genesys.catalog.model.filters;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.ListPath;
import java.io.Serializable;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.genesys.blocks.model.filters.StringFilter;
import org.genesys.catalog.model.dataset.DatasetAccessionRef;
import org.genesys.catalog.model.dataset.QDatasetAccessionRef;
import org.genesys2.server.service.filter.AccessionFilter;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.ListPath;
/**
* The Class AccessionRefFilter.
......@@ -33,7 +35,9 @@ import java.util.Set;
* @author Viacheslav Pavlov
* @author Matija Obreza
*/
public class AccessionRefFilter {
public class AccessionRefFilter implements Serializable {
private static final long serialVersionUID = 7898002699557658474L;
/** The doi. */
public Set<String> doi;
......
......@@ -24,9 +24,10 @@ import java.util.List;
import static org.genesys.catalog.model.vocab.QControlledVocabulary.controlledVocabulary;
public class ControlledVocabularyFilter extends UuidModelFilter<ControlledVocabularyFilter, ControlledVocabulary> {
private static final long serialVersionUID = 5953933222811688208L;
/** The owner. */
public PartnerFilter owner;
......
......@@ -38,6 +38,8 @@ import com.querydsl.core.types.Predicate;
*/
public class DatasetFilter extends UuidModelFilter<DatasetFilter, Dataset> implements IFullTextFilter {
private static final long serialVersionUID = -3014463705200950518L;
/** Any text. */
public String _text;
......
......@@ -14,6 +14,7 @@ import static org.genesys.catalog.model.dataset.QDatasetLocation.datasetLocation
public class DatasetLocationFilter extends UuidModelFilter<DatasetLocationFilter, DatasetLocation> {
private static final long serialVersionUID = -601069622681438809L;
/**
* The longitude.
......
......@@ -39,6 +39,8 @@ import static org.genesys.catalog.model.traits.QDescriptor.descriptor;
*/
public class DescriptorFilter extends UuidModelFilter<DescriptorFilter, Descriptor> implements IFullTextFilter {
private static final long serialVersionUID = -7996157718282752063L;
/** Any text. */
public String _text;
......
......@@ -38,6 +38,8 @@ import static org.genesys.catalog.model.traits.QDescriptorList.descriptorList;
*/
public class DescriptorListFilter extends UuidModelFilter<DescriptorListFilter, DescriptorList> implements IFullTextFilter {
private static final long serialVersionUID = -5524243000542552690L;
/** Any text. */
public String _text;
......
......@@ -39,6 +39,8 @@ import com.querydsl.core.types.Predicate;
*/
public class PartnerFilter extends UuidModelFilter<PartnerFilter, Partner> {
private static final long serialVersionUID = -6235354214065490627L;
/** The short name. */
public Set<String> shortName;
......
......@@ -34,7 +34,7 @@ public interface ShortFilterService {
* @return string with normalized filter
* @throws IOException Signals that an I/O exception has occurred.
*/
String normalizeFilter(SuperModelFilter<?,?> filter) throws IOException;
<T extends SuperModelFilter<T, ?>> String normalizeFilter(T filter) throws IOException;
/**
* Normalize the filter.
......@@ -43,7 +43,7 @@ public interface ShortFilterService {
* @param clazz the clazz
* @throws IOException Signals that an I/O exception has occurred.
*/
<T extends SuperModelFilter<?, ?>> T normalizeFilter(SuperModelFilter<?, ?> filter, Class<T> clazz) throws IOException;
<T extends SuperModelFilter<T, ?>> T normalizeFilter(T filter, Class<T> clazz) throws IOException;
/**
* Load short filter or create a new code.
......@@ -52,7 +52,7 @@ public interface ShortFilterService {
* @return found or created name of the shortened filter object
* @throws IOException
*/
String getCode(SuperModelFilter<?,?> filter) throws IOException;
<T extends SuperModelFilter<T, ?>> String getCode(T filter) throws IOException;
/**
* Load ShortFilter by short name.
......@@ -79,7 +79,7 @@ public interface ShortFilterService {
* @return the Instance of type T with data from JSON
* @throws IOException Signals that an I/O exception has occurred.
*/
<T extends SuperModelFilter<?,?>> T filterByCode(String code, Class<T> clazz) throws IOException;
<T extends SuperModelFilter<T,?>> T filterByCode(String code, Class<T> clazz) throws IOException;
public static class FilterInfo<T> {
public T filter;
......@@ -104,6 +104,6 @@ public interface ShortFilterService {
* @return
* @throws IOException
*/
<T extends SuperModelFilter<?,?>> T readFilter(String json, Class<T> clazz) throws IOException;
<T extends SuperModelFilter<T,?>> T readFilter(String json, Class<T> clazz) throws IOException;
}
......@@ -102,13 +102,13 @@ public class ShortFilterServiceImpl implements ShortFilterService, InitializingB
}
@Override
public <T extends SuperModelFilter<?, ?>> T readFilter(String json, Class<T> clazz) throws IOException {
public <T extends SuperModelFilter<T, ?>> T readFilter(String json, Class<T> clazz) throws IOException {
return BasicModelFilter.normalize(mapper.readValue(json, clazz));
}
@Override
@SuppressWarnings(value = "unchecked")
public String normalizeFilter(final SuperModelFilter<?, ?> filter) throws IOException {
public <T extends SuperModelFilter<T, ?>> String normalizeFilter(final T filter) throws IOException {
// Defaults
SuperModelFilter<?, ?> defaultFilter = null;
......@@ -146,7 +146,7 @@ public class ShortFilterServiceImpl implements ShortFilterService, InitializingB
}
@Override
public <T extends SuperModelFilter<?, ?>> T normalizeFilter(SuperModelFilter<?, ?> filter, Class<T> clazz) throws IOException {
public <T extends SuperModelFilter<T, ?>> T normalizeFilter(T filter, Class<T> clazz) throws IOException {
if (filter == null) {
try {
return clazz.getDeclaredConstructor().newInstance();
......@@ -176,7 +176,7 @@ public class ShortFilterServiceImpl implements ShortFilterService, InitializingB
@Override
@Transactional
public String getCode(final SuperModelFilter<?, ?> filter) throws IOException {
public <T extends SuperModelFilter<T, ?>> String getCode(final T filter) throws IOException {
final String normalizedFilter = normalizeFilter(filter);
ShortFilter shortFilter = loadByJSON(normalizedFilter);
......@@ -250,7 +250,7 @@ public class ShortFilterServiceImpl implements ShortFilterService, InitializingB
@Override
@Transactional(readOnly = true)
public <T extends SuperModelFilter<?, ?>> T filterByCode(String code, Class<T> clazz) throws IOException {
public <T extends SuperModelFilter<T, ?>> T filterByCode(String code, Class<T> clazz) throws IOException {
ShortFilter shortFilter = shortFilterRepository.findByCode(code == null ? "" : code);
if (shortFilter == null) {
......@@ -295,7 +295,7 @@ public class ShortFilterServiceImpl implements ShortFilterService, InitializingB
StringBuilder sb = new StringBuilder();
for (Object p : params) {
if (p instanceof BasicModelFilter) {
BasicModelFilter<?, ?> filter = (BasicModelFilter<?, ?>) p;
BasicModelFilter filter = (BasicModelFilter) p;
try {
sb.append(sfs.getCode(filter));
} catch (IOException e) {
......
......@@ -54,7 +54,6 @@ import org.springframework.data.jpa.repository.support.Querydsl;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.core.types.dsl.PathBuilderFactory;
import com.querydsl.jpa.JPAExpressions;
......
......@@ -47,6 +47,7 @@ import org.genesys2.server.service.PGRFANetworkService;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.std.UUIDDeserializer;
import com.hazelcast.internal.util.CollectionUtil;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.JPQLQuery;
......@@ -337,7 +338,23 @@ public class AccessionFilter extends UuidModelFilter<AccessionFilter, Accession>
}
}
query.where(ExpressionUtils.allOf(predicates));
var builder = new BooleanBuilder(ExpressionUtils.allOf(predicates));
if (NOT != null) {
// This is not a regular NOT operation where not(A & B) = not(A) or not(B)
// This is not(A, B) = not(A) and not(B)
builder.and(ExpressionUtils.anyOf(NOT.collectPredicates()).not());
}
if (AND != null) {
builder.and(AND.buildPredicate());
}
if (OR != null) {
builder.or(OR.buildPredicate());
}
query.where(builder);
return query;
}
......
......@@ -38,7 +38,7 @@ public class ShortFilterProcessor {
@Autowired
protected ShortFilterService shortFilterService;
public <T extends SuperModelFilter<?, ?>> FilterInfo<T> processFilter(final String filterCode, final T filter, Class<T> clazz) throws IOException {
public <T extends SuperModelFilter<T, ?>> FilterInfo<T> processFilter(final String filterCode, final T filter, Class<T> clazz) throws IOException {
Throwable lastException = null;
for (int i = 5; i >=0; i--) {
......@@ -55,7 +55,7 @@ public class ShortFilterProcessor {
throw new IOException("Failed to process filter: " + lastException.getMessage(), lastException);
}
private <T extends SuperModelFilter<?, ?>> FilterInfo<T> doProcessFilter(final String filterCode, final T filter, Class<T> clazz) throws IOException {
private <T extends SuperModelFilter<T, ?>> FilterInfo<T> doProcessFilter(final String filterCode, final T filter, Class<T> clazz) throws IOException {
FilterInfo<T> processedFilter = new FilterInfo<>();
if (filterCode != null) {
......@@ -82,11 +82,11 @@ public class ShortFilterProcessor {
return processedFilter;
}
public <T extends SuperModelFilter<?,?>> T filterByCode(String filterCode, Class<T> clazz) throws IOException {
public <T extends SuperModelFilter<T,?>> T filterByCode(String filterCode, Class<T> clazz) throws IOException {
return shortFilterService.filterByCode(filterCode, clazz);
}
public <T extends SuperModelFilter<?, ?>> T normalizeFilter(T filter, Class<T> filterType) throws IOException {
public <T extends SuperModelFilter<T, ?>> T normalizeFilter(T filter, Class<T> filterType) throws IOException {
return shortFilterService.normalizeFilter(filter, filterType);
}
}
......@@ -59,10 +59,15 @@ public abstract class AbstractServiceTest extends AbstractTest {
@Autowired
public TaxonomyService taxonomyService;
protected FaoInstitute setupInstitute(final String code){
final FaoInstitute inputI = new FaoInstitute();
inputI.setCode(code);
return instituteRepository.save(inputI);
protected FaoInstitute setupInstitute(final String instCode) {
var institute = instituteService.getInstitute(instCode);
if (institute == null) {
final FaoInstitute inputI = new FaoInstitute();
inputI.setCode(instCode);
return instituteRepository.save(inputI);
} else {
return institute;
}
}
protected Accession upsertAccession(final String instCode, final String acceNumb, final String genus) {
......
......@@ -23,6 +23,7 @@ import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.Set;
import org.genesys.blocks.model.filters.NumberFilter;
import org.genesys.filerepository.InvalidRepositoryFileDataException;
......@@ -180,4 +181,64 @@ public class AccessionServiceTest extends AbstractServicesTest {
assertThat(geoTile, hasSize(1));
}
@Test
public void testAndOrFilters() throws Exception {
var inst1= setupInstitute(INST_CODE);
var inst2= setupInstitute("ABC002");
Accession a1 = new Accession();
a1.setAccessionId(new AccessionId());
a1.setInstitute(inst1);
a1.setAccessionNumber("A 1");
a1.setSampStat(400);
a1.setDonorCode(inst2.getCode());
a1.setDonorNumb("ABC-7000");
a1.setTaxonomy(ensureTaxonomy("Zea", "mays"));
accessionRepository.save(a1);
Accession a2 = new Accession();
a2.setAccessionId(new AccessionId());
a2.setInstitute(inst2);
a2.setAccessionNumber("ABC 7000");
a2.setSampStat(300);
a2.setDonorCode("CCC333");
a2.setDonorNumb("XYZ");
a2.setTaxonomy(ensureTaxonomy("Zea", "mays"));
accessionRepository.save(a2);
var filter = new AccessionFilter();
filter.taxa().genus = Set.of("Zea");
var list = accessionService.list(filter, Pageable.ofSize(10));
assertThat(list.getContent(), hasSize(2));
filter.sampStat = Set.of(500);
assertThat(accessionService.list(filter, Pageable.ofSize(10)).getContent(), hasSize(0));
filter.sampStat = Set.of(400, 300);
assertThat(accessionService.list(filter, Pageable.ofSize(10)).getContent(), hasSize(2));
filter.institute().code = Set.of(inst1.getCode());
assertThat(accessionService.list(filter, Pageable.ofSize(10)).getContent(), hasSize(1));
var filter2 = new AccessionFilter();
filter2.institute().code = Set.of(inst2.getCode());
assertThat(accessionService.list(filter2, Pageable.ofSize(10)).getContent(), hasSize(1));
filter.OR = filter2;
filter.AND = null;
list = accessionService.list(filter, Pageable.ofSize(10));
assertThat(list.getContent(), hasSize(2));
filter.OR = null;
filter.AND = filter2;
list = accessionService.list(filter, Pageable.ofSize(10));
assertThat(list.getContent(), hasSize(0));
}
private Taxonomy2 ensureTaxonomy(String genus, String species) {
var taxon = new Taxonomy2();
taxon.setGenus(genus);
taxon.setSpecies(species);
return taxonomyService.ensureTaxonomy(taxon);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment