From: Richard Millet Date: Sat, 26 Jan 2013 01:05:20 +0000 (-0800) Subject: CSPACE-5564: Added support for generic Nuxeo file importer to avoid unnecessary image... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=09e78d3a65eab0106e8acd090019fe5f1de881a1;p=tmp%2Fjakarta-migration.git CSPACE-5564: Added support for generic Nuxeo file importer to avoid unnecessary image derivatives from being created during a publishing event. --- diff --git a/services/article/client/src/test/java/org/collectionspace/services/client/test/ArticleServiceTest.java b/services/article/client/src/test/java/org/collectionspace/services/client/test/ArticleServiceTest.java index 5d4cc35ff..6bdbfb363 100644 --- a/services/article/client/src/test/java/org/collectionspace/services/client/test/ArticleServiceTest.java +++ b/services/article/client/src/test/java/org/collectionspace/services/client/test/ArticleServiceTest.java @@ -23,7 +23,13 @@ package org.collectionspace.services.client.test; //import java.util.ArrayList; +import java.math.BigInteger; +import java.util.Date; + import javax.ws.rs.core.Response; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; import org.collectionspace.services.client.AbstractCommonListUtils; import org.collectionspace.services.client.CollectionSpaceClient; @@ -602,9 +608,21 @@ public class ArticleServiceTest extends ArticlesCommon articlesCommon = new ArticlesCommon(); articlesCommon.setArticleNumber(articleNumber); + articlesCommon.setArticleContentName("contentname-" + articleNumber); + articlesCommon.setArticleContentRepositoryId("42640780-82eb-4650-8a70"); + articlesCommon.setArticleContentUrl("https://github.com/collectionspace/services/blob/CSPACE-5564-REM-A/services/article/jaxb/src/main/resources/articles-common.xsd"); articlesCommon.setArticleJobId(articleJobId); articlesCommon.setArticleSource(getUTF8DataFragment()); - + try { + XMLGregorianCalendar expirationDate = + DatatypeFactory.newInstance().newXMLGregorianCalendarDate(2013, 12, 31, 0); + articlesCommon.setAccessExpirationDate(expirationDate); + } catch (DatatypeConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + articlesCommon.setAccessedCount(new BigInteger("3")); + articlesCommon.setAccessedCountLimit(new BigInteger("5")); PoxPayloadOut multipart = new PoxPayloadOut( this.getServicePathComponent()); diff --git a/services/blob/service/src/main/java/org/collectionspace/services/blob/BlobResource.java b/services/blob/service/src/main/java/org/collectionspace/services/blob/BlobResource.java index 7343a04cc..441baff01 100644 --- a/services/blob/service/src/main/java/org/collectionspace/services/blob/BlobResource.java +++ b/services/blob/service/src/main/java/org/collectionspace/services/blob/BlobResource.java @@ -24,29 +24,22 @@ package org.collectionspace.services.blob; import org.collectionspace.services.article.ArticlesCommon; -import org.collectionspace.services.client.ArticleClient; import org.collectionspace.services.client.BlobClient; +import org.collectionspace.services.client.PayloadOutputPart; +import org.collectionspace.services.client.PayloadPart; import org.collectionspace.services.client.PoxPayloadIn; import org.collectionspace.services.client.PoxPayloadOut; -import org.collectionspace.services.client.workflow.WorkflowClient; import org.collectionspace.services.common.FileUtils; import org.collectionspace.services.common.ResourceBase; import org.collectionspace.services.common.ResourceMap; -import org.collectionspace.services.common.ServiceMain; import org.collectionspace.services.common.ServiceMessages; -import org.collectionspace.services.common.article.ArticleResource; import org.collectionspace.services.common.article.ArticleUtil; import org.collectionspace.services.common.blob.BlobInput; import org.collectionspace.services.common.blob.BlobUtil; import org.collectionspace.services.common.context.ServiceContext; -import org.collectionspace.services.common.imaging.nuxeo.NuxeoBlobUtils; import org.collectionspace.services.nuxeo.client.java.CommonList; -import org.collectionspace.services.workflow.WorkflowCommon; import org.jboss.resteasy.plugins.providers.multipart.InputPart; import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput; -import org.nuxeo.ecm.core.api.DocumentModel; -import org.nuxeo.ecm.core.api.DocumentRef; -import org.nuxeo.ecm.core.api.IdRef; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; @@ -271,6 +264,17 @@ public class BlobResource extends ResourceBase { return result; } + private BlobsCommon getBlobsCommon(String csid) throws Exception { + BlobsCommon result = null; + + ServiceContext ctx = createServiceContext(); + PoxPayloadOut ppo = this.get(csid, ctx); + PayloadPart blobsCommonPart = ppo.getPart(BlobClient.SERVICE_COMMON_PART_NAME); + result = (BlobsCommon)blobsCommonPart.getBody(); + + return result; + } + /* * Publish the blob content. */ @@ -285,17 +289,43 @@ public class BlobResource extends ResourceBase { try { ctx = createServiceContext(); + + BlobsCommon blobsCommon = getBlobsCommon(csid); StringBuffer mimeType = new StringBuffer(); InputStream contentStream = getBlobContent(ctx, csid, null /*derivative term*/, mimeType /*will get set*/); result = ArticleUtil.publishToRepository((ArticlesCommon)null, resourceMap, uriInfo, - getRepositoryClient(ctx), ctx, contentStream, csid); + getRepositoryClient(ctx), ctx, contentStream, blobsCommon.getName()); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.PUT_FAILED); } return result; - } + } + + @GET + @Path("{csid}/derivatives/{derivativeTerm}/content/publish") + public Response publishDerivativeContent( + @Context ResourceMap resourceMap, + @Context UriInfo uriInfo, + @PathParam("csid") String csid, + @PathParam("derivativeTerm") String derivativeTerm) { + Response result = null; + ServiceContext ctx = null; + + try { + ctx = createServiceContext(); + StringBuffer mimeType = new StringBuffer(); + InputStream contentStream = getBlobContent(ctx, csid, derivativeTerm, mimeType); + result = ArticleUtil.publishToRepository((ArticlesCommon)null, resourceMap, uriInfo, + getRepositoryClient(ctx), ctx, contentStream, csid); + } catch (Exception e) { + throw bigReThrow(e, ServiceMessages.CREATE_FAILED); + } + + return result; + } + @GET @Path("{csid}/derivatives/{derivativeTerm}/content") public Response getDerivativeContent( 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 a99401895..9345ab91e 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 @@ -222,7 +222,7 @@ extends DocHandlerBase { DocumentModel documentModel = wrapDoc.getWrappedObject(); RepositoryInstance repoSession = this.getRepositorySession(); - BlobsCommon blobsCommon = NuxeoBlobUtils.createBlobInRepository(ctx, repoSession, blobInput, purgeOriginal); + 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(); diff --git a/services/common/src/main/java/org/collectionspace/services/common/article/ArticleUtil.java b/services/common/src/main/java/org/collectionspace/services/common/article/ArticleUtil.java index 2f3a84f0e..b03c5a6f2 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/article/ArticleUtil.java +++ b/services/common/src/main/java/org/collectionspace/services/common/article/ArticleUtil.java @@ -82,7 +82,8 @@ public class ArticleUtil { String streamName) throws TransactionException { Response result = null; - BlobsCommon blobsCommon = NuxeoBlobUtils.createBlobInRepository(parentCtx, repositoryClient, inputStream, streamName); + BlobsCommon blobsCommon = NuxeoBlobUtils.createBlobInRepository(parentCtx, repositoryClient, + inputStream, streamName, false); articlesCommon = setArticlesCommonMetadata(articlesCommon, uriInfo, parentCtx); articlesCommon.setArticleContentRepositoryId(blobsCommon.getRepositoryId()); 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 cef902c6a..12acd2d8e 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 @@ -54,6 +54,9 @@ import org.nuxeo.ecm.platform.mimetype.MimetypeDetectionException; import org.nuxeo.ecm.platform.mimetype.interfaces.MimetypeRegistry; import org.nuxeo.ecm.platform.picture.api.adapters.PictureBlobHolder; import org.nuxeo.ecm.platform.filemanager.api.FileManager; +import org.nuxeo.ecm.platform.filemanager.service.FileManagerService; +import org.nuxeo.ecm.platform.filemanager.service.extension.FileImporter; +import org.nuxeo.ecm.platform.filemanager.utils.FileManagerUtils; import org.nuxeo.ecm.platform.types.TypeManager; import org.nuxeo.ecm.core.repository.RepositoryDescriptor; @@ -87,8 +90,11 @@ import org.nuxeo.ecm.core.api.repository.RepositoryInstance; import org.nuxeo.ecm.core.api.repository.Repository; 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.DocumentRef; +import org.nuxeo.ecm.core.event.EventServiceAdmin; +import org.nuxeo.ecm.core.event.impl.EventListenerList; import org.nuxeo.ecm.core.schema.DocumentType; import org.nuxeo.ecm.core.schema.SchemaManager; @@ -98,6 +104,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; //import org.nuxeo.ecm.core.repository.jcr.testing.RepositoryOSGITestCase; +import org.collectionspace.services.client.PoxPayloadIn; +import org.collectionspace.services.client.PoxPayloadOut; import org.collectionspace.services.common.ServiceMain; import org.collectionspace.services.common.blob.BlobInput; import org.collectionspace.services.common.context.ServiceContext; @@ -538,6 +546,22 @@ public class NuxeoBlobUtils { return result; } + static private Blob checkMimeType(Blob blob, String fullname) + throws ClientException { + final String mimeType = blob.getMimeType(); + if (mimeType != null && !mimeType.equals("application/octet-stream") + && !mimeType.equals("application/octetstream")) { + return blob; + } + String filename = FileManagerUtils.fetchFileName(fullname); + try { + blob = getMimeService().updateMimetype(blob, filename); + } catch (MimetypeDetectionException e) { + throw new ClientException(e); + } + return blob; + } + /** * Gets the type service. Not in use, but please keep for future reference * @@ -547,11 +571,13 @@ public class NuxeoBlobUtils { */ private static TypeManager getTypeService() throws ClientException { TypeManager typeService = null; + try { typeService = Framework.getService(TypeManager.class); } catch (Exception e) { throw new ClientException(e); } + return typeService; } @@ -728,7 +754,49 @@ public class NuxeoBlobUtils { * @throws ClientException * the client exception */ - private static FileManager getFileManagerService() throws ClientException { + private static FileManager getFileManager() throws ClientException { + FileManager result = null; + + try { + result = Framework.getService(FileManager.class); + } catch (Exception e) { + String msg = "Unable to get Nuxeo's FileManager service."; + logger.error(msg, e); + throw new ClientException("msg", e); + } + + return result; + } + + /** + * Gets Nuxeo's file manager service. + * + * @return the file manager service + * @throws ClientException + * the client exception + */ + private static FileManagerService getFileManagerService() throws ClientException { + FileManagerService result = null; + + try { + result = (FileManagerService)getFileManager(); + } catch (Exception e) { + String msg = "Unable to get Nuxeo's FileManager service."; + logger.error(msg, e); + throw new ClientException("msg", e); + } + + return result; + } + + /** + * Gets Nuxeo's file manager service. + * + * @return the file manager service + * @throws ClientException + * the client exception + */ + private static FileManager getFileManagerServicex() throws ClientException { FileManager result = null; try { result = Framework.getService(FileManager.class); @@ -740,6 +808,18 @@ public class NuxeoBlobUtils { return result; } + private static EventServiceAdmin getEventServiceAdmin() throws ClientException { + EventServiceAdmin result = null; + try { + result = Framework.getService(EventServiceAdmin.class); + } catch (Exception e) { + String msg = "Unable to get Nuxeo's EventServiceAdmin service."; + logger.error(msg, e); + throw new ClientException("msg", e); + } + return result; + } + private static BinaryManager getBinaryManagerService() throws ClientException { BinaryManager result = null; try { @@ -770,11 +850,60 @@ public class NuxeoBlobUtils { nuxeoClient.releaseRepositorySession(ctx, repoSession); } + static private MimetypeRegistry getMimeService() throws ClientException { + MimetypeRegistry result = null; + + try { + result = Framework.getService(MimetypeRegistry.class); + } catch (Exception e) { + throw new ClientException(e); + } + + return result; + } + + private static DocumentModel createDocumentFromBlob( + RepositoryInstance repoSession, + Blob inputStreamBlob, + String blobLocation, + boolean overwrite, + String blobName, + boolean useNuxeoAdaptors) throws Exception { + DocumentModel result = null; + + if (useNuxeoAdaptors == true) { + // + // Use Nuxeo's high-level create method which looks for plugin adapters that match the MIME type. For example, + // for image blobs, Nuxeo's file manager will pick a special image plugin that will automatically generate + // image derivatives. + // + result = getFileManager().createDocumentFromBlob( + repoSession, inputStreamBlob, blobLocation, true, blobName); + } else { + // + // User Nuxeo's default file importer/adapter explicitly. This avoids specialized functionality from happening like + // image derivative creation. + // + String digestAlgorithm = getFileManager() + .getDigestAlgorithm(); // Only call this because we seem to need some way of initializing Nuxeo's FileManager with a call. + + FileManagerService fileManagerService = getFileManagerService(); + inputStreamBlob = checkMimeType(inputStreamBlob, blobName); + + FileImporter defaultFileImporter = fileManagerService.getPluginByName("DefaultFileImporter"); + result = defaultFileImporter.create( + repoSession, inputStreamBlob, blobLocation, true, blobName, getTypeService()); + } + + return result; + } + static public BlobsCommon createBlobInRepository( - ServiceContext ctx, + ServiceContext ctx, RepositoryClient repositoryClient, InputStream inputStream, - String blobName) throws TransactionException { + String blobName, + boolean useNuxeoAdaptors) throws TransactionException { BlobsCommon result = null; boolean repoSessionCleanup = false; @@ -783,25 +912,22 @@ public class NuxeoBlobUtils { repoSession = getRepositorySession(ctx, repositoryClient); repoSessionCleanup = true; } - - String nuxeoWspaceId = ctx.getRepositoryWorkspaceId(); - DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId); - + try { + // We'll store the blob inside the workspace directory of the calling service + String nuxeoWspaceId = ctx.getRepositoryWorkspaceId(); + DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId); DocumentModel blobLocation = repoSession.getDocument(nuxeoWspace); - Blob inputStreamBlob = new InputStreamBlob(inputStream); - String digestAlgorithm = getFileManagerService() - .getDigestAlgorithm(); // Only call this because we seem to need some way of initializing Nuxeo's FileManager with a call. - logger.debug("Start --> Starting call to Nuxeo to create the blob document."); // For example, see Nuxeo's DefaultPictureAdapter class for details - DocumentModel documentModel = getFileManagerService() - .createDocumentFromBlob(repoSession, inputStreamBlob, - blobLocation.getPathAsString(), true, - blobName); - logger.debug("Stop --> Finished calling Nuxeo to create the blob document."); - - result = createBlobsCommon(documentModel, inputStreamBlob); // Now create our metadata resource document - + Blob inputStreamBlob = new InputStreamBlob(inputStream); + DocumentModel documentModel = createDocumentFromBlob( + repoSession, + inputStreamBlob, + blobLocation.getPathAsString(), + true, + blobName, + useNuxeoAdaptors); + result = createBlobsCommon(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? @@ -826,28 +952,27 @@ public class NuxeoBlobUtils { * @return the string * @throws Exception */ - public static BlobsCommon createBlobInRepository(ServiceContext ctx, + public static BlobsCommon createBlobInRepository( + ServiceContext ctx, RepositoryInstance repoSession, BlobInput blobInput, - boolean purgeOriginal) throws Exception { + boolean purgeOriginal, + boolean useNuxeoAdaptors) throws Exception { BlobsCommon result = null; try { File blobFile = blobInput.getBlobFile(); + // We'll store the blob inside the workspace directory of the calling service String nuxeoWspaceId = ctx.getRepositoryWorkspaceId(); DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId); DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace); - if (logger.isTraceEnabled()) { - for (String facet : wspaceDoc.getFacets()) { - logger.trace("Facet: " + facet); - } - for (String docType : wspaceDoc.getDocumentType().getChildrenTypes()) { - logger.trace("Child type: " + docType); - } - } - - result = createBlobInRepository(repoSession, wspaceDoc, purgeOriginal, blobFile, null /*mime type*/); + result = createBlobInRepository(repoSession, + wspaceDoc, + purgeOriginal, + blobFile, + null, // MIME type + useNuxeoAdaptors); } catch (Exception e) { logger.error("Could not create image blob", e); throw e; @@ -885,26 +1010,25 @@ public class NuxeoBlobUtils { * the mime type * @return the string */ - static public BlobsCommon createBlobInRepository(RepositoryInstance nuxeoSession, + static private BlobsCommon createBlobInRepository(RepositoryInstance nuxeoSession, DocumentModel blobLocation, boolean purgeOriginal, File file, - String mimeType) { + String mimeType, + boolean useNuxeoAdaptors) { BlobsCommon result = null; try { // Blob fileBlob = createStreamingBlob(blobFile, blobFile.getName(), // mimeType); Blob fileBlob = createNuxeoFileBasedBlob(file); - String digestAlgorithm = getFileManagerService() - .getDigestAlgorithm(); // Only call this because we seem to need some way of initializing Nuxeo's FileManager with a call. - logger.debug("Start --> Starting call to Nuxeo to create the blob document."); // For example, see Nuxeo's DefaultPictureAdapter class for details - DocumentModel documentModel = getFileManagerService() - .createDocumentFromBlob(nuxeoSession, fileBlob, - blobLocation.getPathAsString(), true, - file.getName()); - logger.debug("Stop --> Finished calling Nuxeo to create the blob document."); + DocumentModel documentModel = createDocumentFromBlob( + nuxeoSession, fileBlob, + blobLocation.getPathAsString(), + true, + file.getName(), + useNuxeoAdaptors); result = createBlobsCommon(documentModel, fileBlob); // Now create our metadata resource document