]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-5386: Adding support for File documents.
authorRichard Millet <remillet@berkeley.edu>
Mon, 9 Jul 2012 22:24:41 +0000 (15:24 -0700)
committerRichard Millet <remillet@berkeley.edu>
Mon, 9 Jul 2012 22:24:41 +0000 (15:24 -0700)
services/blob/3rdparty/nuxeo-platform-cs-blob/src/main/resources/OSGI-INF/ecm-types-contrib.xml
services/blob/service/src/main/java/org/collectionspace/services/blob/BlobResource.java
services/blob/service/src/main/java/org/collectionspace/services/blob/nuxeo/BlobDocumentModelHandler.java
services/common/src/main/java/org/collectionspace/services/common/blob/BlobInput.java
services/common/src/main/java/org/collectionspace/services/common/blob/BlobUtil.java
services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoImageUtils.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java

index f591e76731dd3b45bc909f870ccfe65ab0e39c10..80bb5673ecc63bb0b01f96842dc2e75bc51a58dd 100644 (file)
@@ -13,6 +13,8 @@
       </layouts>        
     </type>
 
+       <!-- We may not need to declare that Folder's accept Blob and Picture instances
+               since we only store these inside Workspace folders -->
     <type id="Folder" coretype="Folder">
       <subtypes>
         <type>Picture</type>
@@ -24,6 +26,7 @@
       <subtypes>
         <type>Picture</type>
         <type>Blob</type>
+               <type>File</type>
       </subtypes>
     </type>
 
index 645c5976f8e651124a00231a1e0c8775c10849fa..21819006d6cf51063749c5c4d66456c0d669a0bc 100644 (file)
@@ -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<PoxPayloadIn, PoxPayloadOut> 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) {
index b1ac28b3a4666ef352df911ef035d228ead58617..6e48cfdeb13edc986968cffd458ce6c663bfd9e2 100644 (file)
@@ -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<BlobsCommon> {
        }
        
        private void extractMetadata(String nuxeoImageID, String metadataLabel) {               
-               PayloadOutputPart result = null;
         Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
         ObjectPartType partMeta = partsMetaMap.get(metadataLabel);
 
@@ -140,7 +135,7 @@ extends DocHandlerBase<BlobsCommon> {
        @Override
        public void extractAllParts(DocumentWrapper<DocumentModel> wrapDoc)
                        throws Exception {
-               ServiceContext ctx = this.getServiceContext();
+               ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
                BlobInput blobInput = BlobUtil.getBlobInput(ctx);
                RepositoryInstance repoSession = this.getRepositorySession();
                DocumentModel docModel = wrapDoc.getWrappedObject();
@@ -195,16 +190,18 @@ extends DocHandlerBase<BlobsCommon> {
 
        @Override
        public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception {
-               ServiceContext ctx = this.getServiceContext();
-               BlobInput blobInput = BlobUtil.getBlobInput(ctx);
-               if (blobInput.getBlobFile() != null) {                  
+               ServiceContext<PoxPayloadIn, PoxPayloadOut> 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<BlobsCommon> {
                        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);
index 83fa54ba653df1d7d49d374db1c40e9c6499f27c..ba7613170e900cbbecf0af2b07d1edd6be6deda7 100644 (file)
@@ -160,11 +160,11 @@ public class BlobInput {
                        theBlobFile = FileUtils.toFile(blobUrl);\r
                        if (theBlobFile.exists() == false || theBlobFile.canRead() == false) {\r
                                String msg = FILE_ACCESS_ERROR + theBlobFile.getAbsolutePath();\r
-                               logger.equals(msg);\r
+                               logger.error(msg);\r
                                throw new DocumentException(msg);\r
                        }\r
                } else {\r
-                       \r
+                       throw new MalformedURLException("Could not create a blob file from: " + blobUrl);\r
                }\r
        this.setBlobFile(theBlobFile);\r
        this.setBlobUri(blobUri);\r
index 57c67baa0f1ae718829e6b3e095a3cb24a955469..bd45a77845c905b4f5dfaa26f201382a981ff12f 100644 (file)
@@ -3,14 +3,14 @@ package org.collectionspace.services.common.blob;
 import org.collectionspace.services.client.PoxPayloadIn;\r
 import org.collectionspace.services.client.PoxPayloadOut;\r
 import org.collectionspace.services.common.context.ServiceContext;\r
-import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;\r
-import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;\r
+//import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;\r
+//import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 \r
 public class BlobUtil {\r
-       //FIXME: REM - We should have a class/interface in common that has constant defs for the names of all the services.\r
-       public static String BLOB_RESOURCE_NAME = "blobs";\r
+       //\r
+       //\r
        private static final Logger logger = LoggerFactory.getLogger(BlobUtil.class);\r
        \r
     public static BlobInput getBlobInput(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx) {\r
index 1f5c3a4b4dbffa5dd30ddfe2e47311f72f220df9..bc97cc837c8f055813aff9fabfd33fa7e4fd4dfc 100644 (file)
@@ -80,6 +80,7 @@ import org.nuxeo.ecm.core.api.ClientException;
 import org.nuxeo.ecm.core.api.DocumentModel;\r
 import org.nuxeo.ecm.core.api.DocumentRef;\r
 \r
+import org.nuxeo.ecm.core.schema.DocumentType;\r
 import org.nuxeo.ecm.core.schema.SchemaManager;\r
 import org.nuxeo.ecm.core.schema.types.Schema;\r
 \r
@@ -171,6 +172,9 @@ public class NuxeoImageUtils {
                // empty constructor\r
        }\r
 \r
+       /*\r
+        * Use this for debugging Nuxeo's PictureView class\r
+        */\r
        private static String toStringPictureView(PictureView pictureView) {\r
                StringBuffer strBuffer = new StringBuffer();\r
                strBuffer.append("Description: " + pictureView.getDescription() + '\n');\r
@@ -376,6 +380,7 @@ public class NuxeoImageUtils {
                        DocumentModel documentModel, Blob blob) {\r
                DefaultBinaryManager binaryManager = null;\r
                RepositoryDescriptor descriptor = null;\r
+               File file = null;\r
 \r
                try {\r
                        RepositoryService repositoryService1 = (RepositoryService) Framework\r
@@ -386,6 +391,7 @@ public class NuxeoImageUtils {
                                        .getRepositoryManager();\r
                        descriptor = repositoryManager.getDescriptor(repositoryName);\r
 \r
+// Keep this code around for future work/enhancements                  \r
 //                     binaryManager = new DefaultBinaryManager();\r
 //\r
 //                     File storageDir = binaryManager.getStorageDir();\r
@@ -397,26 +403,28 @@ public class NuxeoImageUtils {
                        e.printStackTrace();\r
                }\r
 \r
-               try {\r
-                       binaryManager.initialize(SQLRepository.getDescriptor(descriptor));\r
-               } catch (IOException e) {\r
-                       // TODO Auto-generated catch block\r
-                       e.printStackTrace();\r
-               } catch (Exception e) {\r
-                       // TODO Auto-generated catch block\r
-                       e.printStackTrace();\r
-               }\r
-\r
-               File storageDir = binaryManager.getStorageDir();\r
-               // SQLBlob blob = (SQLBlob)\r
-               // documentModel.getPropertyValue("schema:blobField");\r
-               File file = binaryManager.getFileForDigest(blob.getDigest(), false);\r
+// Keep this code around for future work/enhancements\r
+//             try {\r
+//                     binaryManager.initialize(SQLRepository.getDescriptor(descriptor));\r
+//             } catch (IOException e) {\r
+//                     // TODO Auto-generated catch block\r
+//                     e.printStackTrace();\r
+//             } catch (Exception e) {\r
+//                     // TODO Auto-generated catch block\r
+//                     e.printStackTrace();\r
+//             }\r
+\r
+// Keep this code around for future work/enhancements\r
+//             File storageDir = binaryManager.getStorageDir();\r
+//             SQLBlob blob = (SQLBlob)\r
+//             documentModel.getPropertyValue("schema:blobField");\r
+//             File file = binaryManager.getFileForDigest(blob.getDigest(), false);\r
 \r
                return file;\r
        }\r
 \r
        /**\r
-        * Returns a schema, given the name of a schema.\r
+        * Returns a schema, given the name of a schema.  Possibly usefule in the future\r
         * \r
         * @param schemaName\r
         *            a schema name.\r
@@ -435,7 +443,7 @@ public class NuxeoImageUtils {
        }\r
 \r
        /**\r
-        * Gets the blob.\r
+        * Gets the blob.  Not in use now, but might be useful in the future.\r
         * \r
         * @param nuxeoSession\r
         *            the nuxeo session\r
@@ -461,7 +469,7 @@ public class NuxeoImageUtils {
        }\r
 \r
        /**\r
-        * Gets the type service.\r
+        * Gets the type service.  Not in use, but please keep for future reference\r
         * \r
         * @return the type service\r
         * @throws ClientException\r
@@ -506,7 +514,7 @@ public class NuxeoImageUtils {
        }\r
 \r
        /**\r
-        * Creates the serializable blob.\r
+        * Creates the serializable blob.  We may need this code, do not remove.\r
         * \r
         * @param fileInputStream\r
         *            the file input stream\r
@@ -613,7 +621,7 @@ public class NuxeoImageUtils {
                return blob;\r
        }\r
 \r
-       private static Blob createFileBlob(File file) {\r
+       private static Blob createNuxeoFileBasedBlob(File file) {\r
                Blob result = null;\r
 \r
                result = new FileBlob(file);\r
@@ -672,9 +680,10 @@ public class NuxeoImageUtils {
         * @param filePath\r
         *            the file path\r
         * @return the string\r
+        * @throws Exception \r
         */\r
-       public static BlobsCommon createPicture(ServiceContext ctx,\r
-                       RepositoryInstance repoSession, BlobInput blobInput) {\r
+       public static BlobsCommon createBlobInRepository(ServiceContext ctx,\r
+                       RepositoryInstance repoSession, BlobInput blobInput) throws Exception {\r
                BlobsCommon result = null;\r
 \r
                try {\r
@@ -682,17 +691,20 @@ public class NuxeoImageUtils {
                        String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();\r
                        DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);\r
                        DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);\r
-\r
-                       // FileInputStream inputStream = new FileInputStream(blobFile);\r
-                       // //FIXME: REM - With an embedded Nuxeo server, we may no longer\r
-                       // need to pass in a stream but instead just pass them the File\r
-                       // instance\r
-                       // if (inputStream != null) {\r
-                       result = createImage(repoSession, wspaceDoc,\r
-                       /* inputStream, */blobFile, null);\r
-                       // }\r
+                       \r
+            if (logger.isDebugEnabled()) {\r
+                   for (String facet : wspaceDoc.getFacets()) {\r
+                       logger.debug("Facet: " + facet);\r
+                   }\r
+                   for (String docType : wspaceDoc.getDocumentType().getChildrenTypes()) {\r
+                       logger.debug("Child type: " + docType);\r
+                   }\r
+            }                  \r
+\r
+                       result = createBlobInRepository(repoSession, wspaceDoc, blobFile, null /*mime type*/);\r
                } catch (Exception e) {\r
-                       logger.error("Could not create image blob", e); //FIXME: REM - We should probably be re-throwing the exception?\r
+                       logger.error("Could not create image blob", e);\r
+                       throw e;\r
                }\r
 \r
                return result;\r
@@ -713,7 +725,7 @@ public class NuxeoImageUtils {
         *            the mime type\r
         * @return the string\r
         */\r
-       static public BlobsCommon createImage(RepositoryInstance nuxeoSession,\r
+       static public BlobsCommon createBlobInRepository(RepositoryInstance nuxeoSession,\r
                        DocumentModel blobLocation,\r
                        // InputStream file,\r
                        File file, String mimeType) {\r
@@ -722,22 +734,21 @@ public class NuxeoImageUtils {
                try {\r
                        // Blob fileBlob = createStreamingBlob(blobFile, blobFile.getName(),\r
                        // mimeType);\r
-                       Blob fileBlob = createFileBlob(file);\r
+                       Blob fileBlob = createNuxeoFileBasedBlob(file);\r
                        String digestAlgorithm = getFileManagerService()\r
-                                       .getDigestAlgorithm(); // Need some way on initializing the\r
-                                                                                       // FileManager with a call.\r
+                                       .getDigestAlgorithm(); // Only call this because we seem to need some way of initializing Nuxeo's FileManager with a call.\r
                        \r
-                       logger.debug("Start --> Calling Nuxeo to create an image blob."); // See Nuxeo's DefaultPictureAdapter class for details\r
+                       logger.debug("Start --> Starting call to Nuxeo to create the blob document."); // For example, see Nuxeo's DefaultPictureAdapter class for details\r
                        DocumentModel documentModel = getFileManagerService()\r
                                        .createDocumentFromBlob(nuxeoSession, fileBlob,\r
                                                        blobLocation.getPathAsString(), true,\r
                                                        file.getName());\r
-                       logger.debug("Stop --> Calling Nuxeo to create an image blob.");\r
+                       logger.debug("Stop --> Finished calling Nuxeo to create the blob document.");\r
                        \r
-                       result = createBlobsCommon(documentModel, fileBlob);\r
+                       result = createBlobsCommon(documentModel, fileBlob); // Now create our metadata resource document\r
                } catch (Exception e) {\r
                        result = null;\r
-                       logger.error("Could not create new image blob", e); //FIXME: REM - This should probably be re-throwing the exception?\r
+                       logger.error("Could not create new Nuxeo blob document.", e); //FIXME: REM - This should probably be re-throwing the exception?\r
                }\r
 \r
                return result;\r
@@ -776,31 +787,23 @@ public class NuxeoImageUtils {
         * @return the image\r
         */\r
        static public BlobOutput getBlobOutput(ServiceContext ctx,\r
-                       RepositoryInstance repoSession, String repositoryId,\r
-                       String derivativeTerm, Boolean getContentFlag) {\r
+                       RepositoryInstance repoSession,\r
+                       String repositoryId,\r
+                       String derivativeTerm,\r
+                       Boolean getContentFlag) {\r
                BlobOutput result = new BlobOutput();\r
 \r
                if (repositoryId != null && repositoryId.isEmpty() == false)\r
                        try {\r
                                IdRef documentRef = new IdRef(repositoryId);\r
-                               DocumentModel documentModel = repoSession\r
-                                               .getDocument(documentRef);\r
+                               DocumentModel documentModel = repoSession.getDocument(documentRef);\r
 \r
                                Blob docBlob = null;\r
                                DocumentBlobHolder docBlobHolder = (DocumentBlobHolder) documentModel\r
                                                .getAdapter(BlobHolder.class);\r
-                               if (docBlobHolder instanceof PictureBlobHolder) { // if it is a\r
-                                                                                                                                       // PictureDocument\r
-                                                                                                                                       // then it\r
-                                                                                                                                       // has these\r
-                                                                                                                                       // Nuxeo\r
-                                                                                                                                       // schemas:\r
-                                                                                                                                       // [dublincore,\r
-                                                                                                                                       // uid,\r
-                                                                                                                                       // picture,\r
-                                                                                                                                       // iptc,\r
-                                                                                                                                       // common,\r
-                                                                                                                                       // image_metadata]\r
+                               if (docBlobHolder instanceof PictureBlobHolder) {\r
+                                       // if it is a PictureDocument then it has these\r
+                                       // Nuxeo schemas: [dublincore, uid, picture, iptc, common, image_metadata]\r
                                        //\r
                                        // Need to add the "MultiviewPictureAdapter" support here to\r
                                        // get the view data, see above.\r
@@ -816,24 +819,18 @@ public class NuxeoImageUtils {
                                }\r
 \r
                                //\r
-                               // Create the result instance that will contain the blob\r
-                               // metadata\r
+                               // Create the result instance that will contain the blob metadata\r
                                // and an InputStream with the bits if the 'getContentFlag' is\r
-                               // set\r
+                               // set.\r
                                //\r
-                               BlobsCommon blobsCommon = createBlobsCommon(documentModel,\r
-                                               docBlob);\r
+                               BlobsCommon blobsCommon = createBlobsCommon(documentModel, docBlob);\r
                                result.setBlobsCommon(blobsCommon);\r
                                if (getContentFlag == true) {\r
                                        InputStream remoteStream = docBlob.getStream();\r
                                        BufferedInputStream bufferedInputStream = new BufferedInputStream(\r
-                                                       remoteStream); // FIXME: REM - To improve\r
-                                                                                       // performance, try\r
-                                                                                       // BufferedInputStream(InputStream\r
-                                                                                       // in, int size)\r
-                                       result.setBlobInputStream(bufferedInputStream); // the input\r
-                                                                                                                                       // stream of\r
-                                                                                                                                       // blob bits\r
+                                                       remoteStream);  // FIXME: REM - To improve performance, try\r
+                                                                                       // BufferedInputStream(InputStream in, int size)\r
+                                       result.setBlobInputStream(bufferedInputStream);\r
                                }\r
 \r
                        } catch (Exception e) {\r
index 99d590ee7f5ed3624854fc87af9356072fa14bd0..833b4685fb372c4d2d34c987543e602dace31d9f 100644 (file)
@@ -1257,7 +1257,14 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
         String workspaceId = null;
         try {
             repoSession = getRepositorySession(null);
-            DocumentModel parentDoc = getWorkspacesRoot(repoSession, domainName);            
+            DocumentModel parentDoc = getWorkspacesRoot(repoSession, domainName);
+            
+            if (logger.isTraceEnabled()) {
+                   for (String facet : parentDoc.getFacets()) {
+                       logger.debug("Facet: " + facet);
+                   }
+            }
+            
             DocumentModel doc = repoSession.createDocumentModel(parentDoc.getPathAsString(),
                     workspaceName, NuxeoUtils.WORKSPACE_DOCUMENT_TYPE);
             doc.setPropertyValue("dc:title", workspaceName);