<modules>
<module>nuxeo-platform-collectionspace</module>
<module>nuxeo-platform-listener</module>
+ <!-- disabled in v4.2 build do to test failures during upgrade to Nuxeo 6
<module>nuxeo-platform-quote-api</module>
<module>nuxeo-platform-quote</module>
+ -->
<module>nuxeo-platform-thumbnail</module>
</modules>
import org.collectionspace.services.jaxb.BlobJAXBSchema;
import org.collectionspace.services.nuxeo.client.java.CommonList;
import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
-
import org.nuxeo.ecm.core.api.ClientException;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.IdRef;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Map;
+
import javax.ws.rs.core.MultivaluedMap;
+
import org.dom4j.Element;
/**
}
}
+ super.fillAllParts(wrapDoc, action);
+ }
+
+ @Override
+ public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception {
+ ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
+ BlobInput blobInput = BlobUtil.getBlobInput(ctx); // The blobInput should have been put into the context by the Blob or Media resource
+ if (blobInput != null && blobInput.getBlobFile() != null) {
+ boolean purgeOriginal = false;
+ MultivaluedMap<String, String> queryParams = ctx.getQueryParams();
+ String purgeOriginalStr = queryParams.getFirst(BlobClient.BLOB_PURGE_ORIGINAL);
+ if (purgeOriginalStr != null && purgeOriginalStr.isEmpty() == false) { // Find our if the caller wants us to purge/delete the original
+ purgeOriginal = true;
+ }
+ //
+ // If blobInput has a file then we just received a multipart/form-data file post or a URI query parameter
+ //
+ DocumentModel documentModel = wrapDoc.getWrappedObject();
+ CoreSessionInterface repoSession = this.getRepositorySession();
+
+ BlobsCommon blobsCommon = NuxeoBlobUtils.createBlobInRepository(ctx, repoSession, blobInput, purgeOriginal, true);
+ blobInput.setBlobCsid(documentModel.getName()); //Assumption here is that the documentModel "name" field is storing a CSID
+
+ PoxPayloadIn input = ctx.getInput();
+ //
+ // If the input payload is null, then we're creating a new blob from a post or a uri. This means there
+ // is no "input" payload for our framework to process. Therefore we need to synthesize a payload from
+ // the BlobsCommon instance we just filled out.
+ //
+ if (input == null) {
+ PoxPayloadOut output = new PoxPayloadOut(BlobClient.SERVICE_PAYLOAD_NAME);
+ PayloadOutputPart commonPart = new PayloadOutputPart(BlobClient.SERVICE_COMMON_PART_NAME, blobsCommon);
+ output.addPart(commonPart);
+ input = new PoxPayloadIn(output.toXML());
+ ctx.setInput(input);
+ } else {
+ // At this point, we've created a blob document in the Nuxeo repository. Usually, we use the blob to create and instance of BlobsCommon and use
+ // that to populate the resource record. However, since the "input" var is not null the requester provided their own resource record data
+ // so we'll use it rather than deriving one from the blob.
+ logger.warn("A resource record payload was provided along with the actually blob binary file. This payload is usually derived from the blob binary. Since a payload was provided, we're creating the resource record from the payload and not from the corresponding blob binary." +
+ " The data in blob resource record fields may not correspond completely with the persisted blob binary file.");
+ }
+ }
+
super.fillAllParts(wrapDoc, action);
}
}
final static String ISO_8601_DATE_PATTERN = "yyyy-MM-dd";
final static String UTC_TIMEZONE_IDENTIFIER = "UTC";
- final static String ISO_8601_UTC_TIMESTAMP_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SS'Z'";
+ final static String ISO_8601_UTC_TIMESTAMP_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
final static Locale NULL_LOCALE = null;
- public final static List<String> isoLanguageCodes = new ArrayList(Arrays.asList(Locale.getISOLanguages()));
+ public final static List<String> isoLanguageCodes = new ArrayList<String>(Arrays.asList(Locale.getISOLanguages()));
/**
* Returns the UTC time zone.
package org.collectionspace.services.common.api;
import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
-import java.util.Locale;
import java.util.TimeZone;
import org.slf4j.Logger;
*/
public static String timestampUTC() {
return formatAsISO8601Timestamp(currentDateAndTime(DateUtils.UTCTimeZone()));
- }
-
- //
- // This is code take from the Nuxeo 6 code base. It is stripping off the thousandths place of the milliseconds value. I'm
- // not sure why they are doing this.
- //
- public static String formatW3CDateTime(Date date) {
- if (date == null) {
- return null;
- }
- Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
- cal.setTime(date);
- StringBuilder buf = new StringBuilder(32);
- return buf.append(cal.get(Calendar.YEAR)).append('-').append(
- pad(cal.get(Calendar.MONTH) + 1)).append('-').append(
- pad(cal.get(Calendar.DATE))).append('T').append(
- pad(cal.get(Calendar.HOUR_OF_DAY))).append(':').append(
- pad(cal.get(Calendar.MINUTE))).append(':').append(
- pad(cal.get(Calendar.SECOND))).append('.').append(
- pad(cal.get(Calendar.MILLISECOND) / 10)).append('Z').toString();
- }
-
- private final static String pad(int i) {
- return i < 10 ? "0".concat(String.valueOf(i)) : String.valueOf(i);
- }
-
+ }
/**
* Returns a String representing the current date and time instance.
return gcal;
}
+ /**
+ * Returns a representation of a calendar date
+ * 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(Date date) {
+ GregorianCalendar gcal = new GregorianCalendar();
+ gcal.setTime(date);
+ return formatAsISO8601Timestamp(gcal);
+ }
/**
* Returns a representation of a calendar date and time instance,
package org.collectionspace.services.common.document;
import java.lang.reflect.Array;
-
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.FieldPosition;
import java.text.NumberFormat;
-
import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import org.collectionspace.services.config.service.ObjectPartType;
import org.collectionspace.services.config.service.XmlContentType;
import org.dom4j.io.DOMReader;
-
import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
import org.jboss.resteasy.plugins.providers.multipart.InputPart;
//import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
import org.nuxeo.ecm.core.schema.types.FieldImpl;
import org.nuxeo.ecm.core.schema.types.QName;
import org.nuxeo.runtime.api.Framework;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
}
}
+ /*
+ * String-encode Nuxeo date types (DateType) as ISO8601 timestamps. If the value passed in is not a Nuxeo date type,
+ * use Nuxeo's "encode" method for the type to string-encode the value.
+ */
+ private static String encodeValue(Type type, Object value) {
+ String result = null;
+
+ if (type != null && value != null) {
+ if (type instanceof DateType) {
+ Date dateResult = null;
+ if (value instanceof Calendar) {
+ dateResult = ((Calendar)value).getTime();
+ } else if (value instanceof Date) {
+ dateResult = (Date)value;
+ } else {
+ logger.error(String.format("Cannot encode type %s with value %s", type, value));
+ }
+ if (dateResult != null) {
+ result = GregorianCalendarDateTimeUtils.formatAsISO8601Timestamp(dateResult);
+ }
+ } else {
+ result = type.encode(value); // If it's not of type DateType, use the default mechanism to encode the value
+ }
+ }
+
+ return result;
+ }
+
/**
* Builds the property.
*
}
*/
} else {
- String encodedVal = type.encode(value);
+ String encodedVal = encodeValue(type, value); // get a String representation of the value
element.setTextContent(encodedVal);
}
} else if (type.isComplexType()) {