From: remillet Date: Thu, 2 Mar 2017 23:29:52 +0000 (-0800) Subject: CSPACE-7081: Code now dynamically querying Nuxeo for picture views -aka, derivative... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=0d917d95da33e826f6ec78c079a525fe7779f317;p=tmp%2Fjakarta-migration.git CSPACE-7081: Code now dynamically querying Nuxeo for picture views -aka, derivative terms/names. --- diff --git a/services/blob/service/src/main/java/org/collectionspace/services/blob/nuxeo/BlobDocumentModelHandler.java b/services/blob/service/src/main/java/org/collectionspace/services/blob/nuxeo/BlobDocumentModelHandler.java index 3026248b2..a9475b49a 100644 --- a/services/blob/service/src/main/java/org/collectionspace/services/blob/nuxeo/BlobDocumentModelHandler.java +++ b/services/blob/service/src/main/java/org/collectionspace/services/blob/nuxeo/BlobDocumentModelHandler.java @@ -49,6 +49,7 @@ import org.slf4j.LoggerFactory; import java.util.List; import java.util.Map; +import java.util.Set; import javax.ws.rs.core.MultivaluedMap; diff --git a/services/common/src/main/java/org/collectionspace/services/common/blob/BlobInput.java b/services/common/src/main/java/org/collectionspace/services/common/blob/BlobInput.java index dc9e24889..2d81e3cd8 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/blob/BlobInput.java +++ b/services/common/src/main/java/org/collectionspace/services/common/blob/BlobInput.java @@ -22,6 +22,7 @@ public class BlobInput { private final static String FILE_ACCESS_ERROR = "The following file is either missing or cannot be read: "; private final static String URL_DOWNLOAD_FAILED = "Could not download file from the following URL: "; + private boolean isTemporaryFile = false; private String blobCsid = null; private File blobFile = null; private String blobUri = null; @@ -176,6 +177,7 @@ public class BlobInput { // public void createBlobFile(HttpServletRequest req, String blobUri) throws Exception { File tmpFile = org.collectionspace.services.common.FileUtilities.createTmpFile(req); + this.setIsTemporaryFile(true); this.setBlobFile(tmpFile); this.setBlobUri(blobUri); } @@ -209,6 +211,7 @@ public class BlobInput { int status = fetchedFile.getStatus(); if (status == Download.COMPLETE) { theBlobFile = fetchedFile.getFile(); + setIsTemporaryFile(true); // setting to true ensures the file will get cleanup (removed) when we're done with it } else { String msg = URL_DOWNLOAD_FAILED + theBlobUri; logger.error(msg); @@ -224,6 +227,7 @@ public class BlobInput { } else { throw new MalformedURLException("Could not create a blob file from: " + blobUrl); } + this.setBlobFile(theBlobFile); this.setBlobUri(blobUri); } @@ -234,7 +238,15 @@ public class BlobInput { public void setMimeType(String mimeType) { this.blobMimeType = mimeType; - } + } + + public void setIsTemporaryFile(boolean flag) { + this.isTemporaryFile = flag; + } + + public boolean isTemporaryFile() { + return this.isTemporaryFile; + } } diff --git a/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoBlobUtils.java b/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoBlobUtils.java index 03dbf84fd..0202ab13b 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoBlobUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoBlobUtils.java @@ -33,9 +33,13 @@ import java.io.InputStream; import java.io.Serializable; import java.math.BigDecimal; import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.nuxeo.runtime.api.Framework; import org.nuxeo.ecm.platform.picture.api.ImageInfo; @@ -55,11 +59,15 @@ import org.nuxeo.ecm.core.api.IdRef; import org.nuxeo.ecm.core.api.blobholder.BlobHolder; import org.nuxeo.ecm.core.api.blobholder.DocumentBlobHolder; import org.nuxeo.ecm.core.api.impl.blob.FileBlob; +import org.nuxeo.ecm.core.api.model.Property; 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.DocumentRef; +import org.nuxeo.ecm.core.api.PropertyException; import org.nuxeo.ecm.core.api.VersioningOption; +import org.nuxeo.ecm.core.blob.BlobManager; +import org.nuxeo.ecm.core.blob.BlobProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.commons.io.IOUtils; @@ -69,6 +77,8 @@ import org.collectionspace.services.common.FileUtilities; import org.collectionspace.services.common.ServiceMain; import org.collectionspace.services.common.blob.BlobInput; import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.document.DocumentException; +import org.collectionspace.services.common.document.DocumentNotFoundException; import org.collectionspace.services.common.document.TransactionException; import org.collectionspace.services.common.repository.RepositoryClient; import org.collectionspace.services.common.api.CommonAPI; @@ -87,14 +97,35 @@ import org.collectionspace.services.nuxeo.extension.thumbnail.ThumbnailConstants import org.collectionspace.services.nuxeo.util.NuxeoUtils; import org.collectionspace.services.config.service.ListResultField; +/** + * Use Nuxeo's FileBlob class to create a temporary file that Nuxeo manages. + * @author remillet + * + */ +class CSpaceFileBlob extends FileBlob { + /** + * + */ + private static final long serialVersionUID = 1L; + + public CSpaceFileBlob(File file, boolean isTempFile) { + super(file); + this.isTemporary = isTempFile; // if set to "true", Nuxeo will delete this file once it is finished with it + } +} + /** * The Class NuxeoBlobUtils. */ public class NuxeoBlobUtils { - + /** The Constant logger. */ private static final Logger logger = LoggerFactory .getLogger(NuxeoBlobUtils.class); + + private static final String VIEWS_PROPERTY = "picture:views"; + private static final String TITLE_PROPERTY = "title"; + private static final String FILENAME_PROPERTY = "filename"; // // A maximum byte size for the byte array used to hold an image. Images larger than this will @@ -197,31 +228,23 @@ public class NuxeoBlobUtils { return strBuffer.toString(); } - // FIXME: REM - This needs to be configuration-bases and NOT hard coded! - // FIXME: REM - Use MultiviewPicture adapter to get some of this information static private String getDerivativeUri(String uri, String derivativeName) { - String result = DERIVATIVE_UNKNOWN; - - if (derivativeName.startsWith(DERIVATIVE_ORIGINAL_TAG) == true) { - result = DERIVATIVE_ORIGINAL; - } else if (derivativeName.startsWith(DERIVATIVE_ORIGINAL_JPEG_TAG) == true) { - result = DERIVATIVE_ORIGINAL_JPEG; - } else if (derivativeName.startsWith(DERIVATIVE_MEDIUM_TAG) == true) { - result = DERIVATIVE_MEDIUM; - } else if (derivativeName.startsWith(DERIVATIVE_SMALL_TAG) == true) { - result = DERIVATIVE_SMALL; - } else if (derivativeName.startsWith(DERIVATIVE_THUMBNAIL_TAG) == true) { - result = DERIVATIVE_THUMBNAIL; - } - - return uri + result + "/" + BlobInput.URI_CONTENT_PATH; + return uri + derivativeName + "/" + BlobInput.URI_CONTENT_PATH; } static private HashMap createBlobListItem(Blob blob, - String uri) { + String uri, + String derivativeName) { HashMap item = new HashMap(); - String value = blob.getEncoding(); + String value = getDerivativeUri(uri, derivativeName); + if (!value.trim().isEmpty()) { + item.put(BlobJAXBSchema.uri, value); + } else { + item.put(BlobJAXBSchema.uri, getDerivativeUri(uri, DERIVATIVE_UNKNOWN)); + } + + value = blob.getEncoding(); if (value != null && !value.trim().isEmpty()) { item.put(BlobJAXBSchema.encoding, value); } @@ -237,10 +260,6 @@ public class NuxeoBlobUtils { if (value != null && !value.trim().isEmpty()) { item.put(BlobJAXBSchema.name, value); } - value = getDerivativeUri(uri, blob.getFilename()); - if (value != null && !value.trim().isEmpty()) { - item.put(BlobJAXBSchema.uri, value); - } return item; } @@ -274,6 +293,48 @@ public class NuxeoBlobUtils { return result; } + static private CommonList handleGenericBlobs(DocumentBlobHolder docBlobHolder, + CoreSessionInterface repoSession, + String repositoryId, + CommonList commonList, + String uri) { + List docBlobs = docBlobHolder.getBlobs(); + // List blobListItems = result.getBlobListItem(); + HashMap item = null; + for (Blob blob : docBlobs) { + if (blob != null) { + item = createBlobListItem(blob, uri, blob.getDigest()); + if (item != null) { + commonList.addItem(item); + } + } + } + + return commonList; + } + + static private CommonList handlePictureViewBlobs(PictureBlobHolder pictureBlobHolder, + CoreSessionInterface repoSession, + String repositoryId, + CommonList commonList, + String uri) { + Set derivativeNameList = NuxeoBlobUtils.getPictureViewNameSet(repoSession, repositoryId); + for (String viewName : derivativeNameList) { + Blob blob = pictureBlobHolder.getBlob(viewName); + if (blob != null) { + HashMap item = createBlobListItem(blob, uri, viewName); + if (item != null) { + commonList.addItem(item); + } + } else { + String msg = String.format("Could not get blob view '%s' for Nuxeo picuture document ID='%s'.", + viewName, repositoryId); + } + } + + return commonList; + } + static public CommonList getBlobDerivatives(CoreSessionInterface repoSession, String repositoryId, List resultsFields, String uri) throws Exception { @@ -288,20 +349,14 @@ public class NuxeoBlobUtils { } commonList.setFieldsReturned(fields); - IdRef documentRef = new IdRef(repositoryId); - DocumentModel documentModel = repoSession.getDocument(documentRef); - DocumentBlobHolder docBlobHolder = (DocumentBlobHolder) documentModel - .getAdapter(BlobHolder.class); - List docBlobs = docBlobHolder.getBlobs(); - // List blobListItems = result.getBlobListItem(); - HashMap item = null; - for (Blob blob : docBlobs) { - if (blob != null) { - item = createBlobListItem(blob, uri); - commonList.addItem(item); - } + DocumentModel documentModel = repoSession.getDocument(new IdRef(repositoryId)); + DocumentBlobHolder docBlobHolder = (DocumentBlobHolder) documentModel.getAdapter(BlobHolder.class); + if (docBlobHolder instanceof PictureBlobHolder) { + commonList = handlePictureViewBlobs((PictureBlobHolder)docBlobHolder, repoSession, repositoryId, commonList, uri); + } else { + commonList = handleGenericBlobs((PictureBlobHolder)docBlobHolder, repoSession, repositoryId, commonList, uri); } - + return commonList; } @@ -419,12 +474,12 @@ public class NuxeoBlobUtils { return bigdec; } - static private BlobsCommon createBlobsCommon(DocumentModel documentModel, + static private BlobsCommon createBlobsCommon(ServiceContext ctx, DocumentModel documentModel, Blob nuxeoBlob) { - return createBlobsCommon(documentModel, nuxeoBlob, false); + return createBlobsCommon(ctx, documentModel, nuxeoBlob, false); } - static private BlobsCommon createBlobsCommon(DocumentModel documentModel, + static private BlobsCommon createBlobsCommon(ServiceContext ctx, DocumentModel documentModel, Blob nuxeoBlob, Boolean getContentFlag) { BlobsCommon result = new BlobsCommon(); @@ -433,6 +488,18 @@ public class NuxeoBlobUtils { result.setName(nuxeoBlob.getFilename()); result.setLength(Long.toString(nuxeoBlob.getLength())); result.setRepositoryId(documentModel.getId()); + // set the blob's digest value + String digest = nuxeoBlob.getDigest(); + if (digest == null) { + try { + BlobManager blobManager = Framework.getService(BlobManager.class); + BlobProvider bp = blobManager.getBlobProvider(ctx.getRepositoryName()); + digest = bp.getBinaryManager().getBinary(nuxeoBlob).getDigest(); + } catch (Exception e) { + logger.warn(String.format("Could not compute digest value for uploaded media '%s'.", nuxeoBlob.getFilename())); + } + } + result.setDigest(digest); // // If getContentFlag is true then we're being asked for the blob's content, so we don't @@ -509,8 +576,15 @@ public class NuxeoBlobUtils { return typeService; } - private static Blob createNuxeoFileBasedBlob(File file) throws Exception { - return new FileBlob(file); + /** + * Create a temporary Nuxeo FileBlob instance for processing. Nuxeo will clean this up for us. + * + * @param file + * @return + * @throws Exception + */ + private static Blob createFileBlob(File file, boolean isTemporary) throws Exception { + return new CSpaceFileBlob(file, isTemporary); } /** @@ -653,7 +727,7 @@ public class NuxeoBlobUtils { false, blobName, useNuxeoAdaptors); - result = createBlobsCommon(documentModel, inputStreamBlob); // Now create the metadata about the Nuxeo blob document + result = createBlobsCommon(ctx, documentModel, inputStreamBlob); // Now create the metadata about the Nuxeo blob document } catch (Exception e) { result = null; logger.error("Could not create new Nuxeo blob document.", e); //FIXME: REM - This should probably be re-throwing the exception? @@ -705,10 +779,12 @@ public class NuxeoBlobUtils { } } - result = createBlobInRepository(repoSession, + result = createBlobInRepository(ctx, + repoSession, wspaceDoc, purgeOriginal, - targetFile, + targetFile, + blobInput.isTemporaryFile(), null, // MIME type useNuxeoAdaptors); // @@ -766,16 +842,18 @@ public class NuxeoBlobUtils { * the mime type * @return the string */ - static private BlobsCommon createBlobInRepository(CoreSessionInterface nuxeoSession, + static private BlobsCommon createBlobInRepository(ServiceContext ctx, + CoreSessionInterface nuxeoSession, DocumentModel blobLocation, boolean purgeOriginal, File file, + boolean isFileTemporary, String mimeType, boolean useNuxeoAdaptors) { BlobsCommon result = null; try { - Blob fileBlob = createNuxeoFileBasedBlob(file); + Blob fileBlob = createFileBlob(file, isFileTemporary); DocumentModel documentModel = createDocumentFromBlob( nuxeoSession, fileBlob, blobLocation.getPathAsString(), @@ -783,7 +861,7 @@ public class NuxeoBlobUtils { file.getName(), useNuxeoAdaptors); - result = createBlobsCommon(documentModel, fileBlob); // Now create our metadata resource document + result = createBlobsCommon(ctx, documentModel, fileBlob); // Now create our metadata resource document // If the requester wants us to generate only derivatives, we need to purge/clear the original image file if (purgeOriginal == true && isPurgeAllowed(documentModel) == true) { @@ -876,7 +954,7 @@ public class NuxeoBlobUtils { static public BlobOutput getBlobOutput(ServiceContext ctx, RepositoryClient repositoryClient, String repositoryId, - StringBuffer outMimeType) throws TransactionException { + StringBuffer outMimeType) throws TransactionException, DocumentNotFoundException { BlobOutput result = null; boolean repoSessionCleanup = false; @@ -893,6 +971,12 @@ public class NuxeoBlobUtils { String mimeType = blobsCommon.getMimeType(); outMimeType.append(mimeType); } + } catch (DocumentException e) { + if (logger.isDebugEnabled()) { + logger.debug(e.getMessage(), e); + } else { + logger.error(e.getMessage()); + } } finally { if (repoSessionCleanup == true) { releaseRepositorySession(ctx, repositoryClient, repoSession); @@ -936,6 +1020,21 @@ public class NuxeoBlobUtils { return result; } + static public Set getPictureViewNameSet(CoreSessionInterface repoSession, String repositoryId) throws PropertyException { + Set result = null; + + DocumentModel docModel = repoSession.getDocument(new IdRef(repositoryId)); + Collection views = docModel.getProperty(VIEWS_PROPERTY).getChildren(); + if (views != null) { + result = new HashSet(); + for (Property property : views) { + result.add((String)property.getValue(TITLE_PROPERTY)); + } + } + + return result; + } + /** * Gets the image. * @@ -946,13 +1045,14 @@ public class NuxeoBlobUtils { * @param derivativeTerm * the derivative term * @return the image + * @throws DocumentNotFoundException */ static public BlobOutput getBlobOutput(ServiceContext ctx, CoreSessionInterface repoSession, String repositoryId, String derivativeTerm, Boolean getContentFlag, - StringBuffer outMimeType) { + StringBuffer outMimeType) throws DocumentNotFoundException { BlobOutput result = new BlobOutput(); boolean isNonImageDerivative = false; @@ -974,6 +1074,12 @@ public class NuxeoBlobUtils { PictureBlobHolder pictureBlobHolder = (PictureBlobHolder) docBlobHolder; if (derivativeTerm != null) { docBlob = pictureBlobHolder.getBlob(derivativeTerm); + if (docBlob == null) { + String msg = String.format("Could not find derivative named '%s' for image/picture named '%s' Nuxeo Picture ID='%s'", + derivativeTerm, documentModel.getName(), repositoryId); + logger.error(msg); + throw new DocumentNotFoundException(msg); + } // Nuxeo derivatives are all JPEG outMimeType.append(MIME_JPEG); // All Nuxeo image derivatives are JPEG images. } else { @@ -986,10 +1092,16 @@ public class NuxeoBlobUtils { } } - if (logger.isWarnEnabled()) { - if (docBlob == null) { - String msg = String.format("Could not retrieve document blob for Nuxeo document ID = '%s' CSID = '%s'", - repositoryId, NuxeoUtils.getCsid(documentModel)); + if (docBlob == null && logger.isWarnEnabled()) { + String msg = String.format("Could not retrieve document blob from Nuxeo document ID='%s' type='%s' name='%s'", + repositoryId, documentModel.getType(), documentModel.getName()); + + if (docBlob == null && docBlobHolder instanceof PictureBlobHolder && derivativeTerm != null) { + msg = String.format("Could not retrieve image blob for derivative '%s' of Picture document with Nuxeo ID='%s' and name='%s'", + derivativeTerm, repositoryId, documentModel.getName()); + } + + if (msg != null) { logger.warn(msg); } } @@ -999,7 +1111,7 @@ public class NuxeoBlobUtils { // and an InputStream with the bits if the 'getContentFlag' is // set. // - BlobsCommon blobsCommon = createBlobsCommon(documentModel, docBlob, getContentFlag); + BlobsCommon blobsCommon = createBlobsCommon(ctx, documentModel, docBlob, getContentFlag); result.setBlobsCommon(blobsCommon); if (getContentFlag == true) { InputStream remoteStream = null; @@ -1052,6 +1164,8 @@ public class NuxeoBlobUtils { // result.setBlobInputStream(bufferedInputStream); result.setBlobInputStream(remoteStream); } + } catch (DocumentNotFoundException d) { + throw d; } catch (Exception e) { if (logger.isErrorEnabled() == true) { logger.error(e.getMessage(), e); diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelHandler.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelHandler.java index 52675c71a..af44a6cfc 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelHandler.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/DocumentModelHandler.java @@ -47,6 +47,7 @@ import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.document.AbstractMultipartDocumentHandlerImpl; import org.collectionspace.services.common.document.DocumentException; import org.collectionspace.services.common.document.DocumentFilter; +import org.collectionspace.services.common.document.DocumentNotFoundException; import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.document.DocumentWrapperImpl; import org.collectionspace.services.nuxeo.util.NuxeoUtils; @@ -61,7 +62,6 @@ import org.collectionspace.services.lifecycle.StateList; import org.collectionspace.services.lifecycle.TransitionDef; import org.collectionspace.services.lifecycle.TransitionDefList; import org.collectionspace.services.lifecycle.TransitionList; - import org.nuxeo.ecm.core.NXCore; import org.nuxeo.ecm.core.api.ClientException; import org.nuxeo.ecm.core.api.DocumentModel; @@ -69,7 +69,6 @@ import org.nuxeo.ecm.core.api.DocumentModelList; import org.nuxeo.ecm.core.api.model.PropertyException; import org.nuxeo.ecm.core.lifecycle.LifeCycle; import org.nuxeo.ecm.core.lifecycle.LifeCycleService; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -185,7 +184,7 @@ public abstract class DocumentModelHandler @Override public void handleGet(DocumentWrapper wrapDoc) throws Exception { - extractAllParts(wrapDoc); + extractAllParts(wrapDoc); } @Override diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryClientImpl.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryClientImpl.java index 32c7979b9..4a5ae318b 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryClientImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryClientImpl.java @@ -376,6 +376,9 @@ public class RepositoryClientImpl implements RepositoryClient