<xs:element name="currentLocation" type="xs:string"/>\r
<xs:element name="currentLocationFitness" type="xs:string"/>\r
<xs:element name="currentLocationNote" type="xs:string"/>\r
- <xs:element name="locationDate" type="xs:string"/>\r
+ <xs:element name="locationDate" type="xs:dateTime"/>\r
<xs:element name="normalLocation" type="xs:string"/>\r
\r
<!-- Movement Information Group -->\r
</xs:element>\r
<xs:element name="movementNote" type="xs:string"/>\r
<xs:element name="movementReferenceNumber" type="xs:string"/>\r
- <xs:element name="plannedRemovalDate" type="xs:string"/>\r
- <xs:element name="removalDate" type="xs:string"/>\r
+ <xs:element name="plannedRemovalDate" type="xs:dateTime"/>\r
+ <xs:element name="removalDate" type="xs:dateTime"/>\r
<xs:element name="reasonForMove" type="xs:string"/>\r
\r
</xs:schema>\r
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
- <scope>test</scope>
+ <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
- <scope>test</scope>
+ <scope>provided</scope>
</dependency>
<!-- CollectionSpace dependencies -->
<dependency>
--- /dev/null
+/**
+ * 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 (c) 2009 Regents of the University of California
+ *
+ * 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.client;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * MovementClientDateTimeUtils.java
+ *
+ * $LastChangedRevision: 2107 $
+ * $LastChangedDate: 2010-05-17 18:22:27 -0700 (Mon, 17 May 2010) $
+ *
+ */
+public class MovementClientDateTimeUtils {
+
+ private static final Logger logger =
+ LoggerFactory.getLogger(MovementClientDateTimeUtils.class);
+
+ final static String UTC_TIMEZONE_IDENTIFIER = "UTC";
+ final static String ISO_8601_UTC_TIMESTAMP_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'";
+
+ // FIXME The methods below are not specific to the Movement service
+ // or its client code.
+ //
+ // At present, they may redundantly be included in or referenced from
+ // several classes in the Movement service module, in its 'service'
+ // and/or 'client' sub-modules.
+ //
+ // However, these methods, and any associated constants and imports
+ // above, should instead be moved to the Date and Time service or
+ // into another common package, where they can be shared by multiple services.
+
+ /**
+ * Returns the default time zone.
+ *
+ * @return The default time zone
+ */
+ public static TimeZone defaultTimeZone() {
+ return TimeZone.getDefault();
+ }
+
+ /**
+ * Returns a calendar date, representing the current date and time instance
+ * in the default time zone.
+ *
+ * @return The current date and time instance in the default time zone
+ */
+ public static GregorianCalendar currentDateAndTime() {
+ return currentDateAndTime(defaultTimeZone());
+ }
+
+ /**
+ * Returns the UTC time zone.
+ *
+ * @return The UTC time zone. Defaults to the closely-related GMT time zone,
+ * if for some reason the UTC time zone identifier cannot be understood.
+ */
+ public static TimeZone UTCTimeZone() {
+ return TimeZone.getTimeZone(UTC_TIMEZONE_IDENTIFIER);
+ }
+
+ /**
+ * Returns a calendar date, representing the current date and time instance
+ * in the UTC time zone.
+ *
+ * @return The current date and time instance in the UTC time zone.
+ */
+ public static GregorianCalendar currentDateAndTimeUTC() {
+ return currentDateAndTime(UTCTimeZone());
+ }
+
+ /**
+ * Returns a calendar date, representing the current date and time instance
+ * in the specified time zone.
+ *
+ * @return The current date and time instance in the specified time zone.
+ * If the time zone is null, will return the current time and
+ * date in the time zone intrinsic to a new Calendar instance.
+ */
+ public static GregorianCalendar currentDateAndTime(TimeZone tz) {
+ GregorianCalendar gcal = new GregorianCalendar();
+ if (tz != null) {
+ gcal.setTimeZone(tz);
+ }
+ Date now = new Date();
+ gcal.setTime(now);
+ return gcal;
+ }
+
+ /**
+ * Returns a String representing the current date and time instance.
+ * in the UTC time zone, formatted as an ISO 8601 timestamp.
+ *
+ * @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;
+ }
+}
import org.collectionspace.services.client.CollectionSpaceClient;
import org.collectionspace.services.client.MovementClient;
+import org.collectionspace.services.client.MovementClientDateTimeUtils;
import org.collectionspace.services.jaxb.AbstractCommonList;
import org.collectionspace.services.movement.MovementsCommon;
import org.collectionspace.services.movement.MovementsCommonList;
*/
private MultipartOutput createInstance(String movementReferenceNumber) {
MovementsCommon movement = new MovementsCommon();
+ String timestampUTC = MovementClientDateTimeUtils.timestampUTC();
// FIXME: Values of currentLocation, normalLocation,
// and movementContact should be refNames.
movement.setCurrentLocation("currentLocation value");
movement.setCurrentLocationFitness("currentLocationFitness value");
movement.setCurrentLocationNote("currentLocationNote value");
- movement.setLocationDate(timestampUTC());
+ movement.setLocationDate(timestampUTC);
movement.setNormalLocation("normalLocation value");
movement.setMovementContact("movementContact value");
MovementMethodsList movementMethodsList = new MovementMethodsList();
movement.setMovementMethods(movementMethodsList);
movement.setMovementNote("movementNote value");
movement.setMovementReferenceNumber(movementReferenceNumber);
- movement.setPlannedRemovalDate("plannedRemovalDate value");
- movement.setRemovalDate("removalDate value");
+ movement.setPlannedRemovalDate(timestampUTC);
+ movement.setRemovalDate(timestampUTC);
movement.setReasonForMove("reasonForMove value");
MultipartOutput multipart = new MultipartOutput();
OutputPart commonPart =
*/
package org.collectionspace.services.movement.nuxeo;
+import java.util.ArrayList;
+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.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;
/** The logger. */
private final Logger logger = LoggerFactory.getLogger(MovementDocumentModelHandler.class);
+
+ private static final String COMMON_PART_LABEL = "movements_common";
+
+ private static final ArrayList<String> DATE_TIME_FIELDS = dateTimeFields();
/** The Movement. */
private MovementsCommon Movement;
this.MovementList = MovementList;
}
+ /* (non-Javadoc)
+ * @see org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl#extractPart(org.nuxeo.ecm.core.api.DocumentModel, java.lang.String, org.collectionspace.services.common.service.ObjectPartType)
+ */
+ @Override
+ protected Map<String, Object> extractPart(DocumentModel docModel, String schema, ObjectPartType partMeta)
+ throws Exception {
+ Map<String, Object> unQObjectProperties = super.extractPart(docModel, schema, partMeta);
+
+ // For each dateTime field in the common part, return an
+ // appropriately formatted representation of its value.
+ if (partMeta.getLabel().equalsIgnoreCase(COMMON_PART_LABEL)) {
+ for(Entry<String, Object> entry : unQObjectProperties.entrySet()){
+ if (isDateTimeType(entry)) {
+ entry.setValue(
+ MovementServiceDateTimeUtils.formatAsISO8601Timestamp(
+ (GregorianCalendar) entry.getValue()));
+ }
+ }
+ }
+
+ return unQObjectProperties;
+ }
+
/**
* Extract common part.
*
MovementListItem ilistItem = new MovementListItem();
ilistItem.setMovementReferenceNumber((String) docModel.getProperty(getServiceContext().getCommonPartLabel(),
MovementJAXBSchema.MOVEMENT_REFERENCE_NUMBER));
- ilistItem.setLocationDate((String) docModel.getProperty(getServiceContext().getCommonPartLabel(),
- MovementJAXBSchema.LOCATION_DATE));
+ GregorianCalendar gcal = (GregorianCalendar) docModel.getProperty(getServiceContext().getCommonPartLabel(),
+ MovementJAXBSchema.LOCATION_DATE);
+ ilistItem.setLocationDate(MovementServiceDateTimeUtils.formatAsISO8601Timestamp(gcal));
String id = NuxeoUtils.extractId(docModel.getPathAsString());
ilistItem.setUri(getServiceContextPath() + id);
ilistItem.setCsid(id);
public String getQProperty(String prop) {
return MovementConstants.NUXEO_SCHEMA_NAME + ":" + prop;
}
+
+ private boolean isDateTimeType(Entry<String, Object> entry) {
+ boolean isDateTimeType = false;
+
+ // Approach 1: Check the name of this property against a list of
+ // dateTime field names.
+ if (DATE_TIME_FIELDS.contains(entry.getKey())){
+ isDateTimeType = true;
+ }
+
+ // Approach 2: Check the data type of this property's value.
+ /*
+ if (entry.getValue() instanceof Calendar) {
+ isDateTimeType = true;
+ }
+ *
+ */
+
+ return isDateTimeType;
+ }
+
+ /**
+ * Returns a list of the names of dateTime fields (e.g. fields whose
+ * XML Schema datatype is xs:dateTime).
+ *
+ * @return A list of names of dateTime fields.
+ */
+ private static ArrayList<String> dateTimeFields() {
+ // FIXME Rather than hard-coding directly here,
+ // identify these fields from configuration, such as:
+ // * Metadata returned from Nuxeo, if available.
+ // * Examination of the XSD schema for this document type.
+ // * External configuration (e.g. date fields as tenant bindings props, via
+ // org.collectionspace.services.common.context.ServiceBindingUtils)
+ ArrayList<String> dateTimeTypeFields = new ArrayList();
+ dateTimeTypeFields.add(MovementJAXBSchema.LOCATION_DATE);
+ dateTimeTypeFields.add(MovementJAXBSchema.PLANNED_REMOVAL_DATE);
+ dateTimeTypeFields.add(MovementJAXBSchema.REMOVAL_DATE);
+ return dateTimeTypeFields;
+ }
}
--- /dev/null
+/**
+ * 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 (c) 2009 Regents of the University of California
+ *
+ * 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.movement.nuxeo;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * MovementClientDateTimeUtils.java
+ *
+ * $LastChangedRevision: 2107 $
+ * $LastChangedDate: 2010-05-17 18:22:27 -0700 (Mon, 17 May 2010) $
+ *
+ */
+public class MovementServiceDateTimeUtils {
+
+ private static final Logger logger =
+ LoggerFactory.getLogger(MovementServiceDateTimeUtils.class);
+
+ final static String UTC_TIMEZONE_IDENTIFIER = "UTC";
+ final static String ISO_8601_UTC_TIMESTAMP_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'";
+
+ // FIXME The methods below are not specific to the Movement service
+ // or its client code.
+ //
+ // At present, they may redundantly be included in or referenced from
+ // several classes in the Movement service module, in its 'service'
+ // and/or 'client' sub-modules.
+ //
+ // However, these methods, and any associated constants and imports
+ // above, should instead be moved to the Date and Time service or
+ // into another common package, where they can be shared by multiple services.
+
+ /**
+ * Returns the UTC time zone.
+ *
+ * @return The UTC time zone. Defaults to the closely-related GMT time zone,
+ * if for some reason the UTC time zone identifier cannot be understood.
+ */
+ public static TimeZone UTCTimeZone() {
+ return TimeZone.getTimeZone(UTC_TIMEZONE_IDENTIFIER);
+ }
+
+ /**
+ * Returns a calendar date, representing the current date and time instance
+ * in the UTC time zone.
+ *
+ * @return The current date and time instance in the UTC time zone.
+ */
+ public static GregorianCalendar currentDateAndTimeUTC() {
+ return currentDateAndTime(UTCTimeZone());
+ }
+
+ /**
+ * Returns a calendar date, representing the current date and time instance
+ * in the specified time zone.
+ *
+ * @return The current date and time instance in the specified time zone.
+ * If the time zone is null, will return the current time and
+ * date in the time zone intrinsic to a new Calendar instance.
+ */
+ public static GregorianCalendar currentDateAndTime(TimeZone tz) {
+ GregorianCalendar gcal = new GregorianCalendar();
+ if (tz != null) {
+ gcal.setTimeZone(tz);
+ }
+ Date now = new Date();
+ gcal.setTime(now);
+ return gcal;
+ }
+
+ /**
+ * Returns a String representing the current date and time instance.
+ * in the UTC time zone, formatted as an ISO 8601 timestamp.
+ *
+ * @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;
+ }
+
+}