Commit 7a77cf6a authored by Maxym Borodenko's avatar Maxym Borodenko Committed by Matija Obreza
Browse files

Filter by last update date

parent 3f540233
......@@ -91,7 +91,7 @@ public class AccessionDetails {
@Field(index = FieldIndex.not_analyzed, type = FieldType.String)
private String donorNumb;
private Date modifiedDate;
private Date lastModifiedDate;
private Date acqusitionDate;
private Float pdciScore;
......@@ -114,7 +114,7 @@ public class AccessionDetails {
ad.id = accession.getId();
ad.uuid = accession.getUuid();
ad.createdDate = accession.getCreatedDate();
ad.modifiedDate = accession.getLastModifiedDate();
ad.lastModifiedDate = accession.getLastModifiedDate();
ad.acceNumb = accession.getAccessionName();
ad.seqNo = accession.getSeqNo();
ad.acqDate = accession.getAcquisitionDate();
......@@ -450,12 +450,12 @@ public class AccessionDetails {
this.donorNumb = donorNumb;
}
public Date getModifiedDate() {
return modifiedDate;
public Date getLastModifiedDate() {
return lastModifiedDate;
}
public void setModifiedDate(Date modifiedDate) {
this.modifiedDate = modifiedDate;
public void setLastModifiedDate(Date lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
public Date getAcqusitionDate() {
......
......@@ -89,4 +89,6 @@ public interface FilterConstants {
public static final String REGION_HOLD_INSTITUTE= "regionHoldInst";
public static final String LAST_MODIFIED_DATE = "lastModifiedDate";
}
......@@ -174,6 +174,7 @@ public class DirectMysqlQuery {
createQuery(whereBuffer, "al.uuid", filters.get(FilterConstants.LISTS), params);
createQuery(whereBuffer, "a.acceNumb", filters.get(FilterConstants.ACCENUMB), params);
createQuery(whereBuffer, "a.seqNo", filters.get(FilterConstants.SEQUENTIAL_NUMBER), params);
createQuery(whereBuffer, "a.lastModifiedDate", filters.get(FilterConstants.LAST_MODIFIED_DATE), params);
createQuery(whereBuffer, "a.orgCty", filters.get(FilterConstants.ORGCTY_ISO3), params);
createQuery(whereBuffer, "a.instCode", filters.get(FilterConstants.INSTCODE), params);
createQuery(whereBuffer, "a.cropName", filters.get(FilterConstants.CROPNAME), params);
......@@ -265,6 +266,10 @@ public class DirectMysqlQuery {
LOG.debug("Handling " + dbName);
}
if (dbName.equals("a.lastModifiedDate") && appliedFilter != null) {
appliedFilter = transformExplicitDateToDateRange(appliedFilter);
}
if (appliedFilter != null && appliedFilter.size() > 0) {
Set<FilterValue> filterValues = appliedFilter.getValues();
......@@ -313,6 +318,27 @@ public class DirectMysqlQuery {
}
private AppliedFilter transformExplicitDateToDateRange(final AppliedFilter appliedFilter) {
if (!appliedFilter.getValues().isEmpty()) {
if (appliedFilter.getValues().toArray()[0] instanceof LiteralValueFilter) {
String date = null;
for (FilterValue filterValue : appliedFilter.getValues()) {
if (filterValue instanceof LiteralValueFilter) {
date = ((LiteralValueFilter) filterValue).getValue().toString();
break;
}
}
if (date != null) {
AppliedFilter newFilter = new AppliedFilter();
newFilter.setFilterName(appliedFilter.getFilterName());
newFilter.addFilterValue(new ValueRangeFilter((date + " 00:00:00"), (date + " 23:59:59")));
return newFilter;
}
}
}
return appliedFilter;
}
private int handleOperations(StringBuffer sb, String dbName, Set<FilterValue> set, List<Object> params) {
if (LOG.isDebugEnabled()) {
LOG.debug("Inspecting " + dbName + " ... " + set);
......
......@@ -18,13 +18,9 @@ package org.genesys2.server.service.impl;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
......@@ -277,7 +273,7 @@ public class ElasticsearchSearchServiceImpl implements ElasticService, Initializ
if (FilterConstants.SGSV.equals(key)) {
orFilter.add(FilterBuilders.termsFilter(FilterConstants.IN_SGSV, literals).execution("or"));
} else {
} else if (!key.equals(FilterConstants.LAST_MODIFIED_DATE)){
orFilter.add(FilterBuilders.termsFilter(key, literals).execution("or"));
}
}
......@@ -294,11 +290,29 @@ public class ElasticsearchSearchServiceImpl implements ElasticService, Initializ
} else if (filterValue instanceof MaxValueFilter) {
MaxValueFilter max = (MaxValueFilter) filterValue;
LOG.debug("Max " + max);
orFilter.add(FilterBuilders.rangeFilter(key).to(max.getTo()));
if (key.equals(FilterConstants.LAST_MODIFIED_DATE)) {
Date dateTo = null;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
dateTo = format.parse(max.getTo().toString());
} catch (ParseException ignored) {}
if (dateTo != null) {
orFilter.add(FilterBuilders.rangeFilter(key).to(dateTo.getTime()));
}
} else orFilter.add(FilterBuilders.rangeFilter(key).to(max.getTo()));
} else if (filterValue instanceof MinValueFilter) {
MinValueFilter min = (MinValueFilter) filterValue;
LOG.debug("Min " + min);
orFilter.add(FilterBuilders.rangeFilter(key).from(min.getFrom()));
if (key.equals(FilterConstants.LAST_MODIFIED_DATE)) {
Date dateFrom = null;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
dateFrom = format.parse(min.getFrom().toString());
} catch (ParseException ignored) {}
if (dateFrom != null) {
orFilter.add(FilterBuilders.rangeFilter(key).from(dateFrom.getTime()));
}
} else orFilter.add(FilterBuilders.rangeFilter(key).from(min.getFrom()));
} else if (filterValue instanceof StartsWithFilter) {
StartsWithFilter startsWith = (StartsWithFilter) filterValue;
LOG.debug("startsWith " + startsWith);
......@@ -311,6 +325,20 @@ public class ElasticsearchSearchServiceImpl implements ElasticService, Initializ
} else {
orFilter.add(FilterBuilders.prefixFilter(key, startsWith.getStartsWith()));
}
} else if (filterValue instanceof LiteralValueFilter) {
LiteralValueFilter val = (LiteralValueFilter) filterValue;
if (key.equals(FilterConstants.LAST_MODIFIED_DATE)) {
Date dateFrom = null;
Date dateTo = null;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
dateFrom = format.parse(val.getValue().toString() + " 00:00:00");
dateTo = format.parse(val.getValue().toString() + " 23:59:59");
} catch (ParseException ignored) {}
if (dateTo != null && dateFrom != null) {
orFilter.add(FilterBuilders.rangeFilter(key).from(dateFrom.getTime()).to(dateTo.getTime()));
}
}
}
}
}
......
......@@ -18,6 +18,9 @@ package org.genesys2.server.service.impl;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import org.apache.commons.collections4.CollectionUtils;
......@@ -100,6 +103,7 @@ public class FilterHandler {
this.availableFilters.add(new AutocompleteFilter(FilterConstants.INSTCODE, "/explore/ac/" + FilterConstants.INSTCODE));
this.availableFilters.add(new BasicFilter(FilterConstants.ACCENUMB, DataType.STRING).setAnalyzed(true));
this.availableFilters.add(new BasicFilter(FilterConstants.SEQUENTIAL_NUMBER, DataType.NUMERIC));
this.availableFilters.add(new BasicFilter(FilterConstants.LAST_MODIFIED_DATE, DataType.STRING));
this.availableFilters.add(new BasicFilter(FilterConstants.ALIAS, DataType.STRING).setAnalyzed(true));
this.availableFilters.add(new BasicFilter(FilterConstants.SGSV, DataType.BOOLEAN));
this.availableFilters.add(new BasicFilter(FilterConstants.MLSSTATUS, DataType.BOOLEAN));
......@@ -314,6 +318,17 @@ public class FilterHandler {
throw new JsonParseException("MinValueFilter expects a single numeric value", jp.getCurrentLocation());
af.addFilterValue(new MinValueFilter(number1));
} else if ("dateMin".equals(op)) {
String value = null;
jp.nextToken();
if (jp.getCurrentToken() == JsonToken.VALUE_STRING) {
value = jp.getValueAsString();
}
if (value == null)
throw new JsonParseException("MinValueFilter for date expects a single string value", jp.getCurrentLocation());
af.addFilterValue(new MinValueFilter(value));
} else if ("max".equals(op)) {
Number number1 = null;
jp.nextToken();
......@@ -327,6 +342,16 @@ public class FilterHandler {
throw new JsonParseException("MaxValueFilter expects a single numeric value", jp.getCurrentLocation());
af.addFilterValue(new MaxValueFilter(number1));
} else if ("dateMax".equals(op)) {
String value = null;
jp.nextToken();
if (jp.getCurrentToken() == JsonToken.VALUE_STRING) {
value = jp.getValueAsString();
}
if (value == null)
throw new JsonParseException("MaxValueFilter for date expects a single string value", jp.getCurrentLocation());
af.addFilterValue(new MaxValueFilter(value));
} else if ("range".equals(op)) {
if (jp.nextToken() == JsonToken.START_ARRAY) {
Number number1 = null, number2 = null;
......@@ -349,6 +374,24 @@ public class FilterHandler {
} else {
throw new JsonParseException("ValueRangeFilter expects an array of values", jp.getCurrentLocation());
}
} else if ("dateRange".equals(op)) {
if (jp.nextToken() == JsonToken.START_ARRAY) {
String value1 = null, value2 = null;
jp.nextToken();
if (jp.getCurrentToken() == JsonToken.VALUE_STRING) {
value1 = jp.getValueAsString();
}
jp.nextToken();
if (jp.getCurrentToken() == JsonToken.VALUE_STRING) {
value2 = jp.getValueAsString();
}
if (value1 == null || value2 == null || jp.nextToken() != JsonToken.END_ARRAY)
throw new JsonParseException("ValueRangeFilter for date expects two string values in an array", jp.getCurrentLocation());
af.addFilterValue(new ValueRangeFilter(value1, value2));
} else {
throw new JsonParseException("ValueRangeFilter expects an array of values", jp.getCurrentLocation());
}
}
if (jp.nextToken() != JsonToken.END_OBJECT)
......@@ -660,6 +703,8 @@ public class FilterHandler {
private Number from;
private Number to;
private String dateFrom;
private String dateTo;
public ValueRangeFilter(Number number1, Number number2) {
if (number1 == null || number2 == null)
......@@ -679,17 +724,52 @@ public class FilterHandler {
this.to = number1.doubleValue() < number2.doubleValue() ? number2 : number1;
}
public ValueRangeFilter(final String dateString1, final String dateString2) {
if (dateString1 == null || dateString2 == null)
throw new NullPointerException("ValueRangeFilter requires non-null values for range");
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
DateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = null;
Date date2 = null;
try {
date1 = formatter.parse(dateString1);
date2 = formatter.parse(dateString2);
} catch (ParseException e) {
try {
date1 = formatter2.parse(dateString1);
date2 = formatter2.parse(dateString2);
} catch (ParseException ignored) {}
}
if (date1 != null && date2 != null) {
if (date1.compareTo(date2) < 0) {
this.dateFrom = dateString1;
this.dateTo = dateString2;
} else if (date1.compareTo(date2) > 0){
this.dateFrom = dateString2;
this.dateTo = dateString1;
}
}
}
@Override
public String getType() {
return "range";
if (dateFrom == null) {
return "range";
} else return "dateRange";
}
public Number getFrom() {
return from;
public Object getFrom() {
if (dateFrom == null) {
return from;
} else return dateFrom;
}
public Number getTo() {
return to;
public Object getTo() {
if (dateTo == null) {
return to;
} else return dateTo;
}
@Override
......@@ -699,33 +779,24 @@ public class FilterHandler {
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((from == null) ? 0 : from.hashCode());
result = prime * result + ((to == null) ? 0 : to.hashCode());
int result = from != null ? from.hashCode() : 0;
result = 31 * result + (to != null ? to.hashCode() : 0);
result = 31 * result + (dateFrom != null ? dateFrom.hashCode() : 0);
result = 31 * result + (dateTo != null ? dateTo.hashCode() : 0);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ValueRangeFilter other = (ValueRangeFilter) obj;
if (from == null) {
if (other.from != null)
return false;
} else if (!from.equals(other.from))
return false;
if (to == null) {
if (other.to != null)
return false;
} else if (!to.equals(other.to))
return false;
return true;
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ValueRangeFilter that = (ValueRangeFilter) o;
if (from != null ? !from.equals(that.from) : that.from != null) return false;
if (to != null ? !to.equals(that.to) : that.to != null) return false;
if (dateFrom != null ? !dateFrom.equals(that.dateFrom) : that.dateFrom != null) return false;
return dateTo != null ? dateTo.equals(that.dateTo) : that.dateTo == null;
}
}
......@@ -741,6 +812,7 @@ public class FilterHandler {
}
private Number to;
private String dateTo;
public MaxValueFilter(Number max) {
if (max instanceof Integer)
......@@ -751,13 +823,21 @@ public class FilterHandler {
this.to = max;
}
public MaxValueFilter(final String max) {
this.dateTo = max;
}
@Override
public String getType() {
return "max";
if (dateTo == null) {
return "max";
} else return "dateMax";
}
public Number getTo() {
return to;
public Object getTo() {
if (dateTo == null) {
return to;
} else return dateTo;
}
@Override
......@@ -767,27 +847,20 @@ public class FilterHandler {
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((to == null) ? 0 : to.hashCode());
int result = to != null ? to.hashCode() : 0;
result = 31 * result + (dateTo != null ? dateTo.hashCode() : 0);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MaxValueFilter other = (MaxValueFilter) obj;
if (to == null) {
if (other.to != null)
return false;
} else if (!to.equals(other.to))
return false;
return true;
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MaxValueFilter that = (MaxValueFilter) o;
if (to != null ? !to.equals(that.to) : that.to != null) return false;
return dateTo != null ? dateTo.equals(that.dateTo) : that.dateTo == null;
}
}
......@@ -803,6 +876,7 @@ public class FilterHandler {
}
private Number from;
private String dateFrom;
public MinValueFilter(Number min) {
if (min instanceof Integer)
......@@ -813,13 +887,21 @@ public class FilterHandler {
this.from = min;
}
public MinValueFilter(final String min) {
this.dateFrom = min;
}
@Override
public String getType() {
return "min";
if (dateFrom == null) {
return "min";
} else return "dateMin";
}
public Number getFrom() {
return from;
public Object getFrom() {
if (dateFrom == null) {
return from;
} else return dateFrom;
}
@Override
......@@ -829,29 +911,21 @@ public class FilterHandler {
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((from == null) ? 0 : from.hashCode());
int result = from != null ? from.hashCode() : 0;
result = 31 * result + (dateFrom != null ? dateFrom.hashCode() : 0);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MinValueFilter other = (MinValueFilter) obj;
if (from == null) {
if (other.from != null)
return false;
} else if (!from.equals(other.from))
return false;
return true;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MinValueFilter that = (MinValueFilter) o;
if (from != null ? !from.equals(that.from) : that.from != null) return false;
return dateFrom != null ? dateFrom.equals(that.dateFrom) : that.dateFrom == null;
}
}
@JsonSerialize(using = StartsWithFilter.Serializer.class)
......
......@@ -314,7 +314,7 @@ public class ExplorerController extends BaseController implements InitializingBe
appliedFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
model.addAttribute("appliedFilters", tempFilters);
model.addAttribute("appliedFilters", getAppliedFilters(tempFilters));
model.addAttribute("accessionCount", elasticService.termStatisticsAuto(appliedFilters, FilterConstants.INSTCODE, 10).getTotalCount());
overviewInstitutes(model, appliedFilters);
overviewComposition(model, appliedFilters);
......
......@@ -229,6 +229,20 @@ public class WiewsController extends BaseController {
return "redirect:/wiews/" + wiewsCode;
}
@RequestMapping("/{dateVal}/{wiewsCode}/last-updated")
public String viewDataByLastModifiedDate(ModelMap model, @PathVariable(value = "wiewsCode") String wiewsCode,
@PathVariable(value = "dateVal") String dateVal,
@RequestParam(value = "page", required = false, defaultValue = "1") int page) {
_logger.debug("Viewing last updated data for" + dateVal);
final FaoInstitute faoInstitute = instituteService.getInstitute(wiewsCode);
if (faoInstitute == null) {
throw new ResourceNotFoundException();
}
model.addAttribute("filter", "{\"" + FilterConstants.LAST_MODIFIED_DATE + "\":[\"" + dateVal + "\"], \"" + FilterConstants.INSTCODE + "\":[\"" + faoInstitute.getCode() + "\"]}");
model.addAttribute("page", page);
return "redirect:/explore";
}
@RequestMapping("/{wiewsCode}/data")
public String viewData(ModelMap model, @PathVariable(value = "wiewsCode") String wiewsCode, @RequestParam(value = "page", required = false, defaultValue = "1") int page) {
_logger.debug("Viewing country " + wiewsCode);
......
......@@ -377,6 +377,7 @@ accession.page.data.title=Accession browser
accession.page.data.intro=Explore the accession data with Genesys. To refine your search, add filters such as country of origin, crop, species, or the latitude and longitude of the collecting site.
accession.taxonomy-at-institute=View {0} at {1}
accession.page.updates.title=Last updates of passport data
accession.sort-data.lastUpdated=View updates of passport data for {0}
accession.page.updates.intro=Updates of passport data by date of last update, institute and number of records updated
accession.page.updated.never=Data provided before 2014
......@@ -427,6 +428,7 @@ filter.taxonomy=Scientific name
filter.art15=ITPGRFA Art. 15 accession
filter.acceNumb=Accession number
filter.seqNo=Detected sequential number
filter.lastModifiedDate=Last Modified Date
filter.alias=Accession name
filter.crops=Crop name
filter.cropName=Provided crop name
......
......@@ -409,6 +409,15 @@ var GenesysFilter = {
},
// add filter with two input text fields for enter values of range
filterRange : function(element, jsonData,i18n) {
var key = $(element).attr('i-key');
if(key === 'lastModifiedDate') {
GenesysFilter.filterDateRange(element, jsonData, i18n);
}
else {
GenesysFilter.filterOtherRange(element, jsonData, i18n);
}
},
filterDateRange: function(element, jsonData, i18n) {
var key = $(element).attr('i-key');
var normKey = GenesysFilter.normKey(key);
var inputId1 = '#' + normKey + '_input_1';
......@@ -417,6 +426,9 @@ var GenesysFilter = {
var inputValue1 = $(inputId1).val();
var inputValue2 = $(inputId2).val();
var isDate1 = false;