From: Richard Millet Date: Wed, 13 Feb 2013 05:12:59 +0000 (-0800) Subject: CSPACE-5497: Add code to rename files that Nuxeo does not like and hand that file... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=071e8f7a796b31771d5204cba1edaa999b06f7c5;p=tmp%2Fjakarta-migration.git CSPACE-5497: Add code to rename files that Nuxeo does not like and hand that file to Nuxeo for blob creation. Saved the original file name in our BlobsCommon instance. --- 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 407515ca6..576d3bf8d 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 @@ -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, diff --git a/services/common/src/main/java/org/collectionspace/services/common/FileUtils.java b/services/common/src/main/java/org/collectionspace/services/common/FileUtils.java index 529308d52..9e45b8386 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/FileUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/FileUtils.java @@ -29,7 +29,6 @@ import javax.servlet.http.HttpServletRequest; import java.io.*; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.UUID; //import java.io.IOException; @@ -67,6 +66,14 @@ public class FileUtils { public static final String DEFAULT_BLOB_NAME = "blob"; private static final String FILE_FORM_FIELD = "file"; + /* + * Creates a copy of the srcFile to a temp file + */ + static public File createTmpFile(File srcFile, String prefix) throws Exception { + File result = createTmpFile(new FileInputStream(srcFile), prefix); + return result; + } + /** * Creates the tmp file. * 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 446db9ea0..ca7807313 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 @@ -10,14 +10,11 @@ import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; -//import org.collectionspace.services.blob.BlobsCommonList; -//import org.collectionspace.services.jaxb.AbstractCommonList; import org.collectionspace.services.nuxeo.client.java.CommonList; -//import org.collectionspace.services.blob.nuxeo.BlobDocumentModelHandler; -//import org.collectionspace.services.common.FileUtils; import org.collectionspace.services.common.Download; import org.collectionspace.services.common.document.DocumentException; -import org.slf4j.LoggerFactory; +import org.collectionspace.services.common.imaging.nuxeo.NuxeoBlobUtils; + import org.apache.commons.io.FileUtils; public class BlobInput { @@ -28,6 +25,7 @@ public class BlobInput { private File blobFile = null; private String blobUri = null; private String blobMimeType = null; + private String originalFileName = null; private String derivativeTerm; private boolean derivativeListRequested = false; @@ -53,6 +51,42 @@ public class BlobInput { this.blobUri = blobUri; } + /* + * Save the original file name in case we rename it because of illegal Nuxeo file name characters + */ + private void setBlobFileName(String fileName) throws Exception { + String sanitizedResult = NuxeoBlobUtils.getSanizitedFilename(fileName); + if (fileName.equals(sanitizedResult) == true) { + originalFileName = null; // + } else { + originalFileName = fileName; + } + } + + public String getBlobFilename() throws Exception { + String result = null; + + if (originalFileName != null && originalFileName.trim().isEmpty() == false) { + result = originalFileName; + } else { + File theBlobFile = this.getBlobFile(); + if (theBlobFile != null) { + result = theBlobFile.getName(); + } + } + + // + // Add a log warning if the blob file name fails Nuxeo's file name restrictions. + // + String sanitizedResult = NuxeoBlobUtils.getSanizitedFilename(result); + if (result.equals(sanitizedResult) == false) { + logger.warn(String.format("The file name '%s' contains characters that Nuxeo deems illegal.", + result)); + } + + return result; + } + /* * Getters and Setters */ @@ -76,8 +110,12 @@ public class BlobInput { return blobFile; } - public void setBlobFile(File blobFile) { + public void setBlobFile(File blobFile) throws Exception { this.blobFile = blobFile; + if (blobFile != null) { + String fileName = blobFile.getName(); + setBlobFileName(fileName); + } } public String getBlobUri() { @@ -135,7 +173,7 @@ public class BlobInput { // FIXME: REM - The callers of this method are sending us a multipart form-data post, so why // are we also receiving the blobUri? // - public void createBlobFile(HttpServletRequest req, String blobUri) { + public void createBlobFile(HttpServletRequest req, String blobUri) throws Exception { File tmpFile = org.collectionspace.services.common.FileUtils.createTmpFile(req); this.setBlobFile(tmpFile); this.setBlobUri(blobUri); @@ -147,11 +185,15 @@ public class BlobInput { if (blobUrl.getProtocol().equalsIgnoreCase("http")) { Download fetchedFile = new Download(blobUrl); - logger.debug("Starting blob download into temp file:" + fetchedFile.getFilePath()); + if (logger.isDebugEnabled() == true) { + logger.debug("Starting blob download into temp file:" + fetchedFile.getFilePath()); + } while (fetchedFile.getStatus() == Download.DOWNLOADING) { // Do nothing while we wait for the file to download } - logger.debug("Finished blob download into temp file: " + fetchedFile.getFilePath()); + if (logger.isDebugEnabled() == true) { + logger.debug("Finished blob download into temp file: " + fetchedFile.getFilePath()); + } int status = fetchedFile.getStatus(); if (status == Download.COMPLETE) { 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 12acd2d8e..613ff631a 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 @@ -63,25 +63,28 @@ import org.nuxeo.ecm.core.repository.RepositoryDescriptor; import org.nuxeo.ecm.core.repository.RepositoryManager; import org.nuxeo.ecm.core.repository.RepositoryService; -//import org.nuxeo.runtime.model.ComponentManager; -//import org.nuxeo.runtime.model.impl.ComponentManagerImpl; -//import org.nuxeo.ecm.core.api.ejb.DocumentManagerBean; -//import org.nuxeo.ecm.core.storage.sql.RepositoryImpl; -//import org.nuxeo.ecm.core.storage.sql.Repository; -import org.nuxeo.ecm.core.storage.sql.Binary; import org.nuxeo.ecm.core.storage.sql.BinaryManager; import org.nuxeo.ecm.core.storage.sql.DefaultBinaryManager; + +/* + * Keep these commented out import statements as reminders of Nuxeo's blob management +import org.nuxeo.runtime.model.ComponentManager; +import org.nuxeo.runtime.model.impl.ComponentManagerImpl; +import org.nuxeo.ecm.core.api.ejb.DocumentManagerBean; +import org.nuxeo.ecm.core.storage.sql.RepositoryImpl; +import org.nuxeo.ecm.core.storage.sql.Repository; +import org.nuxeo.ecm.core.storage.sql.Binary; import org.nuxeo.ecm.core.storage.sql.RepositoryImpl; import org.nuxeo.ecm.core.storage.sql.RepositoryResolver; import org.nuxeo.ecm.core.storage.sql.coremodel.SQLBlob; import org.nuxeo.ecm.core.storage.sql.coremodel.SQLRepository; -//import org.nuxeo.ecm.core.storage.sql.RepositoryDescriptor; +import org.nuxeo.ecm.core.storage.sql.RepositoryDescriptor; +import org.nuxeo.ecm.core.api.DocumentResolver; +*/ -//import org.nuxeo.ecm.core.api.DocumentResolver; 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.DocumentModelImpl; import org.nuxeo.ecm.core.api.impl.blob.FileBlob; import org.nuxeo.ecm.core.api.impl.blob.InputStreamBlob; import org.nuxeo.ecm.core.api.impl.blob.StreamingBlob; @@ -90,13 +93,10 @@ 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; import org.nuxeo.ecm.core.schema.types.Schema; @@ -106,27 +106,24 @@ import org.slf4j.LoggerFactory; import org.collectionspace.services.client.PoxPayloadIn; import org.collectionspace.services.client.PoxPayloadOut; +import org.collectionspace.services.common.FileUtils; 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.TransactionException; import org.collectionspace.services.common.repository.RepositoryClient; import org.collectionspace.services.common.api.GregorianCalendarDateTimeUtils; +import org.collectionspace.services.common.blob.BlobOutput; import org.collectionspace.services.blob.BlobsCommon; import org.collectionspace.services.blob.DimensionSubGroup; import org.collectionspace.services.blob.DimensionSubGroupList; import org.collectionspace.services.blob.MeasuredPartGroup; import org.collectionspace.services.blob.MeasuredPartGroupList; -//import org.collectionspace.services.blob.BlobsCommonList; -//import org.collectionspace.services.blob.BlobsCommonList.BlobListItem; import org.collectionspace.services.jaxb.BlobJAXBSchema; import org.collectionspace.services.nuxeo.client.java.CommonList; import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl; import org.collectionspace.services.nuxeo.extension.thumbnail.ThumbnailConstants; import org.collectionspace.services.nuxeo.util.NuxeoUtils; -import org.collectionspace.services.common.blob.BlobOutput; - import org.collectionspace.services.config.service.ListResultField; @@ -139,6 +136,12 @@ public class NuxeoBlobUtils { private static final Logger logger = LoggerFactory .getLogger(NuxeoBlobUtils.class); + // + // File name constants + // + private static final String NUXEO_FILENAME_BAD_CHARS = "[^a-zA-Z_0-9-.%:/\\ ]"; + private static final String NUXEO_FILENAME_VALID_STRING = "[a-zA-Z_0-9-.%:/\\ ]+"; + public static final String DOCUMENT_PLACEHOLDER_IMAGE = "documentImage.jpg"; public static final String DOCUMENT_MISSING_PLACEHOLDER_IMAGE = "documentImageMissing.jpg"; public static final String MIME_JPEG = "image/jpeg"; @@ -180,7 +183,6 @@ public class NuxeoBlobUtils { public static final String SCHEMA_IMAGE_METADATA = "image_metadata"; private static final int THUMB_SIZE_HEIGHT = 100; - private static final int THUMB_SIZE_WIDTH = 75; // static DefaultBinaryManager binaryManager = new DefaultBinaryManager(); @@ -262,6 +264,35 @@ public class NuxeoBlobUtils { return item; } + + static public String getSanizitedFilename(File srcFile) throws Exception { + return getSanizitedFilename(srcFile.getName()); + } + + /* + * Valid Nuxeo file names are a subset of *nix and Windows filenames, so we need to check. + */ + static public String getSanizitedFilename(String fileName) throws Exception { + String result = fileName; + + if (fileName != null && fileName.matches(NUXEO_FILENAME_VALID_STRING) == false) { + String fixedString = fileName.replaceAll(NUXEO_FILENAME_BAD_CHARS, "_"); // Replace "bad" chars with underscore character + if (fixedString.matches(NUXEO_FILENAME_VALID_STRING) == true) { + result = fixedString; + } else { + String errMsg = String.format("\tSorry, the sanizited string '%s' is still bad.", fixedString); + throw new Exception(errMsg); + } + } + + if (result != null && logger.isDebugEnabled() == true) { + if (result.equals(fileName) == false) { + logger.debug(String.format("The file name '%s' was sanizitized to '%s'.", fileName, result)); + } + } + + return result; + } static public CommonList getBlobDerivatives(RepositoryInstance repoSession, String repositoryId, List resultsFields, String uri) @@ -717,11 +748,8 @@ public class NuxeoBlobUtils { return blob; } - private static Blob createNuxeoFileBasedBlob(File file) { - Blob result = null; - - result = new FileBlob(file); - return result; + private static Blob createNuxeoFileBasedBlob(File file) throws Exception { + return new FileBlob(file); } /** @@ -960,22 +988,45 @@ public class NuxeoBlobUtils { boolean useNuxeoAdaptors) throws Exception { BlobsCommon result = null; + File originalFile = blobInput.getBlobFile(); + File targetFile = originalFile; 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 the original file's name contains "illegal" characters, then we create a copy of the file to give Nuxeo. + // + String sanitizedName = NuxeoBlobUtils.getSanizitedFilename(originalFile); + if (sanitizedName.equals(originalFile.getName()) == false) { + targetFile = FileUtils.createTmpFile(originalFile, sanitizedName); + if (logger.isDebugEnabled() == true) { + 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'", + originalFile.getName(), targetFile.getAbsolutePath())); + } + } result = createBlobInRepository(repoSession, wspaceDoc, purgeOriginal, - blobFile, + targetFile, null, // MIME type useNuxeoAdaptors); + // + // Make sure we're using the original file name in our BlobsCommon instance. If the original file's name + // contained illegal characters, then we created and handed a copy of the file to Nuxeo. We don't want the + // copy's file name stored in the BlobsCommon instance, we want the original file name instead. + // + if (targetFile.equals(originalFile) == false) { + result.setName(originalFile.getName()); + } + } catch (Exception e) { - logger.error("Could not create image blob", e); + logger.error("Could not create image blob.", e); throw e; + } finally { + } return result; @@ -1019,8 +1070,6 @@ public class NuxeoBlobUtils { BlobsCommon result = null; try { - // Blob fileBlob = createStreamingBlob(blobFile, blobFile.getName(), - // mimeType); Blob fileBlob = createNuxeoFileBasedBlob(file); DocumentModel documentModel = createDocumentFromBlob(