]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-5497: Add code to rename files that Nuxeo does not like and hand that file...
authorRichard Millet <remillet@berkeley.edu>
Wed, 13 Feb 2013 05:12:59 +0000 (21:12 -0800)
committerRichard Millet <remillet@berkeley.edu>
Wed, 13 Feb 2013 05:12:59 +0000 (21:12 -0800)
services/blob/service/src/main/java/org/collectionspace/services/blob/BlobResource.java
services/common/src/main/java/org/collectionspace/services/common/FileUtils.java
services/common/src/main/java/org/collectionspace/services/common/blob/BlobInput.java
services/common/src/main/java/org/collectionspace/services/common/imaging/nuxeo/NuxeoBlobUtils.java

index 407515ca61cd90130f59aab24a3c0e356412ed45..576d3bf8dd463f9364b6d0e8e2ff206a5699f08d 100644 (file)
@@ -280,7 +280,7 @@ public class BlobResource extends ResourceBase {
     /*
      * Publish the blob content.
      */
-    @GET
+    @POST
     @Path("{csid}/content/publish")
     public Response publishBlobContent(
                @Context ResourceMap resourceMap,
@@ -303,7 +303,7 @@ public class BlobResource extends ResourceBase {
        return result;
     }
     
-    @GET
+    @POST
     @Path("{csid}/derivatives/{derivativeTerm}/content/publish")
     public Response publishDerivativeContent(
                @Context ResourceMap resourceMap,
index 529308d52791a460f3b128a0e67b4290d8446107..9e45b83867bdb7b4711c27a810aea2c181286a3a 100644 (file)
@@ -29,7 +29,6 @@ import javax.servlet.http.HttpServletRequest;
 import java.io.*;\r
 import java.util.Iterator;\r
 import java.util.List;\r
-import java.util.Map;\r
 import java.util.UUID;\r
 \r
 //import java.io.IOException;\r
@@ -67,6 +66,14 @@ public class FileUtils {
        public static final String DEFAULT_BLOB_NAME = "blob";\r
        private static final String FILE_FORM_FIELD = "file";\r
        \r
+       /*\r
+        * Creates a copy of the srcFile to a temp file\r
+        */\r
+       static public File createTmpFile(File srcFile, String prefix) throws Exception {\r
+               File result = createTmpFile(new FileInputStream(srcFile), prefix);\r
+               return result;\r
+       }\r
+       \r
        /**\r
         * Creates the tmp file.\r
         *\r
index 446db9ea08e005bef2e4c07953bc7e445e062cb4..ca7807313d7e53685812be710bae1a6f29f78f99 100644 (file)
@@ -10,14 +10,11 @@ import org.slf4j.LoggerFactory;
 \r
 import javax.servlet.http.HttpServletRequest;\r
 \r
-//import org.collectionspace.services.blob.BlobsCommonList; \r
-//import org.collectionspace.services.jaxb.AbstractCommonList;\r
 import org.collectionspace.services.nuxeo.client.java.CommonList;\r
-//import org.collectionspace.services.blob.nuxeo.BlobDocumentModelHandler;\r
-//import org.collectionspace.services.common.FileUtils;\r
 import org.collectionspace.services.common.Download;\r
 import org.collectionspace.services.common.document.DocumentException;\r
-import org.slf4j.LoggerFactory;\r
+import org.collectionspace.services.common.imaging.nuxeo.NuxeoBlobUtils;\r
+\r
 import org.apache.commons.io.FileUtils;\r
 \r
 public class BlobInput {\r
@@ -28,6 +25,7 @@ public class BlobInput {
        private File blobFile = null;\r
        private String blobUri = null;\r
        private String blobMimeType = null;\r
+       private String originalFileName = null;\r
        \r
        private String derivativeTerm;\r
        private boolean derivativeListRequested = false;\r
@@ -53,6 +51,42 @@ public class BlobInput {
                this.blobUri = blobUri;\r
        }\r
        \r
+       /*\r
+        * Save the original file name in case we rename it because of illegal Nuxeo file name characters\r
+        */\r
+       private void setBlobFileName(String fileName) throws Exception {\r
+               String sanitizedResult = NuxeoBlobUtils.getSanizitedFilename(fileName);\r
+               if (fileName.equals(sanitizedResult) == true) {\r
+                       originalFileName = null; //\r
+               } else {\r
+                       originalFileName = fileName;\r
+               }\r
+       }\r
+       \r
+       public String getBlobFilename() throws Exception {\r
+               String result = null;\r
+               \r
+               if (originalFileName != null && originalFileName.trim().isEmpty() == false) {\r
+                       result = originalFileName;\r
+               } else {\r
+                       File theBlobFile = this.getBlobFile();\r
+                       if (theBlobFile != null) {\r
+                               result = theBlobFile.getName();\r
+                       }\r
+               }\r
+               \r
+               //\r
+               // Add a log warning if the blob file name fails Nuxeo's file name restrictions.\r
+               //\r
+               String sanitizedResult = NuxeoBlobUtils.getSanizitedFilename(result);\r
+               if (result.equals(sanitizedResult) == false) {\r
+                       logger.warn(String.format("The file name '%s' contains characters that Nuxeo deems illegal.",\r
+                                       result));\r
+               }               \r
+               \r
+               return result;\r
+       }\r
+       \r
        /*\r
         * Getters and Setters\r
         */\r
@@ -76,8 +110,12 @@ public class BlobInput {
                return blobFile;\r
        }\r
 \r
-       public void setBlobFile(File blobFile) {\r
+       public void setBlobFile(File blobFile) throws Exception {\r
                this.blobFile = blobFile;\r
+               if (blobFile != null) {\r
+                       String fileName = blobFile.getName();\r
+                       setBlobFileName(fileName);\r
+               }\r
        }\r
 \r
        public String getBlobUri() {\r
@@ -135,7 +173,7 @@ public class BlobInput {
        // FIXME: REM - The callers of this method are sending us a multipart form-data post, so why\r
        // are we also receiving the blobUri?\r
        //\r
-       public void createBlobFile(HttpServletRequest req, String blobUri) {\r
+       public void createBlobFile(HttpServletRequest req, String blobUri) throws Exception {\r
        File tmpFile = org.collectionspace.services.common.FileUtils.createTmpFile(req);\r
        this.setBlobFile(tmpFile);\r
        this.setBlobUri(blobUri);\r
@@ -147,11 +185,15 @@ public class BlobInput {
 \r
                if (blobUrl.getProtocol().equalsIgnoreCase("http")) {\r
                        Download fetchedFile = new Download(blobUrl);\r
-                       logger.debug("Starting blob download into temp file:" + fetchedFile.getFilePath());\r
+                       if (logger.isDebugEnabled() == true) {\r
+                               logger.debug("Starting blob download into temp file:" + fetchedFile.getFilePath());\r
+                       }\r
                        while (fetchedFile.getStatus() == Download.DOWNLOADING) {\r
                                // Do nothing while we wait for the file to download\r
                        }\r
-                       logger.debug("Finished blob download into temp file: " + fetchedFile.getFilePath());\r
+                       if (logger.isDebugEnabled() == true) {\r
+                               logger.debug("Finished blob download into temp file: " + fetchedFile.getFilePath());\r
+                       }\r
                        \r
                        int status = fetchedFile.getStatus();\r
                        if (status == Download.COMPLETE) {\r
index 12acd2d8eb95667174addd9de5c344bc79ecebf1..613ff631a9d00599be8a4a06c54dfd5e29e4ed2d 100644 (file)
@@ -63,25 +63,28 @@ import org.nuxeo.ecm.core.repository.RepositoryDescriptor;
 import org.nuxeo.ecm.core.repository.RepositoryManager;\r
 \r
 import org.nuxeo.ecm.core.repository.RepositoryService;\r
-//import org.nuxeo.runtime.model.ComponentManager;\r
-//import org.nuxeo.runtime.model.impl.ComponentManagerImpl;\r
-//import org.nuxeo.ecm.core.api.ejb.DocumentManagerBean;\r
-//import org.nuxeo.ecm.core.storage.sql.RepositoryImpl;\r
-//import org.nuxeo.ecm.core.storage.sql.Repository;\r
-import org.nuxeo.ecm.core.storage.sql.Binary;\r
 import org.nuxeo.ecm.core.storage.sql.BinaryManager;\r
 import org.nuxeo.ecm.core.storage.sql.DefaultBinaryManager;\r
+\r
+/*\r
+ * Keep these commented out import statements as reminders of Nuxeo's blob management\r
+import org.nuxeo.runtime.model.ComponentManager;\r
+import org.nuxeo.runtime.model.impl.ComponentManagerImpl;\r
+import org.nuxeo.ecm.core.api.ejb.DocumentManagerBean;\r
+import org.nuxeo.ecm.core.storage.sql.RepositoryImpl;\r
+import org.nuxeo.ecm.core.storage.sql.Repository;\r
+import org.nuxeo.ecm.core.storage.sql.Binary;\r
 import org.nuxeo.ecm.core.storage.sql.RepositoryImpl;\r
 import org.nuxeo.ecm.core.storage.sql.RepositoryResolver;\r
 import org.nuxeo.ecm.core.storage.sql.coremodel.SQLBlob;\r
 import org.nuxeo.ecm.core.storage.sql.coremodel.SQLRepository;\r
-//import org.nuxeo.ecm.core.storage.sql.RepositoryDescriptor;\r
+import org.nuxeo.ecm.core.storage.sql.RepositoryDescriptor;\r
+import org.nuxeo.ecm.core.api.DocumentResolver;\r
+*/\r
 \r
-//import org.nuxeo.ecm.core.api.DocumentResolver;\r
 import org.nuxeo.ecm.core.api.IdRef;\r
 import org.nuxeo.ecm.core.api.blobholder.BlobHolder;\r
 import org.nuxeo.ecm.core.api.blobholder.DocumentBlobHolder;\r
-import org.nuxeo.ecm.core.api.impl.DocumentModelImpl;\r
 import org.nuxeo.ecm.core.api.impl.blob.FileBlob;\r
 import org.nuxeo.ecm.core.api.impl.blob.InputStreamBlob;\r
 import org.nuxeo.ecm.core.api.impl.blob.StreamingBlob;\r
@@ -90,13 +93,10 @@ import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
 import org.nuxeo.ecm.core.api.repository.Repository;\r
 import org.nuxeo.ecm.core.api.Blob;\r
 import org.nuxeo.ecm.core.api.ClientException;\r
-import org.nuxeo.ecm.core.api.CoreSession;\r
 import org.nuxeo.ecm.core.api.DocumentModel;\r
 import org.nuxeo.ecm.core.api.DocumentRef;\r
 import org.nuxeo.ecm.core.event.EventServiceAdmin;\r
-import org.nuxeo.ecm.core.event.impl.EventListenerList;\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
@@ -106,27 +106,24 @@ import org.slf4j.LoggerFactory;
 \r
 import org.collectionspace.services.client.PoxPayloadIn;\r
 import org.collectionspace.services.client.PoxPayloadOut;\r
+import org.collectionspace.services.common.FileUtils;\r
 import org.collectionspace.services.common.ServiceMain;\r
 import org.collectionspace.services.common.blob.BlobInput;\r
 import org.collectionspace.services.common.context.ServiceContext;\r
-import org.collectionspace.services.common.document.DocumentException;\r
 import org.collectionspace.services.common.document.TransactionException;\r
 import org.collectionspace.services.common.repository.RepositoryClient;\r
 import org.collectionspace.services.common.api.GregorianCalendarDateTimeUtils;\r
+import org.collectionspace.services.common.blob.BlobOutput;\r
 import org.collectionspace.services.blob.BlobsCommon;\r
 import org.collectionspace.services.blob.DimensionSubGroup;\r
 import org.collectionspace.services.blob.DimensionSubGroupList;\r
 import org.collectionspace.services.blob.MeasuredPartGroup;\r
 import org.collectionspace.services.blob.MeasuredPartGroupList;\r
-//import org.collectionspace.services.blob.BlobsCommonList;\r
-//import org.collectionspace.services.blob.BlobsCommonList.BlobListItem;\r
 import org.collectionspace.services.jaxb.BlobJAXBSchema;\r
 import org.collectionspace.services.nuxeo.client.java.CommonList;\r
 import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl;\r
 import org.collectionspace.services.nuxeo.extension.thumbnail.ThumbnailConstants;\r
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;\r
-import org.collectionspace.services.common.blob.BlobOutput;\r
-\r
 import org.collectionspace.services.config.service.ListResultField;\r
 \r
 \r
@@ -139,6 +136,12 @@ public class NuxeoBlobUtils {
        private static final Logger logger = LoggerFactory\r
                        .getLogger(NuxeoBlobUtils.class);\r
 \r
+       //\r
+       // File name constants\r
+       //\r
+    private static final String NUXEO_FILENAME_BAD_CHARS = "[^a-zA-Z_0-9-.%:/\\ ]";\r
+    private static final String NUXEO_FILENAME_VALID_STRING = "[a-zA-Z_0-9-.%:/\\ ]+";\r
+\r
        public static final String DOCUMENT_PLACEHOLDER_IMAGE = "documentImage.jpg";\r
        public static final String DOCUMENT_MISSING_PLACEHOLDER_IMAGE = "documentImageMissing.jpg";\r
        public static final String MIME_JPEG = "image/jpeg";\r
@@ -180,7 +183,6 @@ public class NuxeoBlobUtils {
        public static final String SCHEMA_IMAGE_METADATA = "image_metadata";\r
 \r
        private static final int THUMB_SIZE_HEIGHT = 100;\r
-\r
        private static final int THUMB_SIZE_WIDTH = 75;\r
 \r
        // static DefaultBinaryManager binaryManager = new DefaultBinaryManager();\r
@@ -262,6 +264,35 @@ public class NuxeoBlobUtils {
 \r
                return item;\r
        }\r
+       \r
+       static public String getSanizitedFilename(File srcFile) throws Exception {\r
+               return getSanizitedFilename(srcFile.getName());\r
+       }\r
+       \r
+       /*\r
+        * Valid Nuxeo file names are a subset of *nix and Windows filenames, so we need to check.\r
+        */\r
+       static public String getSanizitedFilename(String fileName) throws Exception {\r
+               String result = fileName;\r
+               \r
+               if (fileName != null && fileName.matches(NUXEO_FILENAME_VALID_STRING) == false) {\r
+                       String fixedString = fileName.replaceAll(NUXEO_FILENAME_BAD_CHARS, "_");  // Replace "bad" chars with underscore character\r
+                       if (fixedString.matches(NUXEO_FILENAME_VALID_STRING) == true) {\r
+                               result = fixedString;\r
+                       } else {\r
+                               String errMsg = String.format("\tSorry, the sanizited string '%s' is still bad.", fixedString);\r
+                               throw new Exception(errMsg);\r
+                       }\r
+               }\r
+               \r
+               if (result != null && logger.isDebugEnabled() == true) {\r
+                       if (result.equals(fileName) == false) {\r
+                               logger.debug(String.format("The file name '%s' was sanizitized to '%s'.", fileName, result));\r
+                       }\r
+               }\r
+\r
+               return result;\r
+       }\r
 \r
        static public CommonList getBlobDerivatives(RepositoryInstance repoSession,\r
                        String repositoryId, List<ListResultField> resultsFields, String uri)\r
@@ -717,11 +748,8 @@ public class NuxeoBlobUtils {
                return blob;\r
        }\r
 \r
-       private static Blob createNuxeoFileBasedBlob(File file) {\r
-               Blob result = null;\r
-\r
-               result = new FileBlob(file);\r
-               return result;\r
+       private static Blob createNuxeoFileBasedBlob(File file) throws Exception {\r
+               return new FileBlob(file);\r
        }\r
 \r
        /**\r
@@ -960,22 +988,45 @@ public class NuxeoBlobUtils {
                        boolean useNuxeoAdaptors) throws Exception {\r
                BlobsCommon result = null;\r
 \r
+               File originalFile = blobInput.getBlobFile();\r
+               File targetFile = originalFile;\r
                try {\r
-                       File blobFile = blobInput.getBlobFile();\r
                        // We'll store the blob inside the workspace directory of the calling service\r
                        String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();\r
                        DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);\r
                        DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);\r
+                       //\r
+                       // If the original file's name contains "illegal" characters, then we create a copy of the file to give Nuxeo.\r
+                       //\r
+                       String sanitizedName = NuxeoBlobUtils.getSanizitedFilename(originalFile);\r
+                       if (sanitizedName.equals(originalFile.getName()) == false) {\r
+                               targetFile = FileUtils.createTmpFile(originalFile, sanitizedName);\r
+                               if (logger.isDebugEnabled() == true) {\r
+                                       logger.debug(String.format("The file '%s''s name has characters that Nuxeo can't deal with.  Rather than renaming the file, we created a new temp file at '%s'",\r
+                                                       originalFile.getName(), targetFile.getAbsolutePath()));\r
+                               }\r
+                       }                       \r
                        \r
                        result = createBlobInRepository(repoSession,\r
                                        wspaceDoc,\r
                                        purgeOriginal,\r
-                                       blobFile, \r
+                                       targetFile, \r
                                        null, // MIME type\r
                                        useNuxeoAdaptors);\r
+                       //\r
+                       // Make sure we're using the original file name in our BlobsCommon instance.  If the original file's name\r
+                       // contained illegal characters, then we created and handed a copy of the file to Nuxeo.  We don't want the\r
+                       // copy's file name stored in the BlobsCommon instance, we want the original file name instead.\r
+                       //\r
+                       if (targetFile.equals(originalFile) == false) {\r
+                               result.setName(originalFile.getName());\r
+                       }\r
+                       \r
                } catch (Exception e) {\r
-                       logger.error("Could not create image blob", e);\r
+                       logger.error("Could not create image blob.", e);\r
                        throw e;\r
+               } finally {\r
+                       \r
                }\r
 \r
                return result;\r
@@ -1019,8 +1070,6 @@ public class NuxeoBlobUtils {
                BlobsCommon result = null;\r
 \r
                try {\r
-                       // Blob fileBlob = createStreamingBlob(blobFile, blobFile.getName(),\r
-                       // mimeType);\r
                        Blob fileBlob = createNuxeoFileBasedBlob(file);\r
                        \r
                        DocumentModel documentModel = createDocumentFromBlob(\r