From 81c86ac3e64c910ea1936aaea6143b01eda017d0 Mon Sep 17 00:00:00 2001 From: Aron Roberts Date: Tue, 17 Aug 2010 02:31:22 +0000 Subject: [PATCH] CSPACE-2418: Groundwork for supporting free-text entry of dates in a variety of formats. Added utility routines to retrieve per-tenant lists of properties, and demonstrated retrieval of date formats from those properties, and of validating incoming dates against permitted date formats. Need to add ISO 8601-based patterns corresponding to those permitted by Nuxeo, determine how best to identify date fields whose values might be validated, and identify where during incoming payload handling to convert from non-ISO 8601 formats. --- .../main/config/services/tenant-bindings.xml | 169 ++++++++----- .../common/config/ServiceConfigUtils.java | 8 +- .../common/config/TenantBindingUtils.java | 106 ++++---- .../common/datetime/DateTimeFormatUtils.java | 226 ++++++++++++++++++ .../GregorianCalendarDateTimeUtils.java | 96 +------- .../nuxeo/MovementDocumentModelHandler.java | 23 +- .../nuxeo/MovementValidatorHandler.java | 63 ++++- 7 files changed, 479 insertions(+), 212 deletions(-) create mode 100644 services/common/src/main/java/org/collectionspace/services/common/datetime/DateTimeFormatUtils.java diff --git a/services/common/src/main/config/services/tenant-bindings.xml b/services/common/src/main/config/services/tenant-bindings.xml index dfe0b1eb3..f42e066e7 100644 --- a/services/common/src/main/config/services/tenant-bindings.xml +++ b/services/common/src/main/config/services/tenant-bindings.xml @@ -1,8 +1,9 @@ + + + + + datePatternMM/dd/YYYY + datePatterndd.MM.YYYY + + + + + - - + + + + + - + @@ -114,7 +128,7 @@ + objectNamePropertyobjectName --> objectNumberPropertyentryNumber + @@ -168,7 +183,7 @@ + objectNamePropertyobjectName --> objectNumberPropertyloanInNumber + @@ -248,6 +264,7 @@ + @@ -293,6 +310,7 @@ + @@ -333,10 +351,10 @@ + - default-domain @@ -371,10 +389,10 @@ - @@ -418,6 +436,7 @@ + @@ -455,9 +474,10 @@ - @@ -495,7 +515,6 @@ authRefcontactNames|contactName authRefsubBodies|subBody - + @@ -546,9 +566,10 @@ - @@ -589,6 +610,7 @@ + @@ -626,9 +648,10 @@ - @@ -665,6 +688,7 @@ + @@ -682,7 +706,7 @@ + objectNamePropertyobjectName --> objectNumberPropertyacquisitionReferenceNumber + ' @@ -753,10 +778,10 @@ + - org.collectionspace.services.account.storage.AccountDocumentHandler @@ -788,10 +813,10 @@ + - default-domain @@ -823,6 +848,7 @@ + @@ -863,6 +889,7 @@ + @@ -896,10 +923,10 @@ + - org.collectionspace.services.authorization.storage.RoleDocumentHandler @@ -931,10 +958,10 @@ + - org.collectionspace.services.authorization.storage.PermissionDocumentHandler @@ -966,6 +993,7 @@ + @@ -1005,6 +1033,7 @@ + @@ -1042,6 +1071,7 @@ + @@ -1085,25 +1115,40 @@ - + + + + + + + + datePatternMM/dd/YYYY + datePatterndd.MM.YYYY + + + + + - - + + + + + - + @@ -1189,7 +1234,7 @@ + objectNamePropertyobjectName --> objectNumberPropertyentryNumber + @@ -1243,7 +1289,7 @@ + objectNamePropertyobjectName --> objectNumberPropertyloanInNumber + @@ -1323,6 +1370,7 @@ + @@ -1368,10 +1416,10 @@ + - pahma-domain @@ -1403,10 +1451,10 @@ - @@ -1447,6 +1495,7 @@ + @@ -1484,9 +1533,10 @@ - @@ -1535,6 +1585,7 @@ + @@ -1578,9 +1629,10 @@ - @@ -1621,6 +1673,7 @@ + @@ -1658,9 +1711,10 @@ - @@ -1697,6 +1751,7 @@ + @@ -1714,7 +1769,7 @@ + objectNamePropertyobjectName --> objectNumberPropertyacquisitionReferenceNumber + ' @@ -1785,10 +1841,10 @@ + - org.collectionspace.services.account.storage.AccountDocumentHandler @@ -1820,10 +1876,10 @@ + - pahma-domain @@ -1855,6 +1911,7 @@ + @@ -1895,6 +1952,7 @@ + @@ -1928,10 +1986,10 @@ + - org.collectionspace.services.authorization.storage.RoleDocumentHandler @@ -1963,10 +2021,10 @@ + - org.collectionspace.services.authorization.storage.PermissionDocumentHandler @@ -1998,6 +2056,7 @@ + @@ -2037,6 +2096,7 @@ + @@ -2074,6 +2134,7 @@ + diff --git a/services/common/src/main/java/org/collectionspace/services/common/config/ServiceConfigUtils.java b/services/common/src/main/java/org/collectionspace/services/common/config/ServiceConfigUtils.java index dc52cabce..51426de5e 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/config/ServiceConfigUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/config/ServiceConfigUtils.java @@ -40,9 +40,11 @@ public class ServiceConfigUtils { /** - * @param serviceConfig - * @param propName the property to fetch (allows multiple property values) - * @return + * Gets the values of a configured property for a service. + * + * @param serviceConfiga tenant binding + * @param propName the property to fetch (can return multiple values for this property). + * @return a list of values for the supplied property. */ public static List getPropertyValues(ServiceConfig serviceConfig, String propName) { diff --git a/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingUtils.java b/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingUtils.java index de64c3e37..05ee63bde 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingUtils.java @@ -10,24 +10,52 @@ import org.collectionspace.services.common.types.PropertyItemType; import org.collectionspace.services.common.types.PropertyType; public class TenantBindingUtils { - - public static final boolean SET_PROP_IF_MISSING = true; - public static final boolean SET_PROP_ALWAYS = false; - + + public static final boolean SET_PROP_IF_MISSING = true; + public static final boolean SET_PROP_ALWAYS = false; + /** * @param tenantBinding * @param propName the property to fetch * @return the String value of the named property */ public static String getPropertyValue(TenantBindingType tenantBinding, - String propName) { - if(propName==null) { - throw new IllegalArgumentException("TenantBindingUtils.getPropertyValues: null property name!"); - } - List tenantPropList = tenantBinding.getProperties(); - return PropertyItemUtils.getPropertyValueByNameFromNodeList(tenantPropList, propName ); + String propName) { + if (propName == null) { + throw new IllegalArgumentException("TenantBindingUtils.getPropertyValue: null property name!"); + } + List tenantPropList = tenantBinding.getProperties(); + return PropertyItemUtils.getPropertyValueByNameFromNodeList(tenantPropList, propName); + } + + /** + * Gets the values of a configured property for a tenant. + * + * @param tenantBinding a tenant binding + * @param propName the property to fetch (can return multiple values for this property). + * @return a list of values for the supplied property. + */ + public static List getPropertyValues(TenantBindingType tenantBinding, + String propName) { + List propValues = null; + List propList = tenantBinding.getProperties(); + if (propList != null && propList.size() > 0) { + List propItems = propList.get(0).getItem(); + for (PropertyItemType propItem : propItems) { + if (propName.equals(propItem.getKey())) { + String value = propItem.getValue(); + if (value != null) { + if (propValues == null) { + propValues = new ArrayList(); + } + propValues.add(value); + } + } + } + } + return propValues; } - + /** * @param service * @param propName the property to fetch @@ -36,15 +64,15 @@ public class TenantBindingUtils { * @return true if set, false if an existing value was left as is. */ public static boolean setPropertyValue(TenantBindingType tenantBinding, - PropertyItemType prop, boolean onlyIfNotSet) { - if(prop==null) { - throw new IllegalArgumentException( - "TenantBindingUtils.setPropertyValue: null property!"); - } - return setPropertyValue(tenantBinding, prop.getKey(), prop.getValue(), - onlyIfNotSet); + PropertyItemType prop, boolean onlyIfNotSet) { + if (prop == null) { + throw new IllegalArgumentException( + "TenantBindingUtils.setPropertyValue: null property!"); + } + return setPropertyValue(tenantBinding, prop.getKey(), prop.getValue(), + onlyIfNotSet); } - + /** * @param tenantBinding * @param propName the property to fetch @@ -53,18 +81,17 @@ public class TenantBindingUtils { * @return true if set, false if an existing value was left as is. */ public static boolean setPropertyValue(TenantBindingType tenantBinding, - String propName, String value, - boolean onlyIfNotSet) { - boolean valueFound = false; - boolean valueSet = false; - if(propName==null) { - throw new IllegalArgumentException("TenantBindingUtils.setPropertyValue: null property name!"); - } - List tenantPropertiesNode = tenantBinding.getProperties(); - return PropertyItemUtils.setPropertyValueInNodeList(tenantPropertiesNode, - propName, value, onlyIfNotSet); + String propName, String value, + boolean onlyIfNotSet) { + boolean valueFound = false; + boolean valueSet = false; + if (propName == null) { + throw new IllegalArgumentException("TenantBindingUtils.setPropertyValue: null property name!"); + } + List tenantPropertiesNode = tenantBinding.getProperties(); + return PropertyItemUtils.setPropertyValueInNodeList(tenantPropertiesNode, + propName, value, onlyIfNotSet); } - /** * @param tenantBinding @@ -74,15 +101,14 @@ public class TenantBindingUtils { * @return true if set, false if an existing value was left as is. */ public static void propagatePropertiesToServices( - TenantBindingType tenantBinding, boolean onlyIfNotSet) { - List tenantPropList = - tenantBinding.getProperties().get(0).getItem(); - for(PropertyItemType tenantPropItem:tenantPropList) { - for(ServiceBindingType service:tenantBinding.getServiceBindings()) { - ServiceBindingUtils.setPropertyValue(service, - tenantPropItem, onlyIfNotSet); - } - } + TenantBindingType tenantBinding, boolean onlyIfNotSet) { + List tenantPropList = + tenantBinding.getProperties().get(0).getItem(); + for (PropertyItemType tenantPropItem : tenantPropList) { + for (ServiceBindingType service : tenantBinding.getServiceBindings()) { + ServiceBindingUtils.setPropertyValue(service, + tenantPropItem, onlyIfNotSet); + } + } } - } diff --git a/services/common/src/main/java/org/collectionspace/services/common/datetime/DateTimeFormatUtils.java b/services/common/src/main/java/org/collectionspace/services/common/datetime/DateTimeFormatUtils.java new file mode 100644 index 000000000..b01e5b80b --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/common/datetime/DateTimeFormatUtils.java @@ -0,0 +1,226 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2009 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + */ +package org.collectionspace.services.common.datetime; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.ArrayList; +import java.util.List; +import java.util.TimeZone; + +import org.collectionspace.services.common.ServiceMain; +import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl; +import org.collectionspace.services.common.config.TenantBindingUtils; +import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.tenant.TenantBindingType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * DateTimeFormatUtils.java + * + * $LastChangedRevision$ + * $LastChangedDate$ + * + */ +public class DateTimeFormatUtils { + + private static final Logger logger = LoggerFactory.getLogger(DateTimeFormatUtils.class); + final static String DATE_FORMAT_PATTERN_PROPERTY_NAME = "datePattern"; + final static String ISO_8601_UTC_TIMESTAMP_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'"; + + // FIXME: + // - Add a method to return the default set of ISO 8601-based date patterns, + // irrespective of per-tenant configuration. + // - Consider cacheing the lists of per-tenant date format patterns + // and refresh the cached copies whenever tenant bindings are read. + // - Methods below related to per-tenant configuration of date formats might + // be moved to their own class. + + /** + * Returns a list of the date format patterns permitted in a service context. + * These patterns must conform to the format for date and time pattern strings + * specified in the Javadocs for the Java language class, java.text.SimpleDateFormat. + * + * @param ctx a service context. + * + * @return a list of date format patterns permitted in the service context. + * Returns an empty list of patterns if the service context is null. + */ + public static List getDateFormatPatternsForTenant(ServiceContext ctx) { + if (ctx == null) { + return new ArrayList(); + } + return getDateFormatPatternsForTenant(ctx.getTenantId()); + } + + /** + * Returns a list of the date format patterns permitted for a tenant, specified + * by tenant ID. + * + * These patterns must conform to the format for date and time pattern strings + * specified in the Javadocs for the Java language class, java.text.SimpleDateFormat. + * + * @param tenantId a tenant ID. + * + * @return a list of date format patterns permitted for the tenant. + */ + public static List getDateFormatPatternsForTenant(String tenantId) { + List patterns = new ArrayList(); + if (tenantId == null || tenantId.trim().isEmpty()) { + return patterns; + } + TenantBindingConfigReaderImpl tReader = + ServiceMain.getInstance().getTenantBindingConfigReader(); + TenantBindingType tenantBinding = tReader.getTenantBinding(tenantId); + patterns = TenantBindingUtils.getPropertyValues(tenantBinding, + DATE_FORMAT_PATTERN_PROPERTY_NAME); + return validatePatterns(patterns); + } + + public static List validatePatterns(List patterns) { + if (patterns == null) { + return new ArrayList(); + } + List validPatterns = new ArrayList(); + for (String pattern : patterns) { + try { + DateFormat df = getDateFormatter(pattern); + validPatterns.add(pattern); + } catch (IllegalArgumentException iae) { + logger.warn("Invalid " + DATE_FORMAT_PATTERN_PROPERTY_NAME + " property: " + pattern); + } + } + return validPatterns; + } + + /** + * Returns a representation of a calendar date and time instance, + * as an ISO 8601-formatted timestamp in the UTC time zone. + * + * @param cal a calendar date and time instance. + * + * @return a representation of that calendar date and time instance, + * as an ISO 8601-formatted timestamp in the UTC time zone. + */ + public static String formatAsISO8601Timestamp(GregorianCalendar cal) { + return formatGregorianCalendarDate(cal, GregorianCalendarDateTimeUtils.UTCTimeZone(), + getDateFormatter(ISO_8601_UTC_TIMESTAMP_PATTERN)); + } + + /** + * Formats a provided calendar date using a provided date formatter, + * in the default system time zone. + * + * @param date A calendar date to format. + * @param df A date formatter to apply. + * + * @return A formatted date string, or the empty string + * if one or more of the parameter values were invalid. + */ + public static String formatGregorianCalendarDate(GregorianCalendar gcal, DateFormat df) { + return formatGregorianCalendarDate(gcal, TimeZone.getDefault(), df); + } + + /** + * Formats a provided calendar date using a provided date formatter, + * in a provided time zone. + * + * @param date A calendar date to format. + * @param tz The time zone qualifier for the calendar date to format. + * @param df A date formatter to apply. + * + * @return A formatted date string, or the empty string + * if one or more of the parameter values were invalid. + */ + public static String formatGregorianCalendarDate(GregorianCalendar gcal, TimeZone tz, DateFormat df) { + String formattedDate = ""; + if (gcal == null) { + logger.warn("Null calendar date was provided when a non-null calendar date was required."); + return formattedDate; + } + if (tz == null) { + logger.warn("Null time zone was provided when a non-null time zone was required."); + return formattedDate; + } + if (df == null) { + logger.warn("Null date formatter was provided when a non-null date formatter was required."); + return formattedDate; + } + gcal.setTimeZone(tz); + Date date = gcal.getTime(); + df.setTimeZone(tz); + formattedDate = df.format(date); + return formattedDate; + } + + /** + * Identifies whether a presumptive date or date/time can be parsed + * by a date parser, using a specified format pattern. + * + * @param str a String, possibly a date or date/time String. + * + * @param pattern A date or date/time pattern. + * + * @return true, if the String can be parsed, using the pattern; + * false if the String cannot be parsed by the pattern, + * or if the String or pattern are null. + */ + public static boolean isParseableByDatePattern(String str, String pattern) { + if (pattern == null || pattern.trim().isEmpty()) { + return false; + } + DateFormat df = null; + try { + df = new SimpleDateFormat(pattern); + df.parse(str); + } catch (ParseException pe) { + return false; + } catch (IllegalArgumentException iae) { + return false; + } + return true; + } + + /** + * Returns a date formatter for a provided date or date/time pattern. + * + * @param pattern A date or date/time pattern. + * + * @return A date formatter using that pattern, or null + * if the pattern was null, empty, or invalid. + */ + public static DateFormat getDateFormatter(String pattern) { + DateFormat df = null; + if (pattern == null || pattern.trim().isEmpty()) { + logger.warn("Null or empty date pattern string was provided when getting date formatter."); + return df; + } + try { + df = new SimpleDateFormat(pattern); + } catch (IllegalArgumentException iae) { + logger.warn("Invalid date pattern string '" + pattern + "': " + iae.getMessage()); + } + return df; + } +} diff --git a/services/common/src/main/java/org/collectionspace/services/common/datetime/GregorianCalendarDateTimeUtils.java b/services/common/src/main/java/org/collectionspace/services/common/datetime/GregorianCalendarDateTimeUtils.java index afc6f0acc..0aab30641 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/datetime/GregorianCalendarDateTimeUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/datetime/GregorianCalendarDateTimeUtils.java @@ -17,8 +17,6 @@ */ package org.collectionspace.services.common.datetime; -import java.text.DateFormat; -import java.text.SimpleDateFormat; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; @@ -86,99 +84,7 @@ public class GregorianCalendarDateTimeUtils { * @return A String representing the current date and time instance. */ public static String timestampUTC() { - return formatAsISO8601Timestamp(currentDateAndTime(UTCTimeZone())); - } - - /** - * Returns a representation of a calendar date and time instance, - * as an ISO 8601-formatted timestamp in the UTC time zone. - * - * @param cal A calendar date and time instance - * - * @return A representation of that calendar date and time instance, - * as an ISO 8601-formatted timestamp in the UTC time zone. - */ - public static String formatAsISO8601Timestamp(GregorianCalendar cal) { - return formatCalendarDate(cal, UTCTimeZone(), ISO8601TimestampFormatter()); - } - - /** - * Formats a provided calendar date using a provided date formatter, - * in the default system time zone. - * - * @param date A calendar date to format. - * @param df A date formatter to apply. - * - * @return A formatted date string, or the empty string - * if one or more of the parameter values were invalid. - */ - public static String formatCalendarDate(GregorianCalendar gcal, DateFormat df) { - return formatCalendarDate(gcal, TimeZone.getDefault(), df); - } - - /** - * Formats a provided calendar date using a provided date formatter, - * in a provided time zone. - * - * @param date A calendar date to format. - * @param tz The time zone qualifier for the calendar date to format. - * @param df A date formatter to apply. - * - * @return A formatted date string, or the empty string - * if one or more of the parameter values were invalid. - */ - public static String formatCalendarDate(GregorianCalendar gcal, TimeZone tz, DateFormat df) { - String formattedDate = ""; - if (gcal == null) { - logger.warn("Null calendar date was provided when a non-null calendar date was required."); - return formattedDate; - } - if (tz == null) { - logger.warn("Null time zone was provided when a non-null time zone was required."); - return formattedDate; - } - if (df == null) { - logger.warn("Null date formatter was provided when a non-null date formatter was required."); - return formattedDate; - } - gcal.setTimeZone(tz); - Date date = gcal.getTime(); - df.setTimeZone(tz); - formattedDate = df.format(date); - return formattedDate; - } - - /** - * Returns a date formatter for an ISO 8601 timestamp pattern. - * - * @return A date formatter for an ISO 8601 timestamp pattern. - * This pattern is specified as a class constant above. - */ - public static DateFormat ISO8601TimestampFormatter() { - return getDateFormatter(ISO_8601_UTC_TIMESTAMP_PATTERN); - } - - /** - * Returns a date formatter for a provided date or date/time pattern. - * - * @param pattern A date or date/time pattern. - * - * @return A date formatter using that pattern, or null - * if the pattern was null, empty, or invalid. - */ - public static DateFormat getDateFormatter(String pattern) { - DateFormat df = null; - if (pattern == null || pattern.trim().isEmpty()) { - logger.warn("Null or empty date pattern string was provided " + - "when a non-null, non-empty date pattern string was required."); - return df; - } - try { - df = new SimpleDateFormat(pattern); - } catch (IllegalArgumentException iae) { - logger.warn("Invalid date pattern string: " + pattern); - } - return df; + return DateTimeFormatUtils.formatAsISO8601Timestamp(currentDateAndTime(UTCTimeZone())); } } diff --git a/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementDocumentModelHandler.java b/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementDocumentModelHandler.java index f606909c1..808b28ebc 100644 --- a/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementDocumentModelHandler.java +++ b/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementDocumentModelHandler.java @@ -23,17 +23,13 @@ */ package org.collectionspace.services.movement.nuxeo; -import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import org.collectionspace.services.MovementJAXBSchema; -import org.collectionspace.services.common.datetime.GregorianCalendarDateTimeUtils; +import org.collectionspace.services.common.datetime.DateTimeFormatUtils; import org.collectionspace.services.common.document.DocumentWrapper; -import org.collectionspace.services.common.service.ObjectPartType; import org.collectionspace.services.movement.MovementsCommon; import org.collectionspace.services.movement.MovementsCommonList; import org.collectionspace.services.movement.MovementsCommonList.MovementListItem; @@ -46,14 +42,15 @@ import org.slf4j.LoggerFactory; /** * The Class MovementDocumentModelHandler. + * + * $LastChangedRevision$ + * $LastChangedDate$ */ public class MovementDocumentModelHandler extends RemoteDocumentModelHandlerImpl { /** The logger. */ private final Logger logger = LoggerFactory.getLogger(MovementDocumentModelHandler.class); - - private static final String COMMON_PART_LABEL = "movements_common"; /** The Movement. */ private MovementsCommon Movement; @@ -145,7 +142,7 @@ public class MovementDocumentModelHandler MovementJAXBSchema.MOVEMENT_REFERENCE_NUMBER)); GregorianCalendar gcal = (GregorianCalendar) docModel.getProperty(getServiceContext().getCommonPartLabel(), MovementJAXBSchema.LOCATION_DATE); - ilistItem.setLocationDate(GregorianCalendarDateTimeUtils.formatAsISO8601Timestamp(gcal)); + ilistItem.setLocationDate(DateTimeFormatUtils.formatAsISO8601Timestamp(gcal)); String id = NuxeoUtils.extractId(docModel.getPathAsString()); ilistItem.setUri(getServiceContextPath() + id); ilistItem.setCsid(id); @@ -166,15 +163,5 @@ public class MovementDocumentModelHandler return MovementConstants.NUXEO_SCHEMA_NAME + ":" + prop; } - private boolean isDateTimeType(Object obj) { - boolean isDateTimeType = false; - - if (obj != null && obj instanceof Calendar) { - isDateTimeType = true; - } - - return isDateTimeType; - } - } diff --git a/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementValidatorHandler.java b/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementValidatorHandler.java index 5b29958e4..0bd4dd934 100644 --- a/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementValidatorHandler.java +++ b/services/movement/service/src/main/java/org/collectionspace/services/movement/nuxeo/MovementValidatorHandler.java @@ -1,17 +1,76 @@ package org.collectionspace.services.movement.nuxeo; +import java.util.List; + import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.context.MultipartServiceContext; +import org.collectionspace.services.common.datetime.DateTimeFormatUtils; import org.collectionspace.services.common.document.InvalidDocumentException; import org.collectionspace.services.common.document.ValidatorHandler; import org.collectionspace.services.common.document.DocumentHandler.Action; +import org.collectionspace.services.movement.MovementsCommon; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class MovementValidatorHandler implements ValidatorHandler { + final Logger logger = LoggerFactory.getLogger(MovementValidatorHandler.class); + @Override public void validate(Action action, ServiceContext ctx) throws InvalidDocumentException { - // TODO Auto-generated method stub - System.out.println("movementValidatorHandler executed."); + + if(logger.isDebugEnabled()) { + logger.debug("validate() action=" + action.name()); + } + try { + MultipartServiceContext mctx = (MultipartServiceContext) ctx; + MovementsCommon mc = (MovementsCommon) mctx.getInputPart(mctx.getCommonPartLabel(), + MovementsCommon.class); + StringBuilder msgBldr = new StringBuilder("validate()"); + boolean invalid = false; + + List patterns = DateTimeFormatUtils.getDateFormatPatternsForTenant(ctx); + + // FIXME: This is an early proof-of-concept. + // + // We need a better way of determining which fields + // in the incoming payload are date fields whose values we + // might wish to validate, and of extracting their values, + // than hard-coding them here. + + /* + boolean validDateFormat = false; + String locDate = mc.getLocationDate(); + for (String pattern : patterns) { + if (DateTimeFormatUtils.isParseableByDatePattern(locDate, pattern)) { + validDateFormat = true; + } + } + if (! validDateFormat) { + invalid = true; + msgBldr.append("\nlocationDate : unrecognized date format '" + locDate + "'"); + } + * + */ + + if(action.equals(Action.CREATE)) { + //create specific validation here + } else if(action.equals(Action.UPDATE)) { + //update specific validation here + } + + if (invalid) { + String msg = msgBldr.toString(); + logger.error(msg); + throw new InvalidDocumentException(msg); + } + } catch (InvalidDocumentException ide) { + throw ide; + } catch (Exception e) { + throw new InvalidDocumentException(e); + } } -- 2.47.3