From: Richard Millet Date: Mon, 9 Jul 2012 22:24:41 +0000 (-0700) Subject: CSPACE-5386: Adding support for File documents. X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=4a3a3451e1466a84cb3eb26f5ae7908f496f0a5c;p=tmp%2Fjakarta-migration.git CSPACE-5386: Adding support for File documents. --- diff --git a/services/blob/3rdparty/nuxeo-platform-cs-blob/src/main/resources/OSGI-INF/ecm-types-contrib.xml b/services/blob/3rdparty/nuxeo-platform-cs-blob/src/main/resources/OSGI-INF/ecm-types-contrib.xml index f591e7673..80bb5673e 100644 --- a/services/blob/3rdparty/nuxeo-platform-cs-blob/src/main/resources/OSGI-INF/ecm-types-contrib.xml +++ b/services/blob/3rdparty/nuxeo-platform-cs-blob/src/main/resources/OSGI-INF/ecm-types-contrib.xml @@ -13,6 +13,8 @@ + Picture @@ -24,6 +26,7 @@ Picture Blob + File 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 645c5976f..21819006d 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 @@ -65,7 +65,7 @@ public class BlobResource extends ResourceBase { @Override public String getServiceName(){ - return BlobUtil.BLOB_RESOURCE_NAME; + return BlobClient.SERVICE_NAME; } @Override @@ -217,12 +217,13 @@ public class BlobResource extends ResourceBase { String blobUri = queryParams.getFirst(BlobClient.BLOB_URI_PARAM); try { - if (blobUri != null) { + if (blobUri != null) { // If we were passed a URI than try to create a blob from it ServiceContext ctx = createServiceContext(); - BlobInput blobInput = BlobUtil.getBlobInput(ctx); - blobInput.createBlobFile(blobUri); - response = this.create(null, ctx); + BlobInput blobInput = BlobUtil.getBlobInput(ctx); // We're going to store a reference to the blob in the current context for the doc handler to use later + blobInput.createBlobFile(blobUri); // This call creates a temp blob file and points our blobInput to it + response = this.create(null, ctx); // Now finish the create. We'll ignore the xmlPayload since we'll derive it from the blob itself } else { + // No URI was passed in so we're just going to create a blob record response = super.create(resourceMap, ui, xmlPayload); } } catch (Exception e) { 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 b1ac28b3a..6e48cfdeb 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 @@ -26,7 +26,6 @@ package org.collectionspace.services.blob.nuxeo; import org.collectionspace.services.blob.BlobsCommon; import org.collectionspace.services.nuxeo.client.java.DocHandlerBase; import org.collectionspace.services.client.BlobClient; -import org.collectionspace.services.client.PayloadInputPart; import org.collectionspace.services.client.PayloadOutputPart; import org.collectionspace.services.client.PoxPayloadIn; import org.collectionspace.services.client.PoxPayloadOut; @@ -39,7 +38,6 @@ import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.imaging.nuxeo.NuxeoImageUtils; import org.collectionspace.services.config.service.ListResultField; import org.collectionspace.services.config.service.ObjectPartType; -import org.collectionspace.services.jaxb.AbstractCommonList; import org.collectionspace.services.jaxb.BlobJAXBSchema; import org.collectionspace.services.nuxeo.client.java.CommonList; @@ -48,12 +46,10 @@ import org.nuxeo.ecm.core.api.ClientException; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.IdRef; import org.nuxeo.ecm.core.api.repository.RepositoryInstance; -import org.nuxeo.ecm.core.schema.types.Schema; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -113,7 +109,6 @@ extends DocHandlerBase { } private void extractMetadata(String nuxeoImageID, String metadataLabel) { - PayloadOutputPart result = null; Map partsMetaMap = getServiceContext().getPartsMetadata(); ObjectPartType partMeta = partsMetaMap.get(metadataLabel); @@ -140,7 +135,7 @@ extends DocHandlerBase { @Override public void extractAllParts(DocumentWrapper wrapDoc) throws Exception { - ServiceContext ctx = this.getServiceContext(); + ServiceContext ctx = this.getServiceContext(); BlobInput blobInput = BlobUtil.getBlobInput(ctx); RepositoryInstance repoSession = this.getRepositorySession(); DocumentModel docModel = wrapDoc.getWrappedObject(); @@ -195,16 +190,18 @@ extends DocHandlerBase { @Override public void fillAllParts(DocumentWrapper wrapDoc, Action action) throws Exception { - ServiceContext ctx = this.getServiceContext(); - BlobInput blobInput = BlobUtil.getBlobInput(ctx); - if (blobInput.getBlobFile() != null) { + ServiceContext 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) { // // If blobInput has a file then we just received a multipart/form-data file post or a URI query parameter // DocumentModel documentModel = wrapDoc.getWrappedObject(); RepositoryInstance repoSession = this.getRepositorySession(); - BlobsCommon blobsCommon = NuxeoImageUtils.createPicture(ctx, repoSession, blobInput); - PoxPayloadIn input = (PoxPayloadIn)ctx.getInput(); + BlobsCommon blobsCommon = NuxeoImageUtils.createBlobInRepository(ctx, repoSession, blobInput); + 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 @@ -216,9 +213,13 @@ extends DocHandlerBase { output.addPart(commonPart); input = new PoxPayloadIn(output.toXML()); ctx.setInput(input); - } -// this.setCommonPartProperties(documentModel, blobsCommon); - blobInput.setBlobCsid(documentModel.getName()); //Assumption here is that the documentModel "name" field is storing a CSID + } 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); 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 83fa54ba6..ba7613170 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 @@ -160,11 +160,11 @@ public class BlobInput { theBlobFile = FileUtils.toFile(blobUrl); if (theBlobFile.exists() == false || theBlobFile.canRead() == false) { String msg = FILE_ACCESS_ERROR + theBlobFile.getAbsolutePath(); - logger.equals(msg); + logger.error(msg); throw new DocumentException(msg); } } else { - + throw new MalformedURLException("Could not create a blob file from: " + blobUrl); } this.setBlobFile(theBlobFile); this.setBlobUri(blobUri); diff --git a/services/common/src/main/java/org/collectionspace/services/common/blob/BlobUtil.java b/services/common/src/main/java/org/collectionspace/services/common/blob/BlobUtil.java index 57c67baa0..bd45a7784 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/blob/BlobUtil.java +++ b/services/common/src/main/java/org/collectionspace/services/common/blob/BlobUtil.java @@ -3,14 +3,14 @@ package org.collectionspace.services.common.blob; import org.collectionspace.services.client.PoxPayloadIn; import org.collectionspace.services.client.PoxPayloadOut; import org.collectionspace.services.common.context.ServiceContext; -import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; -import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; +//import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; +//import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class BlobUtil { - //FIXME: REM - We should have a class/interface in common that has constant defs for the names of all the services. - public static String BLOB_RESOURCE_NAME = "blobs"; + // + // private static final Logger logger = LoggerFactory.getLogger(BlobUtil.class); public static BlobInput getBlobInput(ServiceContext ctx) { 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 1f5c3a4b4..bc97cc837 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 @@ -80,6 +80,7 @@ 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.schema.DocumentType; import org.nuxeo.ecm.core.schema.SchemaManager; import org.nuxeo.ecm.core.schema.types.Schema; @@ -171,6 +172,9 @@ public class NuxeoImageUtils { // empty constructor } + /* + * Use this for debugging Nuxeo's PictureView class + */ private static String toStringPictureView(PictureView pictureView) { StringBuffer strBuffer = new StringBuffer(); strBuffer.append("Description: " + pictureView.getDescription() + '\n'); @@ -376,6 +380,7 @@ public class NuxeoImageUtils { DocumentModel documentModel, Blob blob) { DefaultBinaryManager binaryManager = null; RepositoryDescriptor descriptor = null; + File file = null; try { RepositoryService repositoryService1 = (RepositoryService) Framework @@ -386,6 +391,7 @@ public class NuxeoImageUtils { .getRepositoryManager(); descriptor = repositoryManager.getDescriptor(repositoryName); +// Keep this code around for future work/enhancements // binaryManager = new DefaultBinaryManager(); // // File storageDir = binaryManager.getStorageDir(); @@ -397,26 +403,28 @@ public class NuxeoImageUtils { e.printStackTrace(); } - try { - binaryManager.initialize(SQLRepository.getDescriptor(descriptor)); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - File storageDir = binaryManager.getStorageDir(); - // SQLBlob blob = (SQLBlob) - // documentModel.getPropertyValue("schema:blobField"); - File file = binaryManager.getFileForDigest(blob.getDigest(), false); +// Keep this code around for future work/enhancements +// try { +// binaryManager.initialize(SQLRepository.getDescriptor(descriptor)); +// } catch (IOException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } catch (Exception e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } + +// Keep this code around for future work/enhancements +// File storageDir = binaryManager.getStorageDir(); +// SQLBlob blob = (SQLBlob) +// documentModel.getPropertyValue("schema:blobField"); +// File file = binaryManager.getFileForDigest(blob.getDigest(), false); return file; } /** - * Returns a schema, given the name of a schema. + * Returns a schema, given the name of a schema. Possibly usefule in the future * * @param schemaName * a schema name. @@ -435,7 +443,7 @@ public class NuxeoImageUtils { } /** - * Gets the blob. + * Gets the blob. Not in use now, but might be useful in the future. * * @param nuxeoSession * the nuxeo session @@ -461,7 +469,7 @@ public class NuxeoImageUtils { } /** - * Gets the type service. + * Gets the type service. Not in use, but please keep for future reference * * @return the type service * @throws ClientException @@ -506,7 +514,7 @@ public class NuxeoImageUtils { } /** - * Creates the serializable blob. + * Creates the serializable blob. We may need this code, do not remove. * * @param fileInputStream * the file input stream @@ -613,7 +621,7 @@ public class NuxeoImageUtils { return blob; } - private static Blob createFileBlob(File file) { + private static Blob createNuxeoFileBasedBlob(File file) { Blob result = null; result = new FileBlob(file); @@ -672,9 +680,10 @@ public class NuxeoImageUtils { * @param filePath * the file path * @return the string + * @throws Exception */ - public static BlobsCommon createPicture(ServiceContext ctx, - RepositoryInstance repoSession, BlobInput blobInput) { + public static BlobsCommon createBlobInRepository(ServiceContext ctx, + RepositoryInstance repoSession, BlobInput blobInput) throws Exception { BlobsCommon result = null; try { @@ -682,17 +691,20 @@ public class NuxeoImageUtils { String nuxeoWspaceId = ctx.getRepositoryWorkspaceId(); DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId); DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace); - - // FileInputStream inputStream = new FileInputStream(blobFile); - // //FIXME: REM - With an embedded Nuxeo server, we may no longer - // need to pass in a stream but instead just pass them the File - // instance - // if (inputStream != null) { - result = createImage(repoSession, wspaceDoc, - /* inputStream, */blobFile, null); - // } + + if (logger.isDebugEnabled()) { + for (String facet : wspaceDoc.getFacets()) { + logger.debug("Facet: " + facet); + } + for (String docType : wspaceDoc.getDocumentType().getChildrenTypes()) { + logger.debug("Child type: " + docType); + } + } + + result = createBlobInRepository(repoSession, wspaceDoc, blobFile, null /*mime type*/); } catch (Exception e) { - logger.error("Could not create image blob", e); //FIXME: REM - We should probably be re-throwing the exception? + logger.error("Could not create image blob", e); + throw e; } return result; @@ -713,7 +725,7 @@ public class NuxeoImageUtils { * the mime type * @return the string */ - static public BlobsCommon createImage(RepositoryInstance nuxeoSession, + static public BlobsCommon createBlobInRepository(RepositoryInstance nuxeoSession, DocumentModel blobLocation, // InputStream file, File file, String mimeType) { @@ -722,22 +734,21 @@ public class NuxeoImageUtils { try { // Blob fileBlob = createStreamingBlob(blobFile, blobFile.getName(), // mimeType); - Blob fileBlob = createFileBlob(file); + Blob fileBlob = createNuxeoFileBasedBlob(file); String digestAlgorithm = getFileManagerService() - .getDigestAlgorithm(); // Need some way on initializing the - // FileManager with a call. + .getDigestAlgorithm(); // Only call this because we seem to need some way of initializing Nuxeo's FileManager with a call. - logger.debug("Start --> Calling Nuxeo to create an image blob."); // See Nuxeo's DefaultPictureAdapter class for details + 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 --> Calling Nuxeo to create an image blob."); + logger.debug("Stop --> Finished calling Nuxeo to create the blob document."); - result = createBlobsCommon(documentModel, fileBlob); + result = createBlobsCommon(documentModel, fileBlob); // Now create our metadata resource document } catch (Exception e) { result = null; - logger.error("Could not create new image blob", e); //FIXME: REM - This should probably be re-throwing the exception? + logger.error("Could not create new Nuxeo blob document.", e); //FIXME: REM - This should probably be re-throwing the exception? } return result; @@ -776,31 +787,23 @@ public class NuxeoImageUtils { * @return the image */ static public BlobOutput getBlobOutput(ServiceContext ctx, - RepositoryInstance repoSession, String repositoryId, - String derivativeTerm, Boolean getContentFlag) { + RepositoryInstance repoSession, + String repositoryId, + String derivativeTerm, + Boolean getContentFlag) { BlobOutput result = new BlobOutput(); if (repositoryId != null && repositoryId.isEmpty() == false) try { IdRef documentRef = new IdRef(repositoryId); - DocumentModel documentModel = repoSession - .getDocument(documentRef); + DocumentModel documentModel = repoSession.getDocument(documentRef); Blob docBlob = null; DocumentBlobHolder docBlobHolder = (DocumentBlobHolder) documentModel .getAdapter(BlobHolder.class); - if (docBlobHolder instanceof PictureBlobHolder) { // if it is a - // PictureDocument - // then it - // has these - // Nuxeo - // schemas: - // [dublincore, - // uid, - // picture, - // iptc, - // common, - // image_metadata] + if (docBlobHolder instanceof PictureBlobHolder) { + // if it is a PictureDocument then it has these + // Nuxeo schemas: [dublincore, uid, picture, iptc, common, image_metadata] // // Need to add the "MultiviewPictureAdapter" support here to // get the view data, see above. @@ -816,24 +819,18 @@ public class NuxeoImageUtils { } // - // Create the result instance that will contain the blob - // metadata + // Create the result instance that will contain the blob metadata // and an InputStream with the bits if the 'getContentFlag' is - // set + // set. // - BlobsCommon blobsCommon = createBlobsCommon(documentModel, - docBlob); + BlobsCommon blobsCommon = createBlobsCommon(documentModel, docBlob); result.setBlobsCommon(blobsCommon); if (getContentFlag == true) { InputStream remoteStream = docBlob.getStream(); BufferedInputStream bufferedInputStream = new BufferedInputStream( - remoteStream); // FIXME: REM - To improve - // performance, try - // BufferedInputStream(InputStream - // in, int size) - result.setBlobInputStream(bufferedInputStream); // the input - // stream of - // blob bits + remoteStream); // FIXME: REM - To improve performance, try + // BufferedInputStream(InputStream in, int size) + result.setBlobInputStream(bufferedInputStream); } } catch (Exception e) { diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java index 99d590ee7..833b4685f 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java @@ -1257,7 +1257,14 @@ public class RepositoryJavaClientImpl implements RepositoryClient