1 package org.collectionspace.services.nuxeo.extension.thumbnail;
4 import java.io.IOException;
5 import java.io.Serializable;
6 import java.security.NoSuchAlgorithmException;
7 import java.util.Calendar;
8 import java.util.GregorianCalendar;
10 import org.apache.commons.logging.Log;
11 import org.apache.commons.logging.LogFactory;
12 import org.nuxeo.ecm.core.api.Blob;
13 import org.nuxeo.ecm.core.api.ClientException;
14 import org.nuxeo.ecm.core.api.CoreSession;
15 import org.nuxeo.ecm.core.api.DocumentModel;
16 import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner;
17 import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
18 import org.nuxeo.ecm.core.convert.api.ConversionService;
19 import org.nuxeo.ecm.platform.filemanager.api.FileManager;
20 import org.nuxeo.runtime.api.Framework;
22 public class AddThumbnailUnrestricted extends UnrestrictedSessionRunner {
24 private static final Log logger = LogFactory
25 .getLog(AddThumbnailUnrestricted.class);
27 protected ConversionService cs;
29 protected DocumentModel doc;
31 protected BlobHolder blobHolder;
33 protected Thumbnail thumbnail = null;
35 public AddThumbnailUnrestricted(CoreSession coreSession, DocumentModel doc,
36 BlobHolder blobHolder) {
39 this.blobHolder = blobHolder;
44 * @see org.nuxeo.ecm.core.api.UnrestrictedSessionRunner#run()
46 * Creates a new thumbnail image and associates it with the document blob by adding a "Thumnail" facet
47 * to the document blob.
50 public void run() throws ClientException {
51 String errMsg = "Error while adding preview thumbnail.";
52 String documentId = doc.getId();
55 Blob blob = blobHolder.getBlob();
57 if (doc.hasFacet(ThumbnailConstants.THUMBNAIL_FACET) == false) { // Make sure we don't already have a "Thumbnail" facet
58 cs = Framework.getService(ConversionService.class);
59 ensureModificationDateExists(doc); // For some reason, the ConversionService service requires the modification date of the blob is not null so we need to ensure it is not null.
60 BlobHolder thumbnailBlobHolder = cs.convert(ThumbnailConstants.THUMBNAIL_CONVERTER_NAME,
61 blobHolder, null /*no params*/);
62 if (thumbnailBlobHolder != null && thumbnailBlobHolder.getBlob() != null) {
63 Blob thumbnailBlob = thumbnailBlobHolder.getBlob();
64 doc.addFacet(ThumbnailConstants.THUMBNAIL_FACET); // Add the "Thumbnail" facet since we were able to create a thumnail image
65 // Give the thumbnail blob a name.
66 String thumbnailName = documentId + ThumbnailConstants.THUMBNAIL_PROPERTY_NAME;
67 thumbnailBlobHolder.getBlob().setFilename(thumbnailName); // Give it a name so we can manually search for it in the "nuxeo" database
69 doc.setProperty(ThumbnailConstants.THUMBNAIL_SCHEMA_NAME,
70 ThumbnailConstants.THUMBNAIL_FILENAME_PROPERTY_NAME,
71 (Serializable) thumbnailName);
72 doc.setProperty(ThumbnailConstants.THUMBNAIL_SCHEMA_NAME,
73 ThumbnailConstants.THUMBNAIL_PROPERTY_NAME,
74 (Serializable) thumbnailBlob);
76 // Save the new Thumnail facet data (including the new thumbnail image). The save triggers a new create event and recurses us back to
77 // this method, but the next time we'll have a Thumbnail facet and bypass this save -sparing us from an infinite event loop.
79 doc = session.saveDocument(doc);
81 logger.warn("Could not create a preview thumbnail image for Nuxeo blob document: " + doc.getId());
85 logger.warn(errMsg + " " + "The Nuxeo blob holder had an empty blob object. Document ID:" + doc.getId());
87 } catch (Exception e) {
88 logger.warn(errMsg, e);
92 private String computeDigest(FileManager fileManager, Blob blob) throws Exception {
96 result = fileManager.computeDigest(blob); // REM - Warning: Why is this operation so slow?
101 private String ensureModificationDateExists(DocumentModel docModel) throws Exception {
102 Calendar modificationDate = (Calendar)doc.getProperty("dublincore", "modified");
103 if (modificationDate == null) {
104 // If the 'modified' field is null then try the 'created' field
105 Calendar creationDate = (Calendar)doc.getProperty("dublincore", "created");
106 if (creationDate != null) {
107 modificationDate = creationDate;
109 // We *need* a 'modified' date, so let's use the current date
110 modificationDate = new GregorianCalendar();
112 doc.setProperty("dublincore", "modified", modificationDate);
115 return modificationDate.toString();
118 public Thumbnail getAdapter() {