Commit 9d15f47f authored by Matija Obreza's avatar Matija Obreza

Updated CountryFilter with region codes

- Accepts region codes and loads country iso3 codes from GeoRegionService
- ES: Fixed nesting of Region in Country
- Updated GeoRegion#isoCode and #name column definitions
- QDSL was null because of http://www.querydsl.com/static/querydsl/3.5.0/reference/html/ch03s03.html#d0e2181
parent 75cbac61
......@@ -81,6 +81,7 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU
@JsonView({ JsonViews.Minimal.class })
@Field(type = FieldType.Object)
@JsonIgnoreProperties({"settings"})
// @QueryInit({ "country.region.*" })
private FaoInstitute institute;
@Column(name = "acceNumb", nullable = false, length = 128)
......@@ -117,6 +118,7 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU
@JoinColumn(name = "orgCtyId", nullable = true)
@JsonView({ JsonViews.Public.class })
@Field(type = FieldType.Object)
// @QueryInit({ "region.*" })
private Country countryOfOrigin;
@Column(name = "sampStat", length = 3)
......
......@@ -74,7 +74,7 @@ public class Country extends BasicModel {
@JoinColumn(name = "regionId")
@JsonView({ JsonViews.Public.class })
@JsonIgnoreProperties({ "countries", "parentRegion" })
@Field(type = FieldType.Nested)
@Field(type = FieldType.Object)
private GeoRegion region;
@Column(name = "minLongitude")
......
......@@ -21,6 +21,8 @@ import org.genesys.blocks.model.JsonViews;
import org.genesys.blocks.model.VersionedModel;
import org.genesys.custom.elasticsearch.IgnoreField;
import org.hibernate.annotations.Type;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldIndex;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
......@@ -35,10 +37,11 @@ public class GeoRegion extends VersionedModel {
private static final long serialVersionUID = -1L;
@Column
@Column(length = 3, nullable = false, unique = true)
@Field(index = FieldIndex.not_analyzed)
private String isoCode;
@Column
@Column(nullable = false, length = 250)
private String name;
@ManyToOne()
......
......@@ -4,8 +4,9 @@ import org.genesys2.server.model.impl.Country;
import org.genesys2.server.model.impl.GeoRegion;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
public interface GeoRegionRepository extends JpaRepository<GeoRegion, Long>{
public interface GeoRegionRepository extends JpaRepository<GeoRegion, Long>, QueryDslPredicateExecutor<GeoRegion> {
@Query("select distinct gr from GeoRegion gr where gr.isoCode = ?1")
GeoRegion findByIsoCode(String isoCode);
......
......@@ -6,29 +6,39 @@ import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Set;
public interface GeoRegionService {
GeoRegion find(String regionIsoCode);
GeoRegion find(String regionIsoCode);
void save(GeoRegion geoRegion);
void save(GeoRegion geoRegion);
void delete(GeoRegion geoRegion);
void delete(GeoRegion geoRegion);
List<GeoRegion> findAll();
List<GeoRegion> findAll();
List<GeoRegion> findAll(Locale locale);
List<GeoRegion> findAll(Locale locale);
void updateGeoRegionData() throws IOException, ParserConfigurationException, SAXException;
void updateGeoRegionData() throws IOException, ParserConfigurationException, SAXException;
GeoRegion getRegion(Country country);
List<GeoRegion> getGeoRegionsForFilter();
List<GeoRegion> getGeoRegionsForFilter();
List<GeoRegion> conversionToSubRegionsList(GeoRegion parentGeo);
List<GeoRegion> conversionToSubRegionsList(GeoRegion parentGeo);
List<GeoRegion> getChildren(String regionIsoCode);
List<GeoRegion> getChildren(String regionIsoCode);
/**
* Get all ISO3 country codes for specified region codes
*
* @param regionCodes set of region codes
* @return a set of ISO3 country codes of countries in all specified regions
*/
Collection<String> countryCodesFor(Set<String> regionCodes);
}
......@@ -15,8 +15,6 @@
*/
package org.genesys2.server.service.filter;
import static org.genesys2.server.model.genesys.QAccession.accession;
import java.util.Set;
import java.util.UUID;
......@@ -24,6 +22,7 @@ import org.genesys.blocks.model.filters.NumberFilter;
import org.genesys.blocks.model.filters.StringFilter;
import org.genesys.blocks.model.filters.UuidModelFilter;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.QAccession;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
import com.hazelcast.util.CollectionUtil;
......@@ -87,12 +86,16 @@ public class AccessionFilter extends UuidModelFilter<AccessionFilter, Accession>
/** acce.lists uuid */
public Set<UUID> list;
public Predicate buildQuery() {
return buildQuery(QAccession.accession);
}
/**
* Builds the query.
*
* @return the predicate
*/
public Predicate buildQuery() {
public Predicate buildQuery(QAccession accession) {
final BooleanBuilder and = new BooleanBuilder();
super.buildQuery(accession, accession._super._super, and);
......@@ -174,4 +177,40 @@ public class AccessionFilter extends UuidModelFilter<AccessionFilter, Accession>
return this;
}
public InstituteFilter holder() {
if (this.holder==null) {
return this.holder = new InstituteFilter();
} else {
return this.holder;
}
}
public CountryFilter origin() {
if (this.origin == null) {
return this.origin = new CountryFilter();
}
return this.origin;
}
public AccessionGeoFilter geo() {
if (this.geo == null) {
return this.geo = new AccessionGeoFilter();
}
return this.geo;
}
public AccessionCollectFilter coll() {
if (this.coll == null) {
return this.coll = new AccessionCollectFilter();
}
return this.coll;
}
public TaxonomyFilter taxa() {
if (this.taxa == null) {
return this.taxa = new TaxonomyFilter();
}
return this.taxa;
}
}
......@@ -118,49 +118,46 @@ public class AppliedFiltersConverter {
}
LOG.trace("Converting {}", pretty.writeValueAsString(af));
switch (filterName) {
case "regionHoldInst": {
filterName = "institute.country.region";
break;
}
case "regionOrigin": {
filterName = "orgCty.region";
break;
}
default:
}
if (filterName.contains(".")) {
int lastDot = filterName.lastIndexOf('.');
String base = filterName.substring(0, lastDot);
String newFilterName = filterName.substring(lastDot + 1);
int firstDot = filterName.indexOf('.');
String base = filterName.substring(0, firstDot);
String newFilterName = filterName.substring(firstDot + 1);
LOG.debug("Doing accession.{} for {}", base, af.getFilterName());
switch (base) {
case "institute": {
InstituteFilter ff = f.holder;
if (ff == null) {
ff = f.holder = new InstituteFilter();
}
InstituteFilter ff = f.holder();
apply(ff, newFilterName, af);
break;
}
case "taxonomy": {
TaxonomyFilter ff = f.taxa;
if (ff == null) {
ff = f.taxa = new TaxonomyFilter();
}
TaxonomyFilter ff = f.taxa();
apply(ff, newFilterName, af);
break;
}
case "coll": {
AccessionCollectFilter ff = f.coll;
if (ff == null) {
ff = f.coll = new AccessionCollectFilter();
}
AccessionCollectFilter ff = f.coll();
apply(ff, newFilterName, af);
break;
}
case "geo": {
AccessionGeoFilter ff = f.geo;
if (ff == null) {
ff = f.geo = new AccessionGeoFilter();
}
AccessionGeoFilter ff = f.geo();
apply(ff, newFilterName, af);
break;
}
case "orgCty": {
CountryFilter ff = f.origin;
if (ff == null) {
ff = f.origin = new CountryFilter();
}
CountryFilter ff = f.origin();
apply(ff, newFilterName, af);
break;
}
......@@ -427,16 +424,22 @@ public class AppliedFiltersConverter {
return nf;
}
private static void apply(CountryFilter ff, String filterName, AppliedFilter af) {
private static void apply(CountryFilter countryFilter, String filterName, AppliedFilter af) {
switch (filterName) {
case "iso3": {
Set<String> iso3 = ff.iso3;
Set<String> iso3 = countryFilter.iso3;
if (iso3 == null) {
iso3 = ff.iso3 = new HashSet<>();
iso3 = countryFilter.iso3 = new HashSet<>();
}
iso3.addAll(toStringSet(af));
break;
}
case "region": {
Set<String> codes = toStringSet(af);
LOG.debug("Got country region codes {}", codes);
countryFilter.region = codes;
break;
}
default:
throw new RuntimeException("Unhandled Institute filter property=" + filterName);
}
......@@ -450,22 +453,37 @@ public class AppliedFiltersConverter {
return af.getValues().stream().map(fv -> (UUID) ((LiteralValueFilter) fv).getValue()).collect(Collectors.toSet());
}
private static void apply(InstituteFilter ff, String filterName, AppliedFilter af) {
private static void apply(InstituteFilter instituteFilter, String filterName, AppliedFilter af) {
switch (filterName) {
case "code": {
Set<String> code = ff.code;
Set<String> code = instituteFilter.code;
if (code == null) {
code = ff.code = new HashSet<>();
code = instituteFilter.code = new HashSet<>();
}
Set<String> codes = toStringSet(af);
LOG.debug("Got Institute codes {}", codes);
code.addAll(codes);
break;
}
case "country.iso3": {
CountryFilter countryFilter = instituteFilter.country();
Set<String> codes = toStringSet(af);
LOG.debug("Got countries codes {}", codes);
countryFilter.iso3 = new HashSet<>();
countryFilter.iso3.addAll(codes);
break;
}
case "country.region": {
Set<String> codes = toStringSet(af);
LOG.debug("Got country region codes {}", codes);
CountryFilter countryFilter = instituteFilter.country();
countryFilter.region = codes;
break;
}
case "networks": {
Set<String> networks = ff.networks;
Set<String> networks = instituteFilter.networks;
if (networks == null) {
networks = ff.networks = new HashSet<>();
networks = instituteFilter.networks = new HashSet<>();
}
Set<String> codes = toStringSet(af);
LOG.debug("Got Institute networks {}", codes);
......@@ -477,24 +495,4 @@ public class AppliedFiltersConverter {
}
}
// private static void apply(CountryFilter country, AppliedFilter af) {
// String filterName = af.getFilterName();
// switch (filterName) {
// case "code": {
// Set<String> code = country.iso3;
// if (code == null) {
// code = country.iso3 = new HashSet<>();
// }
// Set<String> codes = af.getValues().stream().map(fv -> (String)
// ((LiteralValueFilter) fv).getValue()).collect(Collectors.toSet());
// LOG.debug("Got origin iso3 codes {}", codes);
// code.addAll(codes);
// break;
// }
// default:
// throw new RuntimeException("Unhandled country filter property=" +
// filterName);
// }
// }
}
......@@ -17,24 +17,29 @@ package org.genesys2.server.service.filter;
import static org.genesys2.server.model.impl.QCountry.country;
import java.util.Collection;
import java.util.Set;
import org.genesys.blocks.model.filters.BasicModelFilter;
import org.genesys.blocks.util.CurrentApplicationContext;
import org.genesys2.server.model.impl.Country;
import org.genesys2.server.model.impl.QCountry;
import org.genesys2.server.service.GeoRegionService;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate;
// TODO: Auto-generated Javadoc
/**
* The Class CountryFilter.
* The filter for {@link Country}
*/
public class CountryFilter extends BasicModelFilter<CountryFilter, Country> {
/** The iso 3. */
public Set<String> iso3;
/** The region codes. */
public Set<String> region;
/**
* Builds the query.
*
......@@ -57,8 +62,16 @@ public class CountryFilter extends BasicModelFilter<CountryFilter, Country> {
if (iso3 != null && !iso3.isEmpty()) {
and.and(country.code3.in(iso3));
}
if (region != null && ! region.isEmpty()) {
and.and(country.code3.in(getCountriesInRegions(region)));
}
return and;
}
private Collection<String> getCountriesInRegions(Set<String> regionCodes) {
GeoRegionService geoRegionService = CurrentApplicationContext.getContext().getBean(GeoRegionService.class);
return geoRegionService.countryCodesFor(regionCodes);
}
}
/*
* Copyright 2018 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys2.server.service.filter;
import java.util.Set;
import org.genesys.blocks.model.filters.BasicModelFilter;
import org.genesys2.server.model.impl.GeoRegion;
import org.genesys2.server.model.impl.QGeoRegion;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate;
/**
* The filter for {@link GeoRegion}
*/
public class GeoRegionFilter extends BasicModelFilter<GeoRegionFilter, GeoRegion> {
/** The region code. */
public Set<String> code;
/**
* Builds the query.
*
* @return the predicate
*/
public Predicate buildQuery() {
return buildQuery(QGeoRegion.geoRegion);
}
/**
* Builds the query.
*
* @param georegion the georegion
* @return the predicate
*/
public Predicate buildQuery(QGeoRegion georegion) {
final BooleanBuilder and = new BooleanBuilder();
super.buildQuery(georegion, georegion._super._super, and);
if (code != null && !code.isEmpty()) {
and.and(georegion.isoCode.in(code));
}
return and;
}
}
......@@ -91,5 +91,12 @@ public class InstituteFilter extends BasicModelFilter<InstituteFilter, FaoInstit
return and;
}
public CountryFilter country() {
if (this.country == null) {
return this.country = new CountryFilter();
} else {
return this.country;
}
}
}
......@@ -395,8 +395,10 @@ public class ElasticsearchServiceImpl implements ElasticsearchService, Initializ
} catch (org.springframework.data.elasticsearch.ElasticsearchException e) {
LOG.error(e.getMessage());
Map<String, String> failedDocs = e.getFailedDocuments();
for (String key : failedDocs.keySet()) {
LOG.error("{} {}", key, failedDocs.get(key));
if (failedDocs != null) {
for (String key : failedDocs.keySet()) {
LOG.error("{} {}", key, failedDocs.get(key));
}
}
} catch (ElasticsearchException e) {
LOG.error("Could not index document", e);
......
/*
* Copyright 2018 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys2.server.service.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.xml.parsers.ParserConfigurationException;
import org.genesys2.server.model.impl.Country;
import org.genesys2.server.model.impl.GeoRegion;
import org.genesys2.server.model.impl.QGeoRegion;
import org.genesys2.server.persistence.CountryRepository;
import org.genesys2.server.persistence.GeoRegionRepository;
import org.genesys2.server.service.GeoRegionService;
......@@ -25,21 +43,38 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.xml.sax.SAXException;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
/**
* GeoRegion service.
*/
@Service
@Transactional(readOnly = true)
public class GeoRegionServiceImpl implements GeoRegionService {
/** The Constant LOG. */
private static final Logger LOG = LoggerFactory.getLogger(GeoRegionServiceImpl.class);
/** The country repository. */
@Autowired
CountryRepository countryRepository;
/** The geo region repository. */
@Autowired
GeoRegionRepository geoRegionRepository;
/** The geo region data CLDR. */
@Autowired
GeoRegionDataCLDR geoRegionDataCLDR;
/** The jpa query factory. */
@Autowired
private JPAQueryFactory jpaQueryFactory;
/* (non-Javadoc)
* @see org.genesys2.server.service.GeoRegionService#find(java.lang.String)
*/
@Override
public GeoRegion find(String regionIsoCode) {
GeoRegion geoRegion = geoRegionRepository.findByIsoCode(regionIsoCode);
......@@ -47,18 +82,27 @@ public class GeoRegionServiceImpl implements GeoRegionService {
return geoRegion;
}
/* (non-Javadoc)
* @see org.genesys2.server.service.GeoRegionService#save(org.genesys2.server.model.impl.GeoRegion)
*/
@Override
@Transactional(readOnly = false)
public void save(GeoRegion geoRegion) {
geoRegionRepository.save(geoRegion);
}
/* (non-Javadoc)
* @see org.genesys2.server.service.GeoRegionService#delete(org.genesys2.server.model.impl.GeoRegion)
*/
@Override
@Transactional(readOnly = false)
public void delete(GeoRegion geoRegion) {
geoRegionRepository.delete(geoRegion);
}
/* (non-Javadoc)
* @see org.genesys2.server.service.GeoRegionService#getRegion(org.genesys2.server.model.impl.Country)
*/
@Override
public GeoRegion getRegion(Country country) {
// NPE check
......@@ -71,6 +115,9 @@ public class GeoRegionServiceImpl implements GeoRegionService {
return geoRegion;
}
/* (non-Javadoc)
* @see org.genesys2.server.service.GeoRegionService#getChildren(java.lang.String)
*/
@Override
public List<GeoRegion> getChildren(String regionIsoCode) {
List<GeoRegion> all = findAll();
......@@ -82,11 +129,17 @@ public class GeoRegionServiceImpl implements GeoRegionService {
return geoRegions;
}
/* (non-Javadoc)
* @see org.genesys2.server.service.GeoRegionService#findAll()
*/
@Override
public List<GeoRegion> findAll() {
return geoRegionRepository.findAll();
}
/* (non-Javadoc)
* @see org.genesys2.server.service.GeoRegionService#findAll(java.util.Locale)