From cdd12a8a463b5fa30ef094a7bdd47cc85e400efa Mon Sep 17 00:00:00 2001 From: felmer <felmer> Date: Wed, 16 May 2012 11:09:28 +0000 Subject: [PATCH] SP-39 improve searching with dates and timestamps. SVN: 25275 --- .../search/DetailedSearchCriterionWidget.java | 30 ++----- .../search/detailed/DetailedQueryBuilder.java | 82 ++++++++++++------- .../basic/dto/DetailedSearchCriterion.java | 16 ++-- 3 files changed, 66 insertions(+), 62 deletions(-) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchCriterionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchCriterionWidget.java index 8f553682fbe..93e1df39657 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchCriterionWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchCriterionWidget.java @@ -16,7 +16,6 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.search; -import java.util.Date; import java.util.List; import com.extjs.gxt.ui.client.Style.HorizontalAlignment; @@ -36,7 +35,6 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAs import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.DetailedSearchFieldComboModel; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.DateRenderer; import ch.systemsx.cisd.openbis.generic.shared.basic.AttributeSearchFieldKindProvider; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CompareType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriterion; @@ -212,33 +210,23 @@ public class DetailedSearchCriterionWidget extends HorizontalPanel { String aCode = selectedFieldName.getAttributeCode(); - @SuppressWarnings("unused") - Date date; - try - { - date = DateRenderer.SHORT_DATE_TIME_FORMAT.parse(selectedValue); - } catch (IllegalArgumentException ex) - { - return new DetailedSearchCriterion(selectedFieldName, selectedValue); - } - CompareType compareType; - if ("REGISTRATION_DATE_FROM".equals(aCode)) + if ("REGISTRATION_DATE_UNTIL".equals(aCode)) { compareType = CompareType.LESS_THAN_OR_EQUAL; } else if ("REGISTRATION_DATE".equals(aCode)) { compareType = CompareType.EQUALS; - } else if ("REGISTRATION_DATE_UNTIL".equals(aCode)) + } else if ("REGISTRATION_DATE_FROM".equals(aCode)) { compareType = CompareType.MORE_THAN_OR_EQUAL; - } else if ("MODIFICATION_DATE_FROM".equals(aCode)) + } else if ("MODIFICATION_DATE_UNTIL".equals(aCode)) { compareType = CompareType.LESS_THAN_OR_EQUAL; } else if ("MODIFICATION_DATE".equals(aCode)) { compareType = CompareType.EQUALS; - } else if ("MODIFICATION_DATE_UNTIL".equals(aCode)) + } else if ("MODIFICATION_DATE_FROM".equals(aCode)) { compareType = CompareType.MORE_THAN_OR_EQUAL; } else @@ -246,7 +234,7 @@ public class DetailedSearchCriterionWidget extends HorizontalPanel return new DetailedSearchCriterion(selectedFieldName, selectedValue); } - return new DetailedSearchCriterion(selectedFieldName, compareType, selectedValue, "+1"); + return new DetailedSearchCriterion(selectedFieldName, compareType, selectedValue); } return null; @@ -262,13 +250,7 @@ public class DetailedSearchCriterionWidget extends HorizontalPanel return null; } - if (criterion.getValue() == null && criterion.getDate() != null) - { - return name + " = " + criterion.getDate(); - } else - { - return name + " = " + criterion.getValue(); - } + return name + " = " + criterion.getValue(); } public List<PropertyType> getAvailablePropertyTypes() diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/detailed/DetailedQueryBuilder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/detailed/DetailedQueryBuilder.java index 3eacebee33c..536405139fc 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/detailed/DetailedQueryBuilder.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/detailed/DetailedQueryBuilder.java @@ -57,6 +57,9 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.hibernate.SearchFieldConstant */ public class DetailedQueryBuilder { + private static final String[] DATE_FORMATS = + { "y-M-d HH:mm:ss", "y-M-d HH:mm", "y-M-d" }; + private final static Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, DetailedQueryBuilder.class); @@ -106,35 +109,8 @@ public class DetailedQueryBuilder resultQuery.add(luceneQuery, occureCondition); } else { - String tzs = criterion.getTimeZone(); - if (tzs.startsWith("+")) - { - tzs = tzs.substring(1); - } else if (tzs.equals("Z")) - { - tzs = "0"; - } - - int offset; - try - { - offset = (-Integer.parseInt(tzs) * 3600000); - } catch (NumberFormatException e) - { - offset = 0; - } - - SimpleDateFormat sdf = new SimpleDateFormat("y-M-d"); - sdf.setTimeZone(TimeZone.getTimeZone("GMT")); - - Date lower; - try - { - lower = sdf.parse(criterion.getDate()); - } catch (ParseException ex) - { - throw new IllegalArgumentException(criterion.getDate(), ex); - } + Date lower = parseDate(criterion.getValue()); + int offset = getTimeZoneOffset(criterion, lower); lower.setTime(lower.getTime() + offset); Date upper = new Date(lower.getTime() + 24 * 3600 * 1000); @@ -152,7 +128,7 @@ public class DetailedQueryBuilder } String fieldName = fieldNames.get(0); - DateBridge bridge = new DateBridge(Resolution.HOUR); + DateBridge bridge = new DateBridge(Resolution.SECOND); TermRangeQuery q = new TermRangeQuery(fieldName, bridge.objectToString(lower), bridge.objectToString(upper), true, true); @@ -169,6 +145,52 @@ public class DetailedQueryBuilder return resultQuery; } + private int getTimeZoneOffset(DetailedSearchCriterion criterion, Date lower) + { + String tzs = criterion.getTimeZone(); + if (tzs.equals(DetailedSearchCriterion.SERVER_TIMEZONE)) + { + return -TimeZone.getDefault().getOffset(lower.getTime()); + } + + if (tzs.startsWith("+")) + { + tzs = tzs.substring(1); + } else if (tzs.equals("Z")) + { + tzs = "0"; + } + + int offset; + try + { + offset = (int) (-Double.parseDouble(tzs) * 3600000); + } catch (NumberFormatException e) + { + offset = 0; + } + return offset; + } + + private Date parseDate(String dateAsString) + { + for (String format : DATE_FORMATS) + { + SimpleDateFormat sdf = new SimpleDateFormat(format); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + + try + { + return sdf.parse(dateAsString); + } catch (ParseException ex) + { + // ignore, try next format + } + } + throw new UserFailureException("Couldn't parse date '" + dateAsString + + "'. It has to match one of the following formats: " + Arrays.asList(DATE_FORMATS)); + } + private List<String> extractAssociationPatterns(DetailedSearchAssociationCriteria association) { List<String> result = new ArrayList<String>(); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchCriterion.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchCriterion.java index 71397535c94..202359fde8a 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchCriterion.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchCriterion.java @@ -26,14 +26,14 @@ public class DetailedSearchCriterion implements Serializable { private static final long serialVersionUID = ServiceVersionHolder.VERSION; + public static final String SERVER_TIMEZONE = "server"; + private DetailedSearchField field; private CompareType type; private String value; - private String date; - private String timezone; public DetailedSearchCriterion() @@ -48,11 +48,16 @@ public class DetailedSearchCriterion implements Serializable this.type = CompareType.EQUALS; } + public DetailedSearchCriterion(DetailedSearchField field, CompareType type, String date) + { + this(field, type, date, SERVER_TIMEZONE); + } + public DetailedSearchCriterion(DetailedSearchField field, CompareType type, String date, String timezone) { this.field = field; - this.date = date; + this.value = date; this.type = type; this.timezone = timezone; } @@ -82,11 +87,6 @@ public class DetailedSearchCriterion implements Serializable return this.type; } - public String getDate() - { - return this.date; - } - public String getTimeZone() { return this.timezone; -- GitLab