From: Richard Millet Date: Tue, 7 Aug 2012 23:01:12 +0000 (-0700) Subject: CSPACE-5437: Adding nuxeo's thumbnail creation. X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=61a6e66ddcc061a0e8864e822963ed30f7bafadb;p=tmp%2Fjakarta-migration.git CSPACE-5437: Adding nuxeo's thumbnail creation. --- diff --git a/3rdparty/nuxeo/build.xml b/3rdparty/nuxeo/build.xml index 3e5b9ac6f..214b10dfa 100644 --- a/3rdparty/nuxeo/build.xml +++ b/3rdparty/nuxeo/build.xml @@ -130,6 +130,7 @@ + + - - - - - - - - - - - - - convert - -strip -thumbnail 100x100 -background transparent -gravity center -extent 100x100 -format png -quality 75 #{inputFilePath}[0] #{outputFilePath} - -strip -thumbnail 100x100 -background transparent -gravity center -extent 100x100 -format png -quality 75 #{inputFilePath}[0] #{outputFilePath} - You need to install ImageMagick. - - - - - - diff --git a/3rdparty/nuxeo/nuxeo-platform-thumbnail/src/main/java/org/collectionspace/services/nuxeo/extension/thumbnail/AddThumbnailUnrestricted.java b/3rdparty/nuxeo/nuxeo-platform-thumbnail/src/main/java/org/collectionspace/services/nuxeo/extension/thumbnail/AddThumbnailUnrestricted.java new file mode 100644 index 000000000..c21cd2094 --- /dev/null +++ b/3rdparty/nuxeo/nuxeo-platform-thumbnail/src/main/java/org/collectionspace/services/nuxeo/extension/thumbnail/AddThumbnailUnrestricted.java @@ -0,0 +1,122 @@ +package org.collectionspace.services.nuxeo.extension.thumbnail; + + +import java.io.IOException; +import java.io.Serializable; +import java.security.NoSuchAlgorithmException; +import java.util.Calendar; +import java.util.GregorianCalendar; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuxeo.ecm.core.api.Blob; +import org.nuxeo.ecm.core.api.ClientException; +import org.nuxeo.ecm.core.api.CoreSession; +import org.nuxeo.ecm.core.api.DocumentModel; +import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner; +import org.nuxeo.ecm.core.api.blobholder.BlobHolder; +import org.nuxeo.ecm.core.convert.api.ConversionService; +import org.nuxeo.ecm.platform.filemanager.api.FileManager; +import org.nuxeo.runtime.api.Framework; + +public class AddThumbnailUnrestricted extends UnrestrictedSessionRunner { + + private static final Log logger = LogFactory + .getLog(AddThumbnailUnrestricted.class); + + protected ConversionService cs; + + protected DocumentModel doc; + + protected BlobHolder blobHolder; + + protected Thumbnail thumbnail = null; + + public AddThumbnailUnrestricted(CoreSession coreSession, DocumentModel doc, + BlobHolder blobHolder) { + super(coreSession); + this.doc = doc; + this.blobHolder = blobHolder; + } + + /* + * (non-Javadoc) + * @see org.nuxeo.ecm.core.api.UnrestrictedSessionRunner#run() + * + * Creates a new thumbnail image and associates it with the document blob by adding a "Thumnail" facet + * to the document blob. + */ + @Override + public void run() throws ClientException { + String errMsg = "Error while adding preview thumbnail."; + String documentId = doc.getId(); + + try { + Blob blob = blobHolder.getBlob(); + if (blob != null) { + if (doc.hasFacet(ThumbnailConstants.THUMBNAIL_FACET) == false) { // Make sure we don't already have a "Thumbnail" facet + cs = Framework.getService(ConversionService.class); + 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. + BlobHolder thumbnailBlobHolder = cs.convert(ThumbnailConstants.THUMBNAIL_CONVERTER_NAME, + blobHolder, null /*no params*/); + if (thumbnailBlobHolder != null && thumbnailBlobHolder.getBlob() != null) { + Blob thumbnailBlob = thumbnailBlobHolder.getBlob(); + doc.addFacet(ThumbnailConstants.THUMBNAIL_FACET); // Add the "Thumbnail" facet since we were able to create a thumnail image + // Give the thumbnail blob a name. + String thumbnailName = documentId + ThumbnailConstants.THUMBNAIL_PROPERTY_NAME; + thumbnailBlobHolder.getBlob().setFilename(thumbnailName); // Give it a name so we can manually search for it in the "nuxeo" database + + doc.setProperty(ThumbnailConstants.THUMBNAIL_SCHEMA_NAME, + ThumbnailConstants.THUMBNAIL_FILENAME_PROPERTY_NAME, + (Serializable) thumbnailName); + doc.setProperty(ThumbnailConstants.THUMBNAIL_SCHEMA_NAME, + ThumbnailConstants.THUMBNAIL_PROPERTY_NAME, + (Serializable) thumbnailBlob); + // + // Save the new Thumnail facet data (including the new thumbnail image). The save triggers a new create event and recurses us back to + // this method, but the next time we'll have a Thumbnail facet and bypass this save -sparing us from an infinite event loop. + // + doc = session.saveDocument(doc); + } else { + logger.warn("Could not create a preview thumbnail image for Nuxeo blob document: " + doc.getId()); + } + } + } else { + logger.warn(errMsg + " " + "The Nuxeo blob holder had an empty blob object. Document ID:" + doc.getId()); + } + } catch (Exception e) { + logger.warn(errMsg, e); + } + } + + private String computeDigest(FileManager fileManager, Blob blob) throws Exception { + String result = null; + + // Compute the digest + result = fileManager.computeDigest(blob); // REM - Warning: Why is this operation so slow? + + return result; + } + + private String ensureModificationDateExists(DocumentModel docModel) throws Exception { + Calendar modificationDate = (Calendar)doc.getProperty("dublincore", "modified"); + if (modificationDate == null) { + // If the 'modified' field is null then try the 'created' field + Calendar creationDate = (Calendar)doc.getProperty("dublincore", "created"); + if (creationDate != null) { + modificationDate = creationDate; + } else { + // We *need* a 'modified' date, so let's use the current date + modificationDate = new GregorianCalendar(); + } + doc.setProperty("dublincore", "modified", modificationDate); + } + + return modificationDate.toString(); + } + + public Thumbnail getAdapter() { + return thumbnail; + } + +} diff --git a/3rdparty/nuxeo/nuxeo-platform-thumbnail/src/main/java/org/collectionspace/services/nuxeo/extension/thumbnail/ThumbnailConstants.java b/3rdparty/nuxeo/nuxeo-platform-thumbnail/src/main/java/org/collectionspace/services/nuxeo/extension/thumbnail/ThumbnailConstants.java new file mode 100644 index 000000000..2a75074c1 --- /dev/null +++ b/3rdparty/nuxeo/nuxeo-platform-thumbnail/src/main/java/org/collectionspace/services/nuxeo/extension/thumbnail/ThumbnailConstants.java @@ -0,0 +1,12 @@ +package org.collectionspace.services.nuxeo.extension.thumbnail; + +public class ThumbnailConstants { + public static final String THUMBNAIL_SIZE_PARAMETER_NAME = "size"; + public static final String THUMBNAIL_DEFAULT_SIZE = "200"; + public static final String THUMBNAIL_FACET = "Thumbnail"; + public static final String THUMBNAIL_SCHEMA_NAME = "thumbnail"; + public static final String THUMBNAIL_PROPERTY_NAME = "thumbnail"; + public static final String THUMBNAIL_DIGEST_PROPERTY_NAME = "digest"; + public static final String THUMBNAIL_FILENAME_PROPERTY_NAME = "fileName"; + public static final String THUMBNAIL_CONVERTER_NAME = "toThumbnail"; +} diff --git a/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/ThumbnailConverter.java b/3rdparty/nuxeo/nuxeo-platform-thumbnail/src/main/java/org/collectionspace/services/nuxeo/extension/thumbnail/ThumbnailConverter.java similarity index 73% rename from services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/ThumbnailConverter.java rename to 3rdparty/nuxeo/nuxeo-platform-thumbnail/src/main/java/org/collectionspace/services/nuxeo/extension/thumbnail/ThumbnailConverter.java index d6074afc4..001792546 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/ThumbnailConverter.java +++ b/3rdparty/nuxeo/nuxeo-platform-thumbnail/src/main/java/org/collectionspace/services/nuxeo/extension/thumbnail/ThumbnailConverter.java @@ -1,4 +1,4 @@ -package org.collectionspace.services.common.imaging.nuxeo; +package org.collectionspace.services.nuxeo.extension.thumbnail; import java.io.File; import java.io.Serializable; @@ -6,9 +6,11 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.nuxeo.ecm.core.api.Blob; import org.nuxeo.ecm.core.api.blobholder.BlobHolder; import org.nuxeo.ecm.core.api.impl.blob.FileBlob; +import org.nuxeo.ecm.core.api.impl.blob.StreamingBlob; import org.nuxeo.ecm.core.convert.api.ConversionException; import org.nuxeo.ecm.core.convert.cache.SimpleCachableBlobHolder; import org.nuxeo.ecm.core.convert.extension.Converter; @@ -19,12 +21,13 @@ import org.nuxeo.ecm.platform.commandline.executor.api.CommandAvailability; import org.nuxeo.ecm.platform.commandline.executor.api.CommandLineExecutorService; import org.nuxeo.ecm.platform.commandline.executor.api.ExecResult; import org.nuxeo.ecm.platform.picture.core.im.IMImageUtils; + import org.nuxeo.runtime.api.Framework; import org.nuxeo.runtime.services.streaming.FileSource; import org.nuxeo.runtime.services.streaming.StreamSource; public class ThumbnailConverter extends IMImageUtils implements Converter { - private static final Log log = LogFactory.getLog(ThumbnailConverter.class); + private static final Log logger = LogFactory.getLog(ThumbnailConverter.class); @Override public BlobHolder convert(BlobHolder blobHolder, @@ -47,13 +50,27 @@ public class ThumbnailConverter extends IMImageUtils implements Converter { StreamSource source = ((SQLBlob) blob).getBinary() .getStreamSource(); inputFile = ((FileSource) source).getFile(); + } else if (blob instanceof StreamingBlob) { + StreamingBlob streamingBlob = ((StreamingBlob) blob); + if (!streamingBlob.isPersistent()) { + streamingBlob.persist(); + } + StreamSource source = streamingBlob.getStreamSource(); + inputFile = ((FileSource) source).getFile(); } if (inputFile == null) { - return null; + return null; // Add a log message here } CmdParameters params = new CmdParameters(); File outputFile = File.createTempFile("nuxeoImageTarget", "." + "png"); + String size = ThumbnailConstants.THUMBNAIL_DEFAULT_SIZE; + if (parameters != null) { + if (parameters.containsKey(ThumbnailConstants.THUMBNAIL_SIZE_PARAMETER_NAME)) { + size = (String) parameters.get(ThumbnailConstants.THUMBNAIL_SIZE_PARAMETER_NAME); + } + } + params.addNamedParameter(ThumbnailConstants.THUMBNAIL_SIZE_PARAMETER_NAME, size); params.addNamedParameter("inputFilePath", inputFile); params.addNamedParameter("outputFilePath", outputFile); @@ -65,6 +82,7 @@ public class ThumbnailConverter extends IMImageUtils implements Converter { Framework.trackFile(outputFile, targetBlob); return new SimpleCachableBlobHolder(targetBlob); } catch (Exception e) { + logger.trace("Could not create a thumbnail image using the Nuxeo conversion service", e); throw new ConversionException("Thumbnail conversion has failed", e); } } diff --git a/3rdparty/nuxeo/nuxeo-platform-thumbnail/src/main/java/org/collectionspace/services/nuxeo/extension/thumbnail/UpdateThumbListener.java b/3rdparty/nuxeo/nuxeo-platform-thumbnail/src/main/java/org/collectionspace/services/nuxeo/extension/thumbnail/UpdateThumbListener.java new file mode 100644 index 000000000..fa9e5f22f --- /dev/null +++ b/3rdparty/nuxeo/nuxeo-platform-thumbnail/src/main/java/org/collectionspace/services/nuxeo/extension/thumbnail/UpdateThumbListener.java @@ -0,0 +1,43 @@ +package org.collectionspace.services.nuxeo.extension.thumbnail; + +import org.nuxeo.ecm.core.api.Blob; +import org.nuxeo.ecm.core.api.ClientException; +import org.nuxeo.ecm.core.api.DocumentModel; +import org.nuxeo.ecm.core.api.blobholder.BlobHolder; +import org.nuxeo.ecm.core.api.event.DocumentEventTypes; +import org.nuxeo.ecm.core.event.Event; +import org.nuxeo.ecm.core.event.EventContext; +import org.nuxeo.ecm.core.event.EventListener; +import org.nuxeo.ecm.core.event.impl.DocumentEventContext; + +public class UpdateThumbListener implements EventListener { + + public void handleEvent(Event event) throws ClientException { + EventContext ec = event.getContext(); + if (ec instanceof DocumentEventContext) { + DocumentEventContext context = (DocumentEventContext) ec; + DocumentModel doc = context.getSourceDocument(); + if (doc.isDirty() || DocumentEventTypes.DOCUMENT_CREATED.equals(event.getName())) { + BlobHolder blobHolder = doc.getAdapter(BlobHolder.class); + if (blobHolder != null) { + Blob blob = blobHolder.getBlob(); + if (blob != null) { + try { + AddThumbnailUnrestricted runner = new AddThumbnailUnrestricted( + context.getCoreSession(), doc, blobHolder); + runner.runUnrestricted(); + return; // Exit + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + // No Blob anymore, remove the facet + if (doc.hasFacet(ThumbnailConstants.THUMBNAIL_FACET)) { + doc.removeFacet(ThumbnailConstants.THUMBNAIL_FACET); + context.getCoreSession().saveDocument(doc); + } + } + } + } +} diff --git a/3rdparty/nuxeo/nuxeo-server/5.5-HF07/bundles/nuxeo-runtime-launcher-5.5.0-HF07.jar b/3rdparty/nuxeo/nuxeo-server/5.5-HF07/bundles/nuxeo-runtime-launcher-5.5.0-HF07.jar new file mode 100644 index 000000000..5e1e3b21e Binary files /dev/null and b/3rdparty/nuxeo/nuxeo-server/5.5-HF07/bundles/nuxeo-runtime-launcher-5.5.0-HF07.jar differ diff --git a/3rdparty/nuxeo/pom.xml b/3rdparty/nuxeo/pom.xml index 7e1c2a73d..3ac17551a 100644 --- a/3rdparty/nuxeo/pom.xml +++ b/3rdparty/nuxeo/pom.xml @@ -1,36 +1,37 @@ - - - - - org.collectionspace.services - org.collectionspace.services.3rdparty - 2.6-SNAPSHOT - - - 4.0.0 - org.collectionspace.services - org.collectionspace.services.3rdparty.nuxeo - pom - services.3rdparty.nuxeo - - - nuxeo-platform-collectionspace - nuxeo-platform-quote-api - nuxeo-platform-quote - - - - - org.osgi - org.osgi.core - 4.1.0 - - - - org.jboss.remoting - jboss-remoting - provided - - - - + + + + + org.collectionspace.services + org.collectionspace.services.3rdparty + 2.6-SNAPSHOT + + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.3rdparty.nuxeo + pom + services.3rdparty.nuxeo + + + nuxeo-platform-collectionspace + nuxeo-platform-quote-api + nuxeo-platform-quote + nuxeo-platform-thumbnail + + + + + org.osgi + org.osgi.core + 4.1.0 + + + + org.jboss.remoting + jboss-remoting + provided + + + + \ No newline at end of file diff --git a/services/blob/client/src/test/resources/blobs/01-03-09_1546.jpg b/services/blob/client/src/test/resources/blobs/01-03-09_1546.jpg deleted file mode 100644 index 15b559c91..000000000 Binary files a/services/blob/client/src/test/resources/blobs/01-03-09_1546.jpg and /dev/null differ diff --git a/services/blob/client/src/test/resources/blobs/Copy of 01-03-09_1546 b/services/blob/client/src/test/resources/blobs/Copy of 01-03-09_1546 deleted file mode 100644 index 15b559c91..000000000 Binary files a/services/blob/client/src/test/resources/blobs/Copy of 01-03-09_1546 and /dev/null differ diff --git a/services/blob/client/src/test/resources/blobs/MavenCheatSheet_EL4J.pdf b/services/blob/client/src/test/resources/blobs/MavenCheatSheet_EL4J.pdf deleted file mode 100644 index 1383b92fa..000000000 Binary files a/services/blob/client/src/test/resources/blobs/MavenCheatSheet_EL4J.pdf and /dev/null differ diff --git a/services/common/pom.xml b/services/common/pom.xml index 5b3123691..de16bbbfa 100644 --- a/services/common/pom.xml +++ b/services/common/pom.xml @@ -18,6 +18,11 @@ org.collectionspace.services.config ${project.version} + + org.collectionspace.services + org.collectionspace.services.3rdparty.nuxeo.thumbnail + ${project.version} + org.collectionspace.services org.collectionspace.services.common-api diff --git a/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoImageUtils.java b/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoImageUtils.java index ff9b10ee6..c1826caed 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoImageUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoImageUtils.java @@ -107,6 +107,7 @@ import org.collectionspace.services.blob.MeasuredPartGroupList; //import org.collectionspace.services.blob.BlobsCommonList.BlobListItem; import org.collectionspace.services.jaxb.BlobJAXBSchema; import org.collectionspace.services.nuxeo.client.java.CommonList; +import org.collectionspace.services.nuxeo.extension.thumbnail.ThumbnailConstants; import org.collectionspace.services.common.blob.BlobOutput; import org.collectionspace.services.config.service.ListResultField; @@ -398,6 +399,29 @@ public class NuxeoImageUtils { if (measuredPartGroupList != null) { result.setMeasuredPartGroupList(measuredPartGroupList); } + + // Check to see if a thumbnail preview was created by Nuxeo + if (documentModel.hasFacet(ThumbnailConstants.THUMBNAIL_FACET)) { + String errorMsg = null; + String thumbnailName = null; + try { + thumbnailName = (String)documentModel.getProperty(ThumbnailConstants.THUMBNAIL_SCHEMA_NAME, + ThumbnailConstants.THUMBNAIL_FILENAME_PROPERTY_NAME); + Blob thumbnailBlob = (Blob)documentModel.getProperty(ThumbnailConstants.THUMBNAIL_SCHEMA_NAME, + ThumbnailConstants.THUMBNAIL_PROPERTY_NAME); + } catch (ClientException e) { + errorMsg = "Could not extract the name of the thumbnail preview image file."; + if (logger.isTraceEnabled()) { + logger.trace(errorMsg, e); + } + } + + if (errorMsg == null) { + logger.info("A thumbnail preview was created for this document blob: " + thumbnailName); + } else { + logger.warn(errorMsg); + } + } } return result;