Commit 1b5d0292 authored by Matija Obreza's avatar Matija Obreza
Browse files

Filter selection

parent ad052e8e
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package org.genesys2.server.service; package org.genesys2.server.service;
import java.util.Collection;
import java.util.List; import java.util.List;
import org.genesys2.server.model.genesys.Accession; import org.genesys2.server.model.genesys.Accession;
...@@ -31,6 +32,8 @@ public interface GenesysFilterService { ...@@ -31,6 +32,8 @@ public interface GenesysFilterService {
List<GenesysFilter> listAvailableFilters(); List<GenesysFilter> listAvailableFilters();
public static interface GenesysFilter { public static interface GenesysFilter {
public String getKey();
public enum DataType { public enum DataType {
FIXEDSTRING, STRING, NUMERIC, BOOLEAN FIXEDSTRING, STRING, NUMERIC, BOOLEAN
...@@ -40,4 +43,8 @@ public interface GenesysFilterService { ...@@ -40,4 +43,8 @@ public interface GenesysFilterService {
EXACT, RANGE, LIST EXACT, RANGE, LIST
} }
} }
List<GenesysFilter> selectFilters(String[] selectedFilters);
Collection<GenesysFilter> generateFilters(Collection<Long> methodIds);
} }
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
package org.genesys2.server.service; package org.genesys2.server.service;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -25,7 +24,6 @@ import org.genesys2.server.model.genesys.Method; ...@@ -25,7 +24,6 @@ import org.genesys2.server.model.genesys.Method;
import org.genesys2.server.model.genesys.Parameter; import org.genesys2.server.model.genesys.Parameter;
import org.genesys2.server.model.genesys.ParameterCategory; import org.genesys2.server.model.genesys.ParameterCategory;
import org.genesys2.server.model.impl.Crop; import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.service.GenesysFilterService.GenesysFilter;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
...@@ -89,6 +87,4 @@ public interface TraitService { ...@@ -89,6 +87,4 @@ public interface TraitService {
Map<Long, List<Method>> mapMethods(Crop crop); Map<Long, List<Method>> mapMethods(Crop crop);
Collection<GenesysFilter> generateFilters(List<Long> methodIds);
} }
...@@ -17,19 +17,25 @@ ...@@ -17,19 +17,25 @@
package org.genesys2.server.service.impl; package org.genesys2.server.service.impl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.genesys2.server.model.genesys.Accession; import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.Method; import org.genesys2.server.model.genesys.Method;
import org.genesys2.server.persistence.domain.AccessionRepository; import org.genesys2.server.persistence.domain.AccessionRepository;
import org.genesys2.server.persistence.domain.MethodRepository;
import org.genesys2.server.persistence.domain.TraitValueRepository; import org.genesys2.server.persistence.domain.TraitValueRepository;
import org.genesys2.server.service.GenesysFilterService; import org.genesys2.server.service.GenesysFilterService;
import org.genesys2.server.service.GenesysFilterService.GenesysFilter.DataType; import org.genesys2.server.service.GenesysFilterService.GenesysFilter.DataType;
...@@ -58,6 +64,9 @@ public class GenesysFilterServiceImpl implements GenesysFilterService { ...@@ -58,6 +64,9 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
@Autowired @Autowired
private TraitValueRepository traitValueRepository; private TraitValueRepository traitValueRepository;
@Autowired
private MethodRepository methodRepository;
@Autowired @Autowired
private AccessionRepository accessionRepository; private AccessionRepository accessionRepository;
...@@ -77,16 +86,18 @@ public class GenesysFilterServiceImpl implements GenesysFilterService { ...@@ -77,16 +86,18 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
public GenesysFilterServiceImpl() { public GenesysFilterServiceImpl() {
this.availableFilters = new ArrayList<GenesysFilter>(); this.availableFilters = new ArrayList<GenesysFilter>();
// "origin", "institute", "lat", "lon", "alt", "genus" // "origin", "institute", "lat", "lon", "alt", "genus"
this.availableFilters.add(new GenesysFilterImpl("accenumb", DataType.NUMERIC)); this.availableFilters.add(new GenesysFilterImpl("crop", DataType.STRING));
this.availableFilters.add(new GenesysFilterImpl("genus", DataType.STRING));
this.availableFilters.add(new GenesysFilterImpl("taxon", DataType.STRING));
this.availableFilters.add(new GenesysFilterImpl("origin", DataType.FIXEDSTRING, 3)); this.availableFilters.add(new GenesysFilterImpl("origin", DataType.FIXEDSTRING, 3));
this.availableFilters.add(new GenesysFilterImpl("institute", DataType.FIXEDSTRING, 6));
this.availableFilters.add(new GenesysFilterImpl("organization", DataType.STRING));
this.availableFilters.add(new GenesysFilterImpl("lat", DataType.NUMERIC)); this.availableFilters.add(new GenesysFilterImpl("lat", DataType.NUMERIC));
this.availableFilters.add(new GenesysFilterImpl("lon", DataType.NUMERIC)); this.availableFilters.add(new GenesysFilterImpl("lon", DataType.NUMERIC));
this.availableFilters.add(new GenesysFilterImpl("elevation", DataType.NUMERIC)); this.availableFilters.add(new GenesysFilterImpl("elevation", DataType.NUMERIC));
this.availableFilters.add(new GenesysFilterImpl("genus", DataType.STRING));
this.availableFilters.add(new GenesysFilterImpl("taxon", DataType.STRING)); this.availableFilters.add(new GenesysFilterImpl("organization", DataType.STRING));
this.availableFilters.add(new GenesysFilterImpl("crop", DataType.STRING)); this.availableFilters.add(new GenesysFilterImpl("institute", DataType.FIXEDSTRING, 6));
this.availableFilters.add(new GenesysFilterImpl("accenumb", DataType.NUMERIC));
this.availableFilters.add(new GenesysFilterImpl("inSvalbard", DataType.BOOLEAN)); this.availableFilters.add(new GenesysFilterImpl("inSvalbard", DataType.BOOLEAN));
this.availableFilters.add(new GenesysFilterImpl("mls", DataType.BOOLEAN)); this.availableFilters.add(new GenesysFilterImpl("mls", DataType.BOOLEAN));
this.availableFilters.add(new GenesysFilterImpl("available", DataType.BOOLEAN)); this.availableFilters.add(new GenesysFilterImpl("available", DataType.BOOLEAN));
...@@ -97,6 +108,50 @@ public class GenesysFilterServiceImpl implements GenesysFilterService { ...@@ -97,6 +108,50 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
return Collections.unmodifiableList(this.availableFilters); return Collections.unmodifiableList(this.availableFilters);
} }
@Override
public List<GenesysFilter> selectFilters(String[] selectedFilters) {
List<GenesysFilter> filters = new ArrayList<GenesysFilter>();
Set<Long> methodIds = new HashSet<Long>();
for (final String selectedFilter : selectedFilters) {
if (selectedFilter.startsWith("gm:")) {
try {
methodIds.add(Long.parseLong(selectedFilter.substring(3)));
} catch (NumberFormatException | NullPointerException e) {
LOG.warn(e);
}
} else {
GenesysFilter coreFilter = CollectionUtils.find(this.availableFilters, new Predicate<GenesysFilter>() {
@Override
public boolean evaluate(GenesysFilter object) {
return object.getKey().equals(selectedFilter);
}
});
if (coreFilter != null) {
filters.add(coreFilter);
}
}
}
filters.addAll(generateFilters(methodIds));
return filters;
}
@Override
public Collection<GenesysFilter> generateFilters(Collection<Long> methodIds) {
List<GenesysFilter> filters = new ArrayList<GenesysFilter>();
for (long methodId : methodIds) {
Method method = methodRepository.findOne(methodId);
if (method == null) {
continue;
}
filters.add(new GenesysMethodFilterImpl("gm:" + method.getId(), method.getParameter().getTitle(), method.getFieldType() == 1
|| method.getFieldType() == 2 ? DataType.NUMERIC : DataType.STRING));
}
return filters;
}
@Override @Override
public Page<Accession> listAccessions(JsonNode jsonTree, Pageable pageable) { public Page<Accession> listAccessions(JsonNode jsonTree, Pageable pageable) {
Iterator<Entry<String, JsonNode>> fields = jsonTree.fields(); Iterator<Entry<String, JsonNode>> fields = jsonTree.fields();
...@@ -376,6 +431,10 @@ public class GenesysFilterServiceImpl implements GenesysFilterService { ...@@ -376,6 +431,10 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
private DataType dataType; private DataType dataType;
private FilterType filterType; private FilterType filterType;
private Integer maxLength; private Integer maxLength;
public boolean isCore() {
return true;
}
public GenesysFilterImpl(String name, DataType type) { public GenesysFilterImpl(String name, DataType type) {
this.name = name; this.name = name;
...@@ -397,6 +456,11 @@ public class GenesysFilterServiceImpl implements GenesysFilterService { ...@@ -397,6 +456,11 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
this.maxLength = i; this.maxLength = i;
} }
@Override
public String getKey() {
return name;
}
public String getName() { public String getName() {
return name; return name;
} }
...@@ -404,7 +468,7 @@ public class GenesysFilterServiceImpl implements GenesysFilterService { ...@@ -404,7 +468,7 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
public DataType getDataType() { public DataType getDataType() {
return dataType; return dataType;
} }
public FilterType getFilterType() { public FilterType getFilterType() {
return filterType; return filterType;
} }
...@@ -413,4 +477,22 @@ public class GenesysFilterServiceImpl implements GenesysFilterService { ...@@ -413,4 +477,22 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
return maxLength; return maxLength;
} }
} }
public static class GenesysMethodFilterImpl extends GenesysFilterImpl {
private String title;
@Override
public boolean isCore() {
return false;
}
public GenesysMethodFilterImpl(String name, String title, DataType dataType) {
super(name, dataType);
this.title = title;
}
public String getTitle() {
return title;
}
}
} }
...@@ -82,11 +82,9 @@ import org.genesys2.server.persistence.domain.TraitValueRepository; ...@@ -82,11 +82,9 @@ import org.genesys2.server.persistence.domain.TraitValueRepository;
import org.genesys2.server.security.AuthUserDetails; import org.genesys2.server.security.AuthUserDetails;
import org.genesys2.server.service.AclService; import org.genesys2.server.service.AclService;
import org.genesys2.server.service.DatasetService; import org.genesys2.server.service.DatasetService;
import org.genesys2.server.service.GenesysFilterService.GenesysFilter.DataType;
import org.genesys2.server.service.GenesysService; import org.genesys2.server.service.GenesysService;
import org.genesys2.server.service.HtmlSanitizer; import org.genesys2.server.service.HtmlSanitizer;
import org.genesys2.server.service.TraitService; import org.genesys2.server.service.TraitService;
import org.genesys2.server.service.GenesysFilterService.GenesysFilter;
import org.genesys2.spring.SecurityContextUtil; import org.genesys2.spring.SecurityContextUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
...@@ -1181,17 +1179,4 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset ...@@ -1181,17 +1179,4 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset
return paramMethods; return paramMethods;
} }
@Override
public Collection<GenesysFilter> generateFilters(List<Long> methodIds) {
List<GenesysFilter> filters = new ArrayList<GenesysFilter>();
for (long methodId : methodIds) {
Method method = methodRepository.findOne(methodId);
if (method == null) {
continue;
}
filters.add(new GenesysFilterServiceImpl.GenesysFilterImpl("gm:" + method.getId(),
method.getFieldType() == 1 || method.getFieldType() == 2 ? DataType.NUMERIC : DataType.STRING));
}
return filters;
}
} }
...@@ -16,17 +16,13 @@ ...@@ -16,17 +16,13 @@
package org.genesys2.server.servlet.controller; package org.genesys2.server.servlet.controller;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import org.genesys2.server.model.genesys.Accession; import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.ParameterCategory;
import org.genesys2.server.model.impl.Crop; import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.CropTaxonomy; import org.genesys2.server.model.impl.CropTaxonomy;
import org.genesys2.server.service.CropService; import org.genesys2.server.service.CropService;
import org.genesys2.server.service.GenesysFilterService; import org.genesys2.server.service.GenesysFilterService;
import org.genesys2.server.service.GenesysFilterService.GenesysFilter;
import org.genesys2.server.service.GenesysService; import org.genesys2.server.service.GenesysService;
import org.genesys2.server.service.TraitService; import org.genesys2.server.service.TraitService;
import org.genesys2.spring.ResourceNotFoundException; import org.genesys2.spring.ResourceNotFoundException;
...@@ -116,40 +112,6 @@ public class CropController extends BaseController { ...@@ -116,40 +112,6 @@ public class CropController extends BaseController {
return "/accession/data"; return "/accession/data";
} }
@RequestMapping(value = "/{shortName}/data/descriptors", method = RequestMethod.GET)
public String viewDescriptors(ModelMap model, @PathVariable(value = "shortName") String shortName) {
_logger.warn("Viewing crop descriptors " + shortName);
Crop crop = cropService.getCrop(shortName);
if (crop == null) {
throw new ResourceNotFoundException();
}
model.addAttribute("crop", crop);
List<ParameterCategory> parameterCategories = traitService.listCategories();
model.addAttribute("categories", parameterCategories);
model.addAttribute("descriptors", traitService.mapTraits(crop, parameterCategories));
model.addAttribute("methods", traitService.mapMethods(crop));
return "/filter/cropdescriptors";
}
@RequestMapping(value = "/{shortName}/data/descriptors", method = RequestMethod.POST)
public String selectDescriptors(ModelMap model, @PathVariable(value = "shortName") String shortName, @RequestParam("methods") List<Long> methodIds) {
_logger.warn("Viewing crop descriptors " + shortName);
Crop crop = cropService.getCrop(shortName);
if (crop == null) {
throw new ResourceNotFoundException();
}
// What filters do we support?
List<GenesysFilter> availableFilters = new ArrayList<GenesysFilter>();
availableFilters.addAll(filterService.listAvailableFilters());
availableFilters.addAll(traitService.generateFilters(methodIds));
model.addAttribute("availableFilters", availableFilters);
return "/filter/index";
}
@RequestMapping("/{shortName}/descriptors") @RequestMapping("/{shortName}/descriptors")
public String viewDescriptors(ModelMap model, @PathVariable(value = "shortName") String shortName, public String viewDescriptors(ModelMap model, @PathVariable(value = "shortName") String shortName,
@RequestParam(value = "page", required = false, defaultValue = "1") int page) { @RequestParam(value = "page", required = false, defaultValue = "1") int page) {
......
...@@ -62,6 +62,18 @@ public class DescriptorController extends BaseController { ...@@ -62,6 +62,18 @@ public class DescriptorController extends BaseController {
return "/descr/details"; return "/descr/details";
} }
/**
* Redirect "/descriptor/gm:1234" URLs to "/descriptor/{traitId}/{methodId}"
*/
@RequestMapping("/gm:{methodId}")
public String viewMethod(ModelMap model, @PathVariable("methodId") long methodId) {
Method method = traitService.getMethod(methodId);
if (method == null) {
throw new ResourceNotFoundException();
}
return "redirect:/descriptors/" + method.getParameter().getId() + "/" + method.getId();
}
@RequestMapping("/{traitId}/{methodId}") @RequestMapping("/{traitId}/{methodId}")
public String view(ModelMap model, @PathVariable("traitId") long traitId, @PathVariable("methodId") long methodId) { public String view(ModelMap model, @PathVariable("traitId") long traitId, @PathVariable("methodId") long methodId) {
Parameter trait = traitService.getTrait(traitId); Parameter trait = traitService.getTrait(traitId);
...@@ -86,7 +98,6 @@ public class DescriptorController extends BaseController { ...@@ -86,7 +98,6 @@ public class DescriptorController extends BaseController {
model.addAttribute("codeStatistics", traitService.getMethodStatistics(method)); model.addAttribute("codeStatistics", traitService.getMethodStatistics(method));
} }
return "/descr/method"; return "/descr/method";
} }
} }
/**
* Copyright 2013 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.servlet.controller;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.genesys2.server.model.genesys.ParameterCategory;
import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.service.CropService;
import org.genesys2.server.service.GenesysFilterService;
import org.genesys2.server.service.GenesysService;
import org.genesys2.server.service.InstituteService;
import org.genesys2.server.service.TaxonomyService;
import org.genesys2.server.service.TraitService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@Controller
@RequestMapping("/explore")
public class ExplorerController extends BaseController {
@Autowired
private GenesysFilterService filterService;
@Autowired
private CropService cropService;
@Autowired
private TraitService traitService;
@Autowired
private InstituteService instituteService;
@Autowired
private GenesysService genesysService;
@Autowired
private TaxonomyService taxonomyService;
private ObjectMapper mapper = new ObjectMapper();
@RequestMapping(value = "/pick", method = RequestMethod.GET)
public String pickFilters(ModelMap model, @RequestParam(value = "filter", required = false, defaultValue = "{}") String jsonFilter,
@RequestParam(value = "pick", required = false, defaultValue = "[]") String pick, @RequestParam(value = "crop", required = false) String shortName) {
String[] selectedFilters = new String[0];
try {
selectedFilters = mapper.readValue(pick, selectedFilters.getClass());
} catch (IOException e) {
_logger.error(e.getMessage(), e);
}
if (StringUtils.isNotBlank(shortName)) {
// Add crop descriptors
Crop crop = cropService.getCrop(shortName);
if (crop != null) {
model.addAttribute("crop", crop);
List<ParameterCategory> parameterCategories = traitService.listCategories();
model.addAttribute("categories", parameterCategories);
model.addAttribute("descriptors", traitService.mapTraits(crop, parameterCategories));
model.addAttribute("methods", traitService.mapMethods(crop));
}
}
// What filters do we support?
model.addAttribute("availableFilters", filterService.listAvailableFilters());
model.addAttribute("jsonString", jsonFilter);
model.addAttribute("selectedFilters", new HashSet<String>(Arrays.asList(selectedFilters)));
model.addAttribute("crops", cropService.list(getLocale()));
return "/filter/pick";
}
@RequestMapping(value = "/pick", method = RequestMethod.POST)
public String doPickFilters(ModelMap model, @RequestParam(value = "filter", required = false, defaultValue = "{}") String jsonFilter,
@RequestParam(value = "pick", required = false) String[] pick, @RequestParam(value = "crop", required = false) String shortName) {
if (StringUtils.isNotBlank(shortName)) {
Crop crop = cropService.getCrop(shortName);
if (crop != null) {
model.addAttribute("crop", crop.getShortName());
}
}
try {
if (pick != null)
model.addAttribute("pick", mapper.writeValueAsString(pick));
} catch (JsonProcessingException e) {
_logger.error(e.getMessage(), e);
}
model.addAttribute("filter", jsonFilter);
return "redirect:/explore/pick";
}
@RequestMapping(value = "/pick", method = RequestMethod.POST, params = { "doView" })
public String doView(ModelMap model, @RequestParam(value = "filter", required = false, defaultValue = "{}") String jsonFilter,
@RequestParam(value = "pick", required = false) String[] pick, @RequestParam(value = "crop", required = false) String shortName) {
doPickFilters(model, jsonFilter, pick, shortName);
return "redirect:/explore/filter";
}
@RequestMapping(value = "/filter", method = RequestMethod.GET)
public String showFilters(ModelMap model, @RequestParam(value = "filter", required = false, defaultValue = "{}") String jsonFilter,
@RequestParam(value = "pick", required = false, defaultValue = "[]") String pick, @RequestParam(value = "crop", required = false) String shortName) {
String[] selectedFilters = new String[0];
try {
selectedFilters = mapper.readValue(pick, selectedFilters.getClass());
} catch (IOException e) {
_logger.