1 package org.collectionspace.services.structureddate;
3 import java.lang.reflect.Array;
4 import java.lang.reflect.InvocationTargetException;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.Iterator;
10 import java.util.Stack;
12 import org.apache.commons.beanutils.PropertyUtils;
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
15 import org.testng.Assert;
16 import org.testng.annotations.BeforeClass;
17 import org.testng.annotations.Test;
18 import org.yaml.snakeyaml.Yaml;
20 public class StructuredDateEvaluatorTest {
21 public static final String TEST_CASE_FILE = "/test-dates.yaml";
22 public static final List<String> YAML_DATE_SPEC = Arrays.asList("year", "month", "day", "era", "certainty", "qualifierType", "qualifierValue", "qualifierUnit");
24 final Logger logger = LoggerFactory.getLogger(StructuredDateEvaluatorTest.class);
33 Yaml yaml = new Yaml();
34 Map<String, Object> testCases = (Map<String, Object>) yaml.load(getClass().getResourceAsStream(TEST_CASE_FILE));
36 for (String displayDate : testCases.keySet()) {
37 logger.debug("Testing input: " + displayDate);
39 Map<String, Object> expectedStructuredDateFields = (Map<String, Object>) testCases.get(displayDate);
41 StructuredDateInternal expectedStructuredDate = createStructuredDateFromYamlSpec(displayDate, expectedStructuredDateFields);
42 StructuredDateInternal actualStructuredDate = null;
45 actualStructuredDate = StructuredDateInternal.parse(displayDate);
47 catch(StructuredDateFormatException e) {
48 logger.debug(e.getMessage());
51 Assert.assertEquals(actualStructuredDate, expectedStructuredDate);
55 private StructuredDateInternal createStructuredDateFromYamlSpec(String displayDate, Map<String, Object> structuredDateFields) {
56 StructuredDateInternal structuredDate = null;
58 if (structuredDateFields != null && structuredDateFields.containsKey("latestDate")) {
59 Object latestDate = structuredDateFields.get("latestDate");
60 if (latestDate instanceof String) {
61 Date currentDate = DateUtils.getCurrentDate();
62 ArrayList latestDateItems = new ArrayList<>();
63 if (latestDate.equals("current date")) {
64 latestDateItems.add(currentDate.getYear());
65 latestDateItems.add(currentDate.getMonth());
66 latestDateItems.add(currentDate.getDay());
67 latestDateItems.add(currentDate.getEra() == Era.BCE ? "BCE" : "CE");
68 structuredDateFields.put("latestDate", latestDateItems);
73 if (structuredDateFields != null) {
74 structuredDate = new StructuredDateInternal();
76 for (String propertyName : structuredDateFields.keySet()) {
77 Object value = structuredDateFields.get(propertyName);
80 Class propertyType = PropertyUtils.getPropertyType(structuredDate, propertyName);
82 if (propertyType.equals(Date.class)) {
83 value = createDateFromYamlSpec((List<Object>) value);
86 PropertyUtils.setProperty(structuredDate, propertyName, value);
88 catch(NoSuchMethodException e) {
89 logger.warn(propertyName + " is not a property");
91 catch(InvocationTargetException e) {
92 logger.error(propertyName + " accessor threw an exception");
94 catch(IllegalAccessException e) {
95 logger.error("could not access property " + propertyName);
99 if (structuredDate.getDisplayDate() == null) {
100 structuredDate.setDisplayDate(displayDate);
104 return structuredDate;
107 private Date createDateFromYamlSpec(List<Object> dateFields) {
108 Date date = new Date();
109 Iterator<Object> fieldIterator = dateFields.iterator();
111 for (String propertyName : YAML_DATE_SPEC) {
112 Object value = fieldIterator.hasNext() ? fieldIterator.next() : null;
115 Class propertyType = PropertyUtils.getPropertyType(date, propertyName);
117 if (value != null && Enum.class.isAssignableFrom(propertyType)) {
118 value = Enum.valueOf(propertyType, (String) value);
121 PropertyUtils.setProperty(date, propertyName, value);
123 catch(NoSuchMethodException e) {
124 logger.warn(propertyName + " is not a property");
126 catch(InvocationTargetException e) {
127 logger.error(propertyName + " accessor threw an exception");
129 catch(IllegalAccessException e) {
130 logger.error("could not access property " + propertyName);