Commit c8a04238 authored by Maxym Borodenko's avatar Maxym Borodenko
Browse files

WIP: Filter accessions by GeoRegion

parent cf377060
......@@ -7,6 +7,7 @@ import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public interface GeoRegionService {
......@@ -18,6 +19,8 @@ public interface GeoRegionService {
List<GeoRegion> findAll();
List<GeoRegion> findAll(Locale locale);
void updateGeoRegionData() throws IOException, ParserConfigurationException, SAXException;
GeoRegion getRegion(Country country);
......
......@@ -2,7 +2,10 @@ package org.genesys2.server.service.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.stream.Collectors;
......@@ -83,6 +86,18 @@ public class GeoRegionServiceImpl implements GeoRegionService {
return geoRegionRepository.findAll();
}
@Override
public List<GeoRegion> findAll(final Locale locale) {
final List<GeoRegion> all = findAll();
Collections.sort(all, new Comparator<GeoRegion>() {
@Override
public int compare(GeoRegion o1, GeoRegion o2) {
return o1.getName(locale).compareTo(o2.getName(locale));
}
});
return all;
}
@Override
@Transactional(readOnly = false)
public void updateGeoRegionData() throws IOException, ParserConfigurationException, SAXException {
......
......@@ -28,10 +28,12 @@ import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TreeMap;
import javax.imageio.ImageIO;
......@@ -53,12 +55,14 @@ import org.genesys2.server.model.genesys.Parameter;
import org.genesys2.server.model.genesys.ParameterCategory;
import org.genesys2.server.model.impl.Country;
import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.GeoRegion;
import org.genesys2.server.service.CropService;
import org.genesys2.server.service.DownloadService;
import org.genesys2.server.service.ElasticService;
import org.genesys2.server.service.FilterConstants;
import org.genesys2.server.service.GenesysFilterService;
import org.genesys2.server.service.GenesysService;
import org.genesys2.server.service.GeoRegionService;
import org.genesys2.server.service.GeoService;
import org.genesys2.server.service.MappingService;
import org.genesys2.server.service.TraitService;
......@@ -124,6 +128,9 @@ public class ExplorerController extends BaseController implements InitializingBe
@Autowired
private GeoService geoService;
@Autowired
GeoRegionService geoRegionService;
private final ObjectMapper mapper = new ObjectMapper();
@Value("${base.url}")
......@@ -177,21 +184,19 @@ public class ExplorerController extends BaseController implements InitializingBe
* @throws IOException
*/
@RequestMapping("/explore")
public String viewFiltered(
HttpServletResponse response,
ModelMap model,
public String viewFiltered(HttpServletResponse response, ModelMap model,
@RequestParam(value = "page", required = false, defaultValue = "1") int page,
@RequestParam(value = "filter", required = true, defaultValue = "{}") String jsonFilter,
@RequestParam(value = "results", required = true, defaultValue = "50") int results,
@RequestParam(value = "columns", required = true, defaultValue = "") String[] columns,
@CookieValue(value = "columns", required = false) String[] cookieColumns
)
@CookieValue(value = "columns", required = false) String[] cookieColumns)
throws IOException, SearchException {
String[] selectedFilters = null;
_logger.debug("Filtering by: " + jsonFilter);
AppliedFilters appliedFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
conversionGeoRegionsFilterToOrgCountryFilter(appliedFilters);
Crop crop = null;
{
......@@ -209,6 +214,7 @@ public class ExplorerController extends BaseController implements InitializingBe
model.addAttribute("crop", crop);
// JSP works with JsonObject
appliedFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
final Map<?, ?> filters = mapper.readValue(appliedFilters.toString(), Map.class);
model.addAttribute("filters", filters);
......@@ -223,6 +229,7 @@ public class ExplorerController extends BaseController implements InitializingBe
List<Integer> counts = new ArrayList<>();
AppliedFilters tempFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
conversionGeoRegionsFilterToOrgCountryFilter(tempFilters);
final GenesysFilter finalFilter = filter;
tempFilters.removeIf(appliedFilter -> appliedFilter.getKey().equals(finalFilter.getKey()));
for (Term term : elasticService.termStatisticsAuto(tempFilters, filter.getKey(), 30).getTerms()) {
......@@ -239,6 +246,7 @@ public class ExplorerController extends BaseController implements InitializingBe
counts = new ArrayList<>();
tempFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
conversionGeoRegionsFilterToOrgCountryFilter(tempFilters);
final GenesysFilter finalFilter2 = filter;
tempFilters.removeIf(appliedFilter -> appliedFilter.getKey().equals(finalFilter2.getKey()));
for (Term term : elasticService.termStatisticsAuto(tempFilters, filter.getKey(), 30).getTerms()) {
......@@ -266,16 +274,33 @@ public class ExplorerController extends BaseController implements InitializingBe
tempFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
model.addAttribute("crops", getCrops(tempFilters));
model.addAttribute("crops", getCrops(appliedFilters));
model.addAttribute("pagedData", accessions);
model.addAttribute("appliedFilters", getAppliedFilters(appliedFilters));
model.addAttribute("appliedFilters", getAppliedFilters(tempFilters));
model.addAttribute("currentFilters", currentFilters);
model.addAttribute("additionalFilters", additionalFilters);
model.addAttribute("availableFilters", availableFilters);
model.addAttribute("geoRegions", getGeoRegions());
return "/accession/explore2";
}
private List<GeoRegion> getGeoRegions() {
List<GeoRegion> geoRegionList = geoRegionService.findAll();
geoRegionList.removeIf(geoRegion -> geoRegion.getName().equals("World") || geoRegion.getName().equals("Americas"));
List<GeoRegion> resultList = new ArrayList<>();
for(GeoRegion geoRegion: geoRegionList) {
if(geoRegion.getParentRegion().getName().equals("World") || geoRegion.getParentRegion().getName().equals("Americas")) {
geoRegion.setParentRegion(null);
resultList.add(geoRegion);
}
else resultList.add(geoRegion);
}
return resultList;
}
private AppliedFilters getAppliedFilters (AppliedFilters filters) {
AppliedFilters newAppliedFilters = new AppliedFilters();
for(AppliedFilter appliedFilter: filters) {
......@@ -287,11 +312,8 @@ public class ExplorerController extends BaseController implements InitializingBe
}
@RequestMapping(value = "/explore/overview")
public String overview(
ModelMap model,
@RequestParam(value = "filter", required = false, defaultValue = "{}") String jsonFilter
)
throws IOException, SearchException {
public String overview(@RequestParam(value = "filter", required = false, defaultValue = "{}") String jsonFilter,
ModelMap model) throws IOException, SearchException {
AppliedFilters appliedFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
String[] selectedFilters = appliedFilters.getFilterNames();
......@@ -391,6 +413,7 @@ public class ExplorerController extends BaseController implements InitializingBe
@RequestParam(value = "filter", required = true, defaultValue = "{}") String jsonFilter,
@RequestParam(value = "results", required = true, defaultValue = "50") int results) throws IOException, SearchException {
AppliedFilters appliedFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
conversionGeoRegionsFilterToOrgCountryFilter(appliedFilters);
return filterService.listAccessionDetails(appliedFilters, new PageRequest(page - 1, results, new Sort("seqNo")));
}
......@@ -429,6 +452,63 @@ public class ExplorerController extends BaseController implements InitializingBe
return availableFilters;
}
private void conversionGeoRegionsFilterToOrgCountryFilter(final AppliedFilters appliedFilters) {
AppliedFilter geoRegionsFilter = appliedFilters.stream()
.filter(filter -> filter.getFilterName().equals("geoRegions")).findFirst().orElse(null);
List<GeoRegion> geoRegionList = new ArrayList<>();
List<Country> countryList = new ArrayList<>();
Set<String> countryIsoList = new HashSet<>();
if (geoRegionsFilter != null && !geoRegionsFilter.getValues().isEmpty()) {
for (String isoCode: getFilterValues(geoRegionsFilter)) {
geoRegionList.add(geoRegionService.find(isoCode));
}
}
if (!geoRegionList.isEmpty()) {
for (GeoRegion geoRegion: geoRegionList) {
countryList.addAll(geoRegion.getCountries());
}
}
if (!countryList.isEmpty()) {
for (Country country: countryList) {
countryIsoList.add(country.getCode3());
}
}
if (!countryIsoList.isEmpty()) {
AppliedFilter orgCtyFilter = appliedFilters.stream()
.filter(filter -> filter.getFilterName().equals("orgCty.iso3"))
.findFirst().orElse(new AppliedFilter().setFilterName("orgCty.iso3"));
if (!orgCtyFilter.getValues().isEmpty()) {
countryIsoList.addAll(getFilterValues(orgCtyFilter));
}
for (String isoCode: countryIsoList) {
orgCtyFilter.addFilterValue(new FilterHandler.LiteralValueFilter(isoCode));
}
appliedFilters.removeIf(appliedFilter1 -> appliedFilter1.getFilterName().equals("geoRegions"));
if(!appliedFilters.hasFilter("orgCty.iso3"))
appliedFilters.add(orgCtyFilter);
}
}
private Set<String> getFilterValues(final AppliedFilter appliedFilter) {
Set<String> literals = new HashSet<>();
for (FilterHandler.FilterValue filterValue : appliedFilter.getValues()) {
if (filterValue instanceof FilterHandler.LiteralValueFilter) {
FilterHandler.LiteralValueFilter literal = (FilterHandler.LiteralValueFilter) filterValue;
literals.add(literal.getValue().toString());
}
}
return literals;
}
@RequestMapping(value = "/explore/booleanSuggestions", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Map<String, Map<String, Integer>> getBooleanSuggestions(@RequestParam(value = "filter", required = true, defaultValue = "{}") String jsonFilter) throws IOException, SearchException {
......@@ -449,6 +529,14 @@ public class ExplorerController extends BaseController implements InitializingBe
return booleanFilters;
}
@RequestMapping(value = "/explore/transformedFilters", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String getTransformedFilters(@RequestParam(value = "filter", required = true, defaultValue = "{}") String jsonFilter) throws IOException, SearchException {
AppliedFilters appliedFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
conversionGeoRegionsFilterToOrgCountryFilter(appliedFilters);
return appliedFilters.toString();
}
@RequestMapping(value = "/explore/cropSuggestions", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Map<String, Map<String, Integer>> getCropSuggestions(@RequestParam(value = "filter", required = true, defaultValue = "{}") String jsonFilter) throws IOException, SearchException {
......@@ -493,6 +581,9 @@ public class ExplorerController extends BaseController implements InitializingBe
}
model.addAttribute("cropsNames", crops);
List<GeoRegion> geoRegions = geoRegionService.findAll(locale);
model.addAttribute("geoRegions", geoRegions);
response.setHeader("Cache-control", "max-age: 3600, private");
return "/accession/i18n";
......@@ -700,6 +791,7 @@ public class ExplorerController extends BaseController implements InitializingBe
@RequestParam(value = "jsonFilter", required = false, defaultValue = "{}") String jsonFilter) throws IOException {
AppliedFilters appliedFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
conversionGeoRegionsFilterToOrgCountryFilter(appliedFilters);
return filterService.autocomplete(filter, ac, appliedFilters);
}
......
......@@ -430,6 +430,7 @@ filter.seqNo=Detected sequential number
filter.alias=Accession name
filter.crops=Crop name
filter.cropName=Provided crop name
filter.regionOfOrigin=Region of Origin
filter.orgCty.iso3=Country of Origin
filter.institute.code=Holding Institute name
filter.institute.country.iso3=Country of holding institute
......
......@@ -77,6 +77,19 @@ var BrowseUtil = {
},
applySuggestions: function (jsonData, messages) {
$.ajax({
url: '/explore/transformedFilters',
method: 'get',
data: {
filter: JSON.stringify(jsonData)
},
success: function (response) {
BrowseUtil.refreshSuggestions(response, messages);
}
});
},
refreshSuggestions: function (jsonData, messages) {
$.ajax({
url: '/explore/listFilterSuggestions',
method: 'get',
......
......@@ -372,6 +372,21 @@ var GenesysFilterUtil = {
var GenesysFilter = {
normKey : GenesysFilterUtil.normKey,
// add filter with select option
filterSelectList: function (element, jsonData) {
var key = $(element).attr('i-key');
var optionSelected = element.find('option:selected');
var valueSelected = optionSelected.val();
var textSelected = optionSelected.text();
if (!GenesysFilterUtil.existInJson(valueSelected, key, jsonData)) {
GenesysFilterUtil.appendHtml(key, textSelected, valueSelected, element);
jsonData[key] = GenesysFilterUtil.collectData(key, valueSelected, jsonData);
$('.geo-switcher option').removeAttr('selected').filter('[value=empty]').attr('selected', true);
}
return jsonData;
},
// add filter with autocomplete or exact field
filterAutocomplete : function(element, jsonData) {
......
......@@ -49,7 +49,7 @@
<!--Filters-->
<filters:filter-list availableFilters="${availableFilters}" filters="${filters}"
additionalFilters="${additionalFilters}" appliedFilters="${appliedFilters}"
crops="${crops}" crop="${crop}"/>
crops="${crops}" crop="${crop}" geoRegions="${geoRegions}"/>
<!--List-->
<div class="col-lg-10 col-md-9 col-sm-9 col-xs-12 main-col-header">
<div class="nav-header clearfix">
......@@ -352,6 +352,13 @@
}
});
$("body").on("change", ".geo-switcher", function () {
if (jsonData[$(this).attr("i-key")] === undefined) {
BrowseUtil.enableFilter(this, jsonData);
}
GenesysFilter.filterSelectList($(this), jsonData);
});
$("body").on("click", ".filter-list", function () {
if (jsonData[$(this).attr("i-key")] === undefined) {
BrowseUtil.enableFilter(this, jsonData);
......
......@@ -11,6 +11,10 @@ var messages = new Array();
messages["geo.iso3166-3.<spring:message text='${country.getCode3()}' javaScriptEscape='true'/>"] = "<c:out value='${country.getName(locale)}'/>";
</c:forEach>
<c:forEach var="geoRegion" items="${geoRegions}">
messages["<spring:message text='${geoRegion.getName()}' javaScriptEscape='true'/>"] = "<c:out value='${geoRegion.getName(locale)}'/>";
</c:forEach>
<c:forEach items="${cropsNames}" var="cropName">
messages["${cropName.key}"] = "${cropName.value}";
</c:forEach>
\ No newline at end of file
......@@ -4,6 +4,7 @@
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ attribute name="geoRegions" required="true" type="java.util.List" %>
<%@ attribute name="additionalFilters" required="false" type="java.util.List" %>
<%@ attribute name="availableFilters" required="true" type="java.util.Map" %>
<%@ attribute name="filters" required="true" type="java.util.Map" %>
......@@ -104,6 +105,11 @@
appliedFilters="${appliedFilters}" type="option"/>
</filters:panel>
<filters:panel id="regionOfOrigin" title="filter.regionOfOrigin">
<filters:filter availableFilters="${availableFilters}" filterMap="${filters}" filterKey="cropName"
appliedFilters="${appliedFilters}" geoRegions="${geoRegions}" type="geoSelect"/>
</filters:panel>
<filters:panel id="origcty" title="filter.orgCty.iso3">
<filters:filter availableFilters="${availableFilters}" filterMap="${filters}"
filterKey="orgCty.iso3"
......
......@@ -13,6 +13,7 @@
<%@ attribute name="type" required="true" type="java.lang.String" %>
<%@ attribute name="cropList" required="false" type="java.util.Map" %>
<%@ attribute name="currentCrop" required="false" type="org.genesys2.server.model.impl.Crop" %>
<%@ attribute name="geoRegions" required="false" type="java.util.List" %>
<spring:message code="filter.internal.message.between" var="between" arguments=" "/>
<spring:message code="filter.internal.message.and" var="varEnd" arguments=" "/>
......@@ -26,6 +27,7 @@
<c:set var="filter" value="${availableFilters[filterKey]}"/>
<c:set var="normalizedKey" value="${filter.key.replace('.', '-').replace(':', '_')}"/>
<c:set var="appliedFilter" value="${appliedFilters.get(filter.key)}"/>
<c:set var="localeCode" value='"${pageContext.response.locale}"' />
<div id="collapse_filt_${filterKey}" class="${filterKey} col-xs-12">
......@@ -46,6 +48,36 @@
</c:forEach>
<!-- </select> -->
</c:when>
<c:when test="${type eq 'geoSelect'}">
<span class="glyphicon glyphicon-menu-down"></span>
<select class="form-control geo-switcher" i-key="geoRegions" >
<option value="empty"></option>
<c:forEach items="${geoRegions}" var="geoRegion">
<c:if test="${geoRegion.parentRegion eq null}">
<c:set var="string" value="${geoRegion.nameL}"/>
<c:set var="index" value="${fn:indexOf(string, localeCode )}"/>
<c:set var="string" value="${fn:substring(geoRegion.nameL, index, fn:length(geoRegion.nameL))}" />
<c:set var="string" value="${fn:substring(string, 6, fn:length(geoRegion.nameL))}" />
<c:set var="index" value="${fn:indexOf(string, '\"' )}"/>
<c:set var="string" value="${fn:substring(string, 0, index)}" />
<optgroup label="${string}">
<c:forEach items="${geoRegions}" var="subRegion">
<c:remove var="string"/>
<c:if test="${subRegion.parentRegion.name eq geoRegion.name}">
<c:set var="string" value="${subRegion.nameL}"/>
<c:set var="index" value="${fn:indexOf(string, localeCode )}"/>
<c:set var ="string" value="${fn:substring(subRegion.nameL, index, fn:length(subRegion.nameL))}" />
<c:set var="string" value="${fn:substring(string, 6, fn:length(subRegion.nameL))}" />
<c:set var="index" value="${fn:indexOf(string, '\"' )}"/>
<c:set var="string" value="${fn:substring(string, 0, index)}" />
<option value="${subRegion.isoCode}">${string}</option>
</c:if>
</c:forEach>
</optgroup>
</c:if>
</c:forEach>
</select>
</c:when>
<c:when test="${type eq 'like'}">
<span class="glyphicon glyphicon-menu-down"></span>
<select class="form-control like-switcher">
......
Markdown is supported
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