From: Ray Lee Date: Thu, 24 Oct 2019 01:56:05 +0000 (-0700) Subject: DRYD-753: Tweak scalar date algorithm to better match UI. Fix failing tests. X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=39d595fef17b6ef472f2450c3176b0dbd4f43aa2;p=tmp%2Fjakarta-migration.git DRYD-753: Tweak scalar date algorithm to better match UI. Fix failing tests. --- diff --git a/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/DateUtils.java b/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/DateUtils.java index 77b6a7f76..36707a072 100644 --- a/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/DateUtils.java +++ b/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/DateUtils.java @@ -1277,11 +1277,11 @@ public class DateUtils { addYears(date, -years); } - public static String getEarliestTimestamp(Date date) { + public static String formatEarliestTimestamp(Date date) { return formatEarliest(date, timestampFormatter); } - public static String getEarliestScalarValue(Date date) { + public static String formatEarliestScalarValue(Date date) { return formatEarliest(date, scalarValueFormatter); } @@ -1306,11 +1306,11 @@ public class DateUtils { return scalarDate; } - public static String getLatestTimestamp(Date date) { + public static String formatLatestTimestamp(Date date) { return formatLatest(date, timestampFormatter); } - public static String getLatestScalarValue(Date date) { + public static String formatLatestScalarValue(Date date) { return formatLatest(date, scalarValueFormatter); } diff --git a/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/StructuredDateInternal.java b/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/StructuredDateInternal.java index 0cf47a427..b146e16a5 100644 --- a/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/StructuredDateInternal.java +++ b/services/structureddate/structureddate/src/main/java/org/collectionspace/services/structureddate/StructuredDateInternal.java @@ -48,6 +48,12 @@ public class StructuredDateInternal { getLatestDate().toString() + "\n"; } + string += + "\n" + + "\tearliestScalarValue: " + getEarliestScalarValue() + "\n" + + "\tlatestScalarValue: " + getLatestScalarValue() + "\n" + + "\tscalarValuesComputed: " + areScalarValuesComputed() + "\n"; + return string; } @@ -75,81 +81,127 @@ public class StructuredDateInternal { .append(this.getPeriod(), that.getPeriod()) .append(this.getEarliestSingleDate(), that.getEarliestSingleDate()) .append(this.getLatestDate(), that.getLatestDate()) + // .append(this.getEarliestScalarValue(), that.getEarliestScalarValue()) + // .append(this.getLatestScalarValue(), that.getLatestScalarValue()) .append(this.areScalarValuesComputed(), that.areScalarValuesComputed()) .isEquals(); } - public void computeScalarValues() { + private String computeEarliestScalarValue() { Date earliestDate = getEarliestSingleDate(); - Date latestDate = getLatestDate(); - if (earliestDate == null && latestDate == null) { - setEarliestScalarValue(null); - setLatestScalarValue(null); + Integer year = null; + Integer month = null; + Integer day = null; + Era era = null; - return; + if (earliestDate != null) { + year = earliestDate.getYear(); + month = earliestDate.getMonth(); + day = earliestDate.getDay(); + era = earliestDate.getEra(); } - if (earliestDate == null) { - earliestDate = latestDate.copy(); + if (year == null && month == null && day == null) { + return null; } - else { - earliestDate = earliestDate.copy(); + + if (year == null) { + // The date must at least specify a year. + throw new InvalidDateException("year must not be null"); } - if (latestDate == null) { - latestDate = earliestDate.copy(); + if (day != null && month == null) { + // If a day is specified, the month must be specified. + throw new InvalidDateException("month may not be null when day is not null"); } - else { - latestDate = latestDate.copy(); + + if (era == null) { + era = Date.DEFAULT_ERA; } - if (earliestDate.getYear() == null || latestDate.getYear() == null) { - // The dates must at least specify a year. - throw new InvalidDateException("year must not be null"); + if (month == null) { + month = 1; + day = 1; } - if (earliestDate.getDay() != null && earliestDate.getMonth() == null) { - // If a day is specified, the month must be specified. - throw new InvalidDateException("month may not be null when day is not null"); + if (day == null) { + day = 1; } - if (latestDate.getDay() != null && latestDate.getMonth() == null) { - // If a day is specified, the month must be specified. - throw new InvalidDateException("month may not be null when day is not null"); + Date date = new Date(year, month, day, era); + + return DateUtils.formatEarliestScalarValue(date); + } + + private String computeLatestScalarValue() { + Date latestDate = getLatestDate(); + + Integer year = null; + Integer month = null; + Integer day = null; + Era era = null; + + if (latestDate != null) { + year = latestDate.getYear(); + month = latestDate.getMonth(); + day = latestDate.getDay(); + era = latestDate.getEra(); + } + + if (year == null && month == null && day == null) { + // No latest date parts are specified. Inherit year, month, and day from earliest/single. + + Date earliestDate = getEarliestSingleDate(); + + // TODO: What if no date parts are specified, but the era/certainty/qualifier is different than + // the earliest/single? + + if (earliestDate != null) { + year = earliestDate.getYear(); + month = earliestDate.getMonth(); + day = earliestDate.getDay(); + } } - if (earliestDate.getEra() == null) { - earliestDate.setEra(Date.DEFAULT_ERA); + if (year == null && month == null && day == null) { + return null; } - if (latestDate.getEra() == null) { - latestDate.setEra(Date.DEFAULT_ERA); + if (year == null) { + // The date must at least specify a year. + throw new InvalidDateException("year must not be null"); } - if (earliestDate.getMonth() == null) { - earliestDate.setMonth(1); - earliestDate.setDay(1); + if (day != null && month == null) { + // If a day is specified, the month must be specified. + throw new InvalidDateException("month may not be null when day is not null"); } - if (latestDate.getMonth() == null) { - latestDate.setMonth(12); - latestDate.setDay(31); + if (era == null) { + era = Date.DEFAULT_ERA; } - if (earliestDate.getDay() == null) { - earliestDate.setDay(1); + if (month == null) { + month = 12; + month = 31; } - if (latestDate.getDay() == null) { - latestDate.setDay(DateUtils.getDaysInMonth(latestDate.getMonth(), latestDate.getYear(), latestDate.getEra())); + if (day == null) { + day = DateUtils.getDaysInMonth(month, year, era); } - // Add one day to the latest day, since that's what the UI does. - DateUtils.addDays(latestDate, 1); + Date date = new Date(year, month, day, era); - setEarliestScalarValue(DateUtils.getEarliestScalarValue(earliestDate)); - setLatestScalarValue(DateUtils.getLatestScalarValue(latestDate)); + // Add one day to the latest day, since that's what the UI has historically (*sigh*) done. + DateUtils.addDays(date, 1); + + return DateUtils.formatLatestScalarValue(date); + } + + public void computeScalarValues() { + setEarliestScalarValue(computeEarliestScalarValue()); + setLatestScalarValue(computeLatestScalarValue()); setScalarValuesComputed(true); } diff --git a/services/structureddate/structureddate/src/test/java/org/collectionspace/services/structureddate/StructuredDateEvaluatorTest.java b/services/structureddate/structureddate/src/test/java/org/collectionspace/services/structureddate/StructuredDateEvaluatorTest.java index 9a56da5e5..1469d9124 100644 --- a/services/structureddate/structureddate/src/test/java/org/collectionspace/services/structureddate/StructuredDateEvaluatorTest.java +++ b/services/structureddate/structureddate/src/test/java/org/collectionspace/services/structureddate/StructuredDateEvaluatorTest.java @@ -1,13 +1,11 @@ package org.collectionspace.services.structureddate; -import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Stack; import org.apache.commons.beanutils.PropertyUtils; import org.slf4j.Logger; @@ -40,7 +38,7 @@ public class StructuredDateEvaluatorTest { StructuredDateInternal expectedStructuredDate = createStructuredDateFromYamlSpec(displayDate, expectedStructuredDateFields); StructuredDateInternal actualStructuredDate = null; - + try { actualStructuredDate = StructuredDateInternal.parse(displayDate); } @@ -55,22 +53,31 @@ public class StructuredDateEvaluatorTest { private StructuredDateInternal createStructuredDateFromYamlSpec(String displayDate, Map structuredDateFields) { StructuredDateInternal structuredDate = null; - if (structuredDateFields != null && structuredDateFields.containsKey("latestDate")) { - Object latestDate = structuredDateFields.get("latestDate"); - if (latestDate instanceof String) { - Date currentDate = DateUtils.getCurrentDate(); - ArrayList latestDateItems = new ArrayList<>(); - if (latestDate.equals("current date")) { + if (structuredDateFields != null) { + if (structuredDateFields.containsKey("latestDate")) { + Object latestDate = structuredDateFields.get("latestDate"); + + if (latestDate instanceof String && latestDate.equals("current date")) { + Date currentDate = DateUtils.getCurrentDate(); + ArrayList latestDateItems = new ArrayList<>(); + latestDateItems.add(currentDate.getYear()); latestDateItems.add(currentDate.getMonth()); latestDateItems.add(currentDate.getDay()); - latestDateItems.add(currentDate.getEra() == Era.BCE ? "BCE" : "CE"); + latestDateItems.add(currentDate.getEra().toDisplayString()); + structuredDateFields.put("latestDate", latestDateItems); } } - } - if (structuredDateFields != null) { + if (!structuredDateFields.containsKey("displayDate")) { + structuredDateFields.put("displayDate", displayDate); + } + + if (!structuredDateFields.containsKey("scalarValuesComputed")) { + structuredDateFields.put("scalarValuesComputed", true); + } + structuredDate = new StructuredDateInternal(); for (String propertyName : structuredDateFields.keySet()) { @@ -95,10 +102,6 @@ public class StructuredDateEvaluatorTest { logger.error("could not access property " + propertyName); } } - - if (structuredDate.getDisplayDate() == null) { - structuredDate.setDisplayDate(displayDate); - } } return structuredDate; @@ -128,7 +131,7 @@ public class StructuredDateEvaluatorTest { } catch(IllegalAccessException e) { logger.error("could not access property " + propertyName); - } + } } return date; diff --git a/services/structureddate/structureddate/src/test/resources/test-dates.yaml b/services/structureddate/structureddate/src/test/resources/test-dates.yaml index 824a1b2f0..6e34784d6 100644 --- a/services/structureddate/structureddate/src/test/resources/test-dates.yaml +++ b/services/structureddate/structureddate/src/test/resources/test-dates.yaml @@ -925,8 +925,8 @@ latestDate: [2013, 4, 5, CE] '5/3/1962-4/5/2013 BC': # hyphenatedRange, date - earliestSingleDate: [2013, 4, 5, BCE] - latestDate: [1962, 5, 3, BCE] + earliestSingleDate: [2013, 4, 5, BCE] + latestDate: [1962, 5, 3, BCE] '5/3/1962 BC-4/5/2013': # hyphenatedRange, date earliestSingleDate: [1962, 5, 3, BCE] @@ -1106,54 +1106,54 @@ "3/4/2000?": # oneDisplayDate - with question mark earliestSingleDate: [2000, 3, 4, CE] - "13 april 1995": # Rule 6 oneDisplayDate: - SingleInterval with Day (cardinal) Month Year Format - earliestSingleDate: [1995, 4, 13, CE] + "13 april 1995": # Rule 6 oneDisplayDate: - SingleInterval with Day (cardinal) Month Year Format + earliestSingleDate: [1995, 4, 13, CE] "13 apr 1995": # oneDisplayDate: - SingleInterval with Day (cardinal) Month Year Format - earliestSingleDate: [1995, 4, 13, CE] + earliestSingleDate: [1995, 4, 13, CE] "13th APRIL 1995": # oneDisplayDate: - SingleInterval with Day (ordinal) Month (all caps) Year Format - earliestSingleDate: [1995, 4, 13, CE] + earliestSingleDate: [1995, 4, 13, CE] - "bc 1995 april 13": # oneDisplayDate: - SingleInterval - With Era Year Month Day format - earliestSingleDate: [1995, 4, 13, BCE] + "bc 1995 april 13": # oneDisplayDate: - SingleInterval - With Era Year Month Day format + earliestSingleDate: [1995, 4, 13, BCE] - "bc 1995, april 13": # oneDisplayDate: - SingleInterval - With Era Year Month Day format - earliestSingleDate: [1995, 4, 13, BCE] + "bc 1995, april 13": # oneDisplayDate: - SingleInterval - With Era Year Month Day format + earliestSingleDate: [1995, 4, 13, BCE] "13th april 1995": # oneDisplayDate: - SingleInterval with Day (ordinal) Month (all caps) Year Format - earliestSingleDate: [1995, 4, 13, CE] + earliestSingleDate: [1995, 4, 13, CE] "1995, april 13": # oneDisplayDate: - SingleInterval - Year COMMA month day format (no era) - earliestSingleDate: [1995, 4, 13, CE] + earliestSingleDate: [1995, 4, 13, CE] - "1995, april 13 AD": # oneDisplayDate: - SingleInterval - Year COMMA month day era format - earliestSingleDate: [1995, 4, 13, CE] + "1995, april 13 AD": # oneDisplayDate: - SingleInterval - Year COMMA month day era format + earliestSingleDate: [1995, 4, 13, CE] "1995 april 13": # oneDisplayDate - singleInterval - dayOrYearFirstDate - Year month day, no era - earliestSingleDate: [1995, 4, 13, CE] + earliestSingleDate: [1995, 4, 13, CE] "13 april 1995": # oneDisplayDate - singleInterval - dayOrYearFirstDate - Day month year, no era - earliestSingleDate: [1995, 4, 13, CE] + earliestSingleDate: [1995, 4, 13, CE] "13 april, 1995": # oneDisplayDate - singleInterval - dayFirstDate - Day Month Year - earliestSingleDate: [1995, 4, 13, CE] + earliestSingleDate: [1995, 4, 13, CE] "13 april, 1995 AD": # oneDisplayDate - singleInterval - dayFirstDate - Day Month Year with comma and era - earliestSingleDate: [1995, 4, 13, CE] + earliestSingleDate: [1995, 4, 13, CE] "13 april 1995 AD": # oneDisplayDate - singleInterval - dayFirstDate - Day Month Year with era, no comma - earliestSingleDate: [1995, 4, 13, CE] + earliestSingleDate: [1995, 4, 13, CE] "13th april, 1995": # oneDisplayDate - singleInterval - dayFirstDate - Day (ordinal) Month Year - earliestSingleDate: [1995, 4, 13, CE] + earliestSingleDate: [1995, 4, 13, CE] "13th april, 1995 - 5th may 1999": # oneDisplayDate - hyphenatedRange - dayFirstDate - Day (ordinal) Month Year - earliestSingleDate: [1995, 4, 13, CE] + earliestSingleDate: [1995, 4, 13, CE] latestDate: [1999, 5, 5, CE] "13 april 15": # oneDisplayDate - ambigous day and year - should be Year month day - earliestSingleDate: [13, 4, 15, CE] + earliestSingleDate: [ 13, 4, 15, CE] "before 13 april 1995": # beforeAfterDate - Empty earliestSingleDate - Day Month Year Format earliestSingleDate: [] @@ -1171,111 +1171,111 @@ "after april 13 1995": # beforeAfterDate - Empty latestDate calculated as current date - Month Day Year Format earliestSingleDate: [1995, 4, 13, CE] latestDate: "current date" - + "10/2005-12/2006": # Month/Year - Month/Year date - earliestSingleDate: [2005, 10, 1, CE] - latestDate: [2006, 12, 31, CE] + earliestSingleDate: [2005, 10, 1, CE] + latestDate: [2006, 12, 31, CE] "04/1995-04/2018": # Month/Year - Month/Year date - earliestSingleDate: [1995, 4, 1, CE] + earliestSingleDate: [1995, 4, 1, CE] latestDate: [2018, 4, 30, CE] "unknown": # Unknown date: Should result in empty fields earliestSingleDate: [] "13 april 15": # oneDisplayDate - ambiguous day and year, intepreted as year month day - earliestSingleDate: [13, 4, 15, CE] + earliestSingleDate: [ 13, 4, 15, CE] "04/5-6/2018": # Month/Day - Day/Year date - earliestSingleDate: [2018, 4, 5, CE] - latestDate: [2018, 4, 6, CE] - + earliestSingleDate: [2018, 4, 5, CE] + latestDate: [2018, 4, 6, CE] + "04/03-07/09": # Ambigious NumDayInMonthRange - should be interpreted as Month/Day - Day/Year date - earliestSingleDate: [9, 4, 3, CE] - latestDate: [9, 4, 7, CE] + earliestSingleDate: [ 9, 4, 3, CE] + latestDate: [ 9, 4, 7, CE] '04/1996-07/09': # Semi-ambigious NumDayInMonthRange - should be interpreted as Month/Year - Month/Year date - earliestSingleDate: [9, 7, 31, CE] + earliestSingleDate: [ 9, 7, 31, CE] latestDate: [1996, 4, 1, CE] "1200±50 BP": # Uncalibrated date with ± symbol - earliestSingleDate: [700, 1, 1, CE] - latestDate: [800, 12, 31, CE ] + earliestSingleDate: [ 700, 1, 1, CE] + latestDate: [ 800, 12, 31, CE ] "3100 +/- 150 BP": # Uncalibrated date with +/- instead of ± symbol - earliestSingleDate: [1300, 1, 1, BCE] + earliestSingleDate: [1300, 1, 1, BCE] latestDate: [1000, 12, 31, BCE] "3100+/-150 BP": # Uncalibrated date with +/- instead of ± symbol, no spaces - earliestSingleDate: [1300, 1, 1, BCE] + earliestSingleDate: [1300, 1, 1, BCE] latestDate: [1000, 12, 31, BCE] "3100+/-150 years BP": # Uncalibrated date with 'years' in it - earliestSingleDate: [1300, 1, 1, BCE] + earliestSingleDate: [1300, 1, 1, BCE] latestDate: [1000, 12, 31, BCE] "3,100+/-150 years BP": # Uncalibrated date with 'years' in it as well as with a comma - earliestSingleDate: [1300, 1, 1, BCE] + earliestSingleDate: [1300, 1, 1, BCE] latestDate: [1000, 12, 31, BCE] "2000±100 BP": # Uncalibrated date with BCE and AD mix - earliestSingleDate: [150, 1, 1, BCE] - latestDate: [50, 12, 31, CE] + earliestSingleDate: [ 150, 1, 1, BCE] + latestDate: [ 50, 12, 31, CE] "5580-5460 BC": # Calibrated date with commas - earliestSingleDate: [5580, 1, 1, BCE] - latestDate: [5460, 12, 31, BCE] + earliestSingleDate: [5580, 1, 1, BCE] + latestDate: [5460, 12, 31, BCE] "5,580 - 5,460 BC": # Calibrated date with commas and spaces - earliestSingleDate: [5580, 1, 1, BCE] - latestDate: [5460, 12, 31, BCE] + earliestSingleDate: [5580, 1, 1, BCE] + latestDate: [5460, 12, 31, BCE] "5460-5580 BC": # Calibrated date with dates reversed - earliestSingleDate: [5580, 1, 1, BCE] - latestDate: [5460, 12, 31, BCE] + earliestSingleDate: [5580, 1, 1, BCE] + latestDate: [5460, 12, 31, BCE] "c. 69 BC": # Circa date, ± 10 years - earliestSingleDate: [74, 1, 1, BCE] - latestDate: [64, 12, 31, BCE] + earliestSingleDate: [ 74, 1, 1, BCE] + latestDate: [ 64, 12, 31, BCE] "ca. 60 BC": # Circa date, ± 5 years - earliestSingleDate: [70, 1, 1, BCE] - latestDate: [50, 12, 31, BCE] + earliestSingleDate: [ 70, 1, 1, BCE] + latestDate: [ 50, 12, 31, BCE] "circa 200 BC": # Circa date, ± 50 years - earliestSingleDate: [250, 1, 1, BCE] - latestDate: [150, 12, 31, BCE] + earliestSingleDate: [ 250, 1, 1, BCE] + latestDate: [ 150, 12, 31, BCE] "circa 1000 BC": # Circa date, ± 500 years - earliestSingleDate: [1500, 1, 1, BCE] - latestDate: [500, 12, 31, BCE] + earliestSingleDate: [1500, 1, 1, BCE] + latestDate: [ 500, 12, 31, BCE] - '5/13/54,962 BC-4/5/2,019': # hyphenatedRange, date with comma'd numbers - earliestSingleDate: [54962, 5, 13, BCE] + '5/13/5,962 BC-4/5/2,019': # hyphenatedRange, date with comma'd numbers + earliestSingleDate: [5962, 5, 13, BCE] latestDate: [2019, 4, 5, CE] - '01-I-2017 BCE': # Day-Month-Year with roman numeral as month + '01-I-2017 BCE': # Day-Month-Year with roman numeral as month earliestSingleDate: [2017, 1, 1, BCE] - '19-XI-2018': # Day-Month-Year with roman numeral as month - earliestSingleDate: [2018, 11, 19, CE] + '19-XI-2018': # Day-Month-Year with roman numeral as month + earliestSingleDate: [2018, 11, 19, CE] - '27-III-1843 BCE': # Day-Month-Year with roman numeral as month - earliestSingleDate: [1843, 3, 27, BCE] + '27-III-1843 BCE': # Day-Month-Year with roman numeral as month + earliestSingleDate: [1843, 3, 27, BCE] - '29-IV-2018': # Day-Month-Year with roman numeral as month - earliestSingleDate: [2018, 4, 29, CE] + '29-IV-2018': # Day-Month-Year with roman numeral as month + earliestSingleDate: [2018, 4, 29, CE] '01-IV-2017 BCE': # Day-Month-Year with roman numeral as month, with Era - earliestSingleDate: [2017, 4, 1, BCE] - + earliestSingleDate: [2017, 4, 1, BCE] + '12 june 1942 BCE - 13 june 1943': # hyphenatedRange range with era only in first interval, mixed eras - earliestSingleDate: [1942, 6, 12, BCE] - latestDate: [1943, 6, 13, CE] + earliestSingleDate: [1942, 6, 12, BCE] + latestDate: [1943, 6, 13, CE] '13 april 1995 CE - 18 april 2019': # hyphenatedRange range with era only in first interval - earliestSingleDate: [1995, 4, 13, CE] - latestDate: [2019, 4, 18, CE] + earliestSingleDate: [1995, 4, 13, CE] + latestDate: [2019, 4, 18, CE] # ------------------------------------------------------------------------------------------------------- # Invalid dates