Commit 28b20edb authored by Matija Obreza's avatar Matija Obreza

ElasticsearchService using AppliedFilters

parent 64e3c84c
......@@ -16,22 +16,37 @@
package org.genesys2.server.model.filters;
public class BasicFilter implements GenesysFilter {
private final String name;
private final DataType dataType;
private FilterType filterType;
private final Integer maxLength;
private boolean analyzed = false;
@Override
public boolean isCore() {
return true;
}
/**
* Is the field analyzed by indexer?
*/
@Override
public boolean isAnalyzed() {
return this.analyzed;
};
public BasicFilter setAnalyzed(boolean analyzed) {
this.analyzed = analyzed;
return this;
}
public BasicFilter(String name, DataType type) {
this.name = name;
this.dataType = type;
if (this.dataType == DataType.NUMERIC) {
this.analyzed = false;
this.filterType = FilterType.RANGE;
} else {
this.filterType = FilterType.EXACT;
......@@ -62,14 +77,12 @@ public class BasicFilter implements GenesysFilter {
return name;
}
public String getName() {
return name;
}
@Override
public DataType getDataType() {
return dataType;
}
@Override
public FilterType getFilterType() {
return filterType;
}
......
......@@ -16,15 +16,24 @@
package org.genesys2.server.model.filters;
public interface GenesysFilter {
public String getKey();
public enum DataType {
FIXEDSTRING, STRING, NUMERIC, BOOLEAN
STRING, NUMERIC, BOOLEAN
}
public enum FilterType {
EXACT, RANGE, LIST, AUTOCOMPLETE, I18NLIST
}
boolean isCore();
DataType getDataType();
FilterType getFilterType();
public boolean isAnalyzed();
}
\ No newline at end of file
......@@ -38,7 +38,7 @@ public interface ElasticService {
void refreshIndex(String className);
Page<AccessionDetails> filter(String jsonFilter, Pageable pageable) throws SearchException;
Page<AccessionDetails> filter(AppliedFilters appliedFilters, Pageable pageable) throws SearchException;
}
......@@ -27,6 +27,7 @@ import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
......@@ -38,9 +39,6 @@ import org.genesys2.server.model.filters.GenesysFilter.DataType;
import org.genesys2.server.model.filters.GenesysFilter.FilterType;
import org.genesys2.server.model.filters.I18nListFilter;
import org.genesys2.server.model.filters.MethodFilter;
import org.genesys2.server.model.filters.NoSuchFilterException;
import org.genesys2.server.model.filters.NoSuchFilterValueException;
import org.genesys2.server.model.filters.UnsupportedFilterOperation;
import org.genesys2.server.model.filters.ValueName;
import org.genesys2.server.model.genesys.Method;
import org.genesys2.server.model.genesys.TraitCode;
......@@ -96,13 +94,13 @@ public class FilterHandler {
this.availableFilters.add(new BasicFilter(FilterConstants.ORGANIZATION, DataType.STRING));
this.availableFilters.add(new AutocompleteFilter(FilterConstants.INSTCODE, "/explore/ac/instCode"));
this.availableFilters.add(new BasicFilter(FilterConstants.ACCENUMB, DataType.STRING, FilterType.RANGE));
this.availableFilters.add(new BasicFilter(FilterConstants.ALIAS, DataType.STRING, FilterType.RANGE));
this.availableFilters.add(new BasicFilter(FilterConstants.ACCENUMB, DataType.STRING, FilterType.RANGE).setAnalyzed(true));
this.availableFilters.add(new BasicFilter(FilterConstants.ALIAS, DataType.STRING, FilterType.RANGE).setAnalyzed(true));
this.availableFilters.add(new BasicFilter(FilterConstants.SGSV, DataType.BOOLEAN));
this.availableFilters.add(new BasicFilter(FilterConstants.MLSSTATUS, DataType.BOOLEAN));
this.availableFilters.add(new BasicFilter(FilterConstants.ART15, DataType.BOOLEAN));
this.availableFilters.add(new BasicFilter(FilterConstants.AVAILABLE, DataType.BOOLEAN));
this.availableFilters.add(new BasicFilter(FilterConstants.COLLMISSID, DataType.STRING));
this.availableFilters.add(new BasicFilter(FilterConstants.COLLMISSID, DataType.STRING).setAnalyzed(true));
this.availableFilters.add(new I18nListFilter<Integer>(FilterConstants.STORAGE, DataType.NUMERIC).build("accession.storage", new Integer[] { 10, 11, 12,
13, 20, 30, 40, 50, 99 }));
}
......@@ -111,37 +109,39 @@ public class FilterHandler {
return Collections.unmodifiableList(this.availableFilters);
}
public GenesysFilter getFilter(String key) {
if (key.startsWith("gm:")) {
return getMethodFilter(key);
}
for (GenesysFilter f : this.availableFilters) {
if (f.getKey().equals(key))
return f;
}
return null;
}
public List<GenesysFilter> selectFilters(String[] selectedFilters) {
LOG.debug("Loading filter definitions sel=" + ArrayUtils.toString(selectedFilters));
final List<GenesysFilter> filters = new ArrayList<GenesysFilter>();
for (final String selectedFilter : selectedFilters) {
if (selectedFilter.startsWith("gm:")) {
try {
final GenesysFilter methodFilter = getMethodFilter(Long.parseLong(selectedFilter.substring(3)));
if (methodFilter != null) {
filters.add(methodFilter);
}
} catch (NumberFormatException | NullPointerException e) {
LOG.warn(e);
}
} else {
final 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);
try {
final GenesysFilter filter = getFilter(selectedFilter);
if (filter != null) {
filters.add(filter);
}
} catch (NumberFormatException | NullPointerException e) {
LOG.warn(e);
}
}
return filters;
}
GenesysFilter getMethodFilter(long methodId) {
GenesysFilter getMethodFilter(String methodFilterName) {
long methodId = Long.parseLong(methodFilterName.substring(3));
final Method method = traitService.getMethod(methodId);
return method == null ? null : toFilter(method);
}
......@@ -172,75 +172,6 @@ public class FilterHandler {
return filter;
}
public List<AppliedFilter> fromJSON(String jsonFilter) throws IOException, NoSuchFilterException, UnsupportedFilterOperation, NoSuchFilterValueException {
@SuppressWarnings("unchecked")
Map<String, List<Object>> filters = objectMapper.readValue(jsonFilter, Map.class);
AppliedFilters appliedFilters = new AppliedFilters();
for (String key : filters.keySet()) {
List<Object> filterValues = filters.get(key);
if (filterValues == null || filterValues.isEmpty())
continue;
LOG.info("key=" + key);
AppliedFilter appliedFilter = new AppliedFilter();
appliedFilter.setFilter(getFilterByName(key));
for (Object filterValue : filterValues) {
appliedFilter.addFilterValue(toFilterValue(filterValue));
}
}
return appliedFilters;
}
private FilterValue toFilterValue(Object filterValue) throws UnsupportedFilterOperation, NoSuchFilterValueException {
if (filterValue == null)
return null;
if (filterValue instanceof Map) {
return toFilterOperation((Map<?, ?>) filterValue);
} else if (filterValue instanceof Number || filterValue instanceof String) {
return new LiteralValueFilter(filterValue);
} else {
throw new NoSuchFilterValueException(filterValue);
}
}
private FilterValue toFilterOperation(Map<?, ?> filterValue) throws UnsupportedFilterOperation {
@SuppressWarnings("unchecked")
List<Number> range = (List<Number>) filterValue.get("range");
if (range != null) {
return new ValueRangeFilter(range.get(0), range.get(1));
}
Number max = (Number) filterValue.get("max");
if (max != null) {
return new MaxValueFilter(max);
}
Number min = (Number) filterValue.get("min");
if (min != null) {
return new MinValueFilter(min);
}
String like = (String) filterValue.get("like");
if (like != null) {
return new StartsWithFilter(like);
}
throw new UnsupportedFilterOperation(filterValue.toString());
}
private GenesysFilter getFilterByName(String key) throws NoSuchFilterException {
for (GenesysFilter filter : this.availableFilters) {
if (filter.getKey().equals(key)) {
return filter;
}
}
throw new NoSuchFilterException(key);
}
public static interface FilterValue {
String getType();
}
......@@ -316,7 +247,11 @@ public class FilterHandler {
jp.nextToken();
String op = jp.getCurrentName();
if ("like".equals(op)) {
af.addFilterValue(new StartsWithFilter(jp.nextTextValue()));
String startsWith = jp.nextTextValue();
if (startsWith == null || StringUtils.isBlank(startsWith))
throw new JsonParseException("StartsWithFilter expects a non-blank string", jp.getCurrentLocation());
af.addFilterValue(new StartsWithFilter(startsWith));
} else if ("min".equals(op)) {
Number number1 = null;
jp.nextToken();
......@@ -436,6 +371,7 @@ public class FilterHandler {
* @param class1
* @return
*/
@SuppressWarnings("unchecked")
public <T> T getFirstLiteralValue(String filterName, Class<T> clazz) {
AppliedFilter af = get(filterName);
if (af != null) {
......@@ -453,15 +389,10 @@ public class FilterHandler {
public static class AppliedFilter {
private GenesysFilter filter;
private Set<FilterValue> values = new HashSet<FilterValue>();
private boolean withNull = false;
private String filterName;
public void setFilter(GenesysFilter filter) {
this.filter = filter;
}
public String getFilterName() {
return this.filterName;
}
......@@ -481,10 +412,6 @@ public class FilterHandler {
return this;
}
public GenesysFilter getFilter() {
return filter;
}
public boolean getWithNull() {
return this.withNull;
}
......
......@@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.genesys2.server.model.elastic.AccessionDetails;
import org.genesys2.server.model.filters.GenesysFilter;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.Method;
......@@ -37,6 +38,7 @@ import org.genesys2.server.model.genesys.Parameter;
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.ElasticService;
import org.genesys2.server.service.FilterConstants;
import org.genesys2.server.service.GenesysFilterService;
import org.genesys2.server.service.GenesysService;
......@@ -48,6 +50,7 @@ import org.genesys2.server.service.impl.FilterHandler;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilter;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
import org.genesys2.server.service.impl.GenesysFilterServiceImpl.LabelValue;
import org.genesys2.server.service.impl.SearchException;
import org.genesys2.spring.ResourceNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
......@@ -62,7 +65,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jhlabs.image.MapColorsFilter;
......@@ -71,6 +73,9 @@ public class ExplorerController extends BaseController {
@Autowired
private GenesysFilterService filterService;
@Autowired
private ElasticService elasticService;
@Autowired
private CropService cropService;
......@@ -181,6 +186,66 @@ public class ExplorerController extends BaseController {
return "/accession/explore";
}
/**
* Browse all using Elasticsearch
*
* @param model
* @param page
* @return
* @throws IOException
* @throws SearchException
*/
@RequestMapping("/explore-es")
public String viewElasticFiltered(ModelMap model, @RequestParam(value = "page", required = false, defaultValue = "1") int page,
@RequestParam(value = "filter", required = true, defaultValue = "{}") String jsonFilter) throws IOException, SearchException {
String[] selectedFilters = null;
_logger.debug("Filtering by: " + jsonFilter);
AppliedFilters appliedFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
Crop crop = null;
{
String shortName = appliedFilters.getFirstLiteralValue(FilterConstants.CROPS, String.class);
if (shortName != null)
crop = cropService.getCrop((String) shortName);
if (crop != null) {
// Keep only one crop
AppliedFilter af = appliedFilters.get(FilterConstants.CROPS);
af.getValues().clear();
af.addFilterValue(new FilterHandler.LiteralValueFilter(crop.getShortName()));
}
}
model.addAttribute("crop", crop);
// JSP works with JsonObject
final Map<String, List<String>> filters = mapper.readValue(appliedFilters.toString(), Map.class);
model.addAttribute("filters", filters);
selectedFilters = appliedFilters.getFilterNames();
final List<GenesysFilter> currentFilters = filterHandler.selectFilters(selectedFilters);
final List<GenesysFilter> availableFilters = filterHandler.listAvailableFilters();
_logger.info(appliedFilters.toString());
model.addAttribute("jsonFilter", appliedFilters.toString());
final Page<AccessionDetails> accessions = elasticService.filter(appliedFilters, new PageRequest(page - 1, 50, new Sort("acceNumb")));
_logger.info("Got: " + accessions);
model.addAttribute("crops", cropService.list(getLocale()));
model.addAttribute("pagedData", accessions);
model.addAttribute("currentFilters", currentFilters);
model.addAttribute("availableFilters", availableFilters);
return "/accession/explore-es";
}
@RequestMapping(value = "/additional-filter", method = RequestMethod.GET)
public String getAdditionalFilters(ModelMap model, @RequestParam(value = "filter", required = true, defaultValue = "") String[] selectedFilters)
throws IOException {
......
This diff is collapsed.
......@@ -377,13 +377,13 @@
});
$("body").on("click", ".apply", function () {
GenesysFilterUtil.submitJson(jsonData);
GenesysFilterUtil.submitJson('/explore', jsonData);
});
$("body").on("click", ".remove-filter", function () {
var key = $(this).parents(".filter-block").attr("i-key");
delete jsonData[key];
GenesysFilterUtil.submitJson(jsonData);
GenesysFilterUtil.submitJson('/explore', jsonData);
});
$("body").on("click", ".edit-fil", function () {
......@@ -407,7 +407,7 @@
GenesysFilterUtil.removeValue(value, key, jsonData);
if (! $(this).parents(".filter-block").hasClass("filter-edit")) {
GenesysFilterUtil.submitJson(jsonData);
GenesysFilterUtil.submitJson('/explore', jsonData);
}
$(this).remove();
......
......@@ -373,9 +373,9 @@ GenesysFilterUtil = {
return str.substr(0, index) + chr + str.substr(index + 1);
},
//form 'get' request
submitJson: function (jsonData) {
submitJson: function (url, jsonData) {
var filter = JSON.stringify(jsonData);
var url = '/explore?filter=' + filter;
var url = url + '?filter=' + filter;
window.location.href = encodeURI(url);
},
......
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