From: Richard Millet Date: Fri, 10 Dec 2010 05:09:49 +0000 (+0000) Subject: CSPACE-3245: Committing final Media/Blob artifacts for v1.2 code-freeze. Full CRUD... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=f0c19d8758b79dc8b22bf52775284cf187a8aa4a;p=tmp%2Fjakarta-migration.git CSPACE-3245: Committing final Media/Blob artifacts for v1.2 code-freeze. Full CRUD+L for Media and Blob schema records and CR+L for Media and Blob binaries and derivatives. Will need to add UD for Media and Blob binaries and derivatives during another sprint. --- 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 56fd5187d..3bce784d0 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 @@ -29,8 +29,10 @@ import org.collectionspace.services.common.ResourceBase; import org.collectionspace.services.common.ServiceMain; import org.collectionspace.services.common.ServiceMessages; 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.document.DocumentHandler; +import org.collectionspace.services.blob.nuxeo.BlobDocumentModelHandler; //FIXEME: A resource class should not have a dependency on a specific DocumentHandler import org.collectionspace.services.blob.BlobsCommon; import org.collectionspace.services.blob.BlobsCommonList; @@ -64,10 +66,10 @@ import java.util.List; @Produces("multipart/mixed") public class BlobResource extends ResourceBase { - @Override + @Override public String getServiceName(){ - return "blobs"; - }; + return BlobUtil.BLOB_RESOURCE_NAME; + } @Override @@ -97,16 +99,23 @@ public class BlobResource extends ResourceBase { return (BlobsCommonList) super.search(queryParams, keywords); } - private BlobsCommonList getDerivativeList(String csid) throws Exception { + private BlobsCommonList getDerivativeList(ServiceContext ctx, + String csid) throws Exception { BlobsCommonList result = null; - ServiceContext ctx = createServiceContext(); - ctx.setProperty(BlobInput.BLOB_DERIVATIVE_LIST_KEY, Boolean.TRUE); + BlobInput blobInput = new BlobInput(); + blobInput.setDerivativeListRequested(true); + BlobUtil.setBlobInput(ctx, blobInput); + MultipartOutput response = this.get(csid, ctx); if (logger.isDebugEnabled() == true) { logger.debug(response.toString()); } - result = (BlobsCommonList)ctx.getProperty(BlobInput.BLOB_DERIVATIVE_LIST_KEY); + // + // The result of a successful get should have put the results in the + // blobInput instance + // + result = BlobUtil.getBlobInput(ctx).getDerivativeList(); return result; } @@ -116,13 +125,19 @@ public class BlobResource extends ResourceBase { try { ServiceContext ctx = createServiceContext(); - ctx.setProperty(BlobInput.BLOB_DERIVATIVE_TERM_KEY, derivativeTerm); - ctx.setProperty(BlobInput.BLOB_CONTENT_KEY, Boolean.TRUE); + BlobInput blobInput = BlobUtil.getBlobInput(ctx); + blobInput.setDerivativeTerm(derivativeTerm); + blobInput.setContentRequested(true); + MultipartOutput response = this.get(csid, ctx); if (logger.isDebugEnabled() == true) { logger.debug(response.toString()); } - result = (InputStream)ctx.getProperty(BlobInput.BLOB_CONTENT_KEY); + // + // The result of a successful get should have put the results in the + // blobInput instance + // + result = BlobUtil.getBlobInput(ctx).getContentStream(); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.CREATE_FAILED); } @@ -136,16 +151,7 @@ public class BlobResource extends ResourceBase { return result; } - - private BlobInput setBlobInput(ServiceContext ctx, - HttpServletRequest req, - String blobUri) { - File tmpFile = FileUtils.createTmpFile(req); - BlobInput blobInput = new BlobInput(tmpFile, blobUri); - ctx.setProperty(BlobInput.class.getName(), blobInput); - return blobInput; - } - + @POST @Consumes("multipart/form-data") @Produces("application/xml") @@ -154,7 +160,8 @@ public class BlobResource extends ResourceBase { Response response = null; try { ServiceContext ctx = createServiceContext(); - setBlobInput(ctx, req, blobUri); + BlobInput blobInput = BlobUtil.getBlobInput(ctx); + blobInput.createBlobFile(req, blobUri); response = this.create(null, ctx); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.CREATE_FAILED); @@ -174,27 +181,28 @@ public class BlobResource extends ResourceBase { } @GET - @Path("{csid}/derivatives/{derivative_term}/content") + @Path("{csid}/derivatives/{derivativeTerm}/content") @Produces({"image/jpeg", "image/png", "image/tiff"}) public InputStream getDerivativeContent( @PathParam("csid") String csid, - @PathParam("derivative_term") String derivative_term) { + @PathParam("derivativeTerm") String derivativeTerm) { InputStream result = null; - result = getBlobContent(csid, derivative_term); + result = getBlobContent(csid, derivativeTerm); return result; } @GET - @Path("{csid}/derivatives/{derivative_term}") + @Path("{csid}/derivatives/{derivativeTerm}") public MultipartOutput getDerivative(@PathParam("csid") String csid, - @PathParam("derivative_term") String derivative_term) { + @PathParam("derivativeTerm") String derivativeTerm) { MultipartOutput result = null; ensureCSID(csid, READ); try { ServiceContext ctx = createServiceContext(); - ctx.setProperty(BlobInput.BLOB_DERIVATIVE_TERM_KEY, derivative_term); + BlobInput blobInput = BlobUtil.getBlobInput(ctx); + blobInput.setDerivativeTerm(derivativeTerm); result = get(csid, ctx); if (result == null) { Response response = Response.status(Response.Status.NOT_FOUND).entity( @@ -218,8 +226,7 @@ public class BlobResource extends ResourceBase { ensureCSID(csid, READ); try { ServiceContext ctx = createServiceContext(); - ctx.setProperty(BlobInput.BLOB_DERIVATIVE_LIST_KEY, true); - result = this.getDerivativeList(csid); + result = this.getDerivativeList(ctx, csid); if (result == null) { Response response = Response.status(Response.Status.NOT_FOUND).entity( ServiceMessages.READ_FAILED + ServiceMessages.resourceNotFoundMsg(csid)).type("text/plain").build(); 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 13f1498a5..7fd798f0b 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 @@ -32,6 +32,7 @@ import org.collectionspace.services.jaxb.BlobJAXBSchema; import org.collectionspace.services.common.blob.BlobInput; import org.collectionspace.services.common.blob.BlobOutput; +import org.collectionspace.services.common.blob.BlobUtil; import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.document.DocumentHandler.Action; @@ -46,6 +47,8 @@ import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler; import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl; import org.collectionspace.services.nuxeo.util.NuxeoUtils; +import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; +import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.DocumentModelList; import org.nuxeo.ecm.core.api.repository.RepositoryInstance; @@ -62,7 +65,7 @@ extends DocHandlerBase { /** The logger. */ private final Logger logger = LoggerFactory.getLogger(BlobDocumentModelHandler.class); - + public final String getNuxeoSchemaName(){ return "blobs"; } @@ -79,7 +82,7 @@ extends DocHandlerBase { List list = ((BlobsCommonList)commonList).getBlobListItem(); return list; } - + private String getDerivativePathBase(DocumentModel docModel) { return getServiceContextPath() + docModel.getName() + "/" + BlobInput.URI_DERIVATIVES_PATH + "/"; @@ -146,24 +149,27 @@ extends DocHandlerBase { public void extractAllParts(DocumentWrapper wrapDoc) throws Exception { ServiceContext ctx = this.getServiceContext(); + BlobInput blobInput = BlobUtil.getBlobInput(ctx); RepositoryInstance repoSession = this.getRepositorySession(); DocumentModel docModel = wrapDoc.getWrappedObject(); BlobsCommon blobsCommon = this.getCommonPartProperties(docModel); String blobRepositoryId = blobsCommon.getRepositoryId(); //cache the value to pass to the blob retriever - if (ctx.getProperty(BlobInput.BLOB_DERIVATIVE_LIST_KEY) != null) { + if (blobInput.isDerivativeListRequested() == true) { BlobsCommonList blobsCommonList = NuxeoImageUtils.getBlobDerivatives( repoSession, blobRepositoryId, getDerivativePathBase(docModel)); - ctx.setProperty(BlobInput.BLOB_DERIVATIVE_LIST_KEY, blobsCommonList); +// ctx.setProperty(BlobInput.BLOB_DERIVATIVE_LIST_KEY, blobsCommonList); + blobInput.setDerivativeList(blobsCommonList); return; //FIXME: Don't like this exit point. Perhaps derivatives should be a sub-resource? } - String derivativeTerm = (String)ctx.getProperty(BlobInput.BLOB_DERIVATIVE_TERM_KEY); - Boolean getContentFlag = ctx.getProperty(BlobInput.BLOB_CONTENT_KEY) != null ? true : false; + String derivativeTerm = blobInput.getDerivativeTerm(); + Boolean getContentFlag = blobInput.isContentRequested(); BlobOutput blobOutput = NuxeoImageUtils.getBlobOutput(ctx, repoSession, blobRepositoryId, derivativeTerm, getContentFlag); if (getContentFlag == true) { - ctx.setProperty(BlobInput.BLOB_CONTENT_KEY, blobOutput.getBlobInputStream()); + blobInput.setContentStream(blobOutput.getBlobInputStream()); +// ctx.setProperty(BlobInput.BLOB_CONTENT_KEY, blobOutput.getBlobInputStream()); } if (derivativeTerm != null) { @@ -182,17 +188,18 @@ extends DocHandlerBase { @Override public void fillAllParts(DocumentWrapper wrapDoc, Action action) throws Exception { ServiceContext ctx = this.getServiceContext(); - BlobInput blobInput = (BlobInput)ctx.getProperty(BlobInput.class.getName()); - if (blobInput == null) { - super.fillAllParts(wrapDoc, action); - } else { + BlobInput blobInput = BlobUtil.getBlobInput(ctx); + if (blobInput.getBlobFile() != null) { // - // If blobInput is set then we just received a multipart/form-data file post + // If blobInput has a file then we just received a multipart/form-data file post // DocumentModel documentModel = wrapDoc.getWrappedObject(); RepositoryInstance repoSession = this.getRepositorySession(); BlobsCommon blobsCommon = NuxeoImageUtils.createPicture(ctx, repoSession, blobInput); this.setCommonPartProperties(documentModel, blobsCommon); + blobInput.setBlobCsid(documentModel.getName()); + } else { + super.fillAllParts(wrapDoc, action); } } } diff --git a/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java b/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java index 3fba1cd38..76ec2781f 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/AbstractCollectionSpaceResourceImpl.java @@ -23,10 +23,13 @@ */ package org.collectionspace.services.common; +import java.util.List; + import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.context.ServiceContextProperties; @@ -35,6 +38,7 @@ import org.collectionspace.services.common.repository.RepositoryClient; import org.collectionspace.services.common.repository.RepositoryClientFactory; import org.collectionspace.services.common.storage.StorageClient; import org.collectionspace.services.common.storage.jpa.JpaStorageClientImpl; +import org.jboss.resteasy.client.ClientResponse; /** * The Class AbstractCollectionSpaceResourceImpl. @@ -55,6 +59,20 @@ public abstract class AbstractCollectionSpaceResourceImpl /** The storage client. */ private StorageClient storageClient; + /** + * Extract id. + * + * @param res the res + * @return the string + */ + protected static String extractId(Response res) { + MultivaluedMap mvm = res.getMetadata(); + String uri = (String) ((List) mvm.get("Location")).get(0); + String[] segments = uri.split("/"); + String id = segments[segments.length - 1]; + return id; + } + /** * Instantiates a new abstract collection space resource. */ diff --git a/services/common/src/main/java/org/collectionspace/services/common/ResourceBase.java b/services/common/src/main/java/org/collectionspace/services/common/ResourceBase.java index b3222b2bb..923a51b31 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/ResourceBase.java +++ b/services/common/src/main/java/org/collectionspace/services/common/ResourceBase.java @@ -58,32 +58,34 @@ extends AbstractMultiPartCollectionSpaceResourceImpl { return bigReThrow(e, serviceMsg, ""); } - protected WebApplicationException bigReThrow(Exception e, String serviceMsg, String csid) - throws WebApplicationException { - Response response; - if (logger.isDebugEnabled()) { - logger.debug(getClass().getName(), e); - } - if (e instanceof UnauthorizedException) { - response = Response.status(Response.Status.UNAUTHORIZED) - .entity(serviceMsg + e.getMessage()) - .type("text/plain") - .build(); - return new WebApplicationException(response); - } else if (e instanceof DocumentNotFoundException) { - response = Response.status(Response.Status.NOT_FOUND) - .entity(serviceMsg + " on "+getClass().getName()+" csid=" + csid) - .type("text/plain") - .build(); - return new WebApplicationException(response); - } else { //e is now instanceof Exception - response = Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(serviceMsg) - .type("text/plain") - .build(); - return new WebApplicationException(response); - } - } + protected WebApplicationException bigReThrow(Exception e, + String serviceMsg, String csid) throws WebApplicationException { + Response response; + if (logger.isDebugEnabled()) { + logger.debug(getClass().getName(), e); + } + if (e instanceof UnauthorizedException) { + response = Response.status(Response.Status.UNAUTHORIZED) + .entity(serviceMsg + e.getMessage()).type("text/plain") + .build(); + return new WebApplicationException(response); + } else if (e instanceof DocumentNotFoundException) { + response = Response + .status(Response.Status.NOT_FOUND) + .entity(serviceMsg + " on " + getClass().getName() + + " csid=" + csid).type("text/plain").build(); + return new WebApplicationException(response); + } else if (e instanceof WebApplicationException) { + // + // subresource may have already thrown this exception + // so just pass it on + return (WebApplicationException)e; + } else { // e is now instanceof Exception + response = Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(serviceMsg).type("text/plain").build(); + return new WebApplicationException(response); + } + } //======================= CREATE ==================================================== @@ -127,13 +129,22 @@ extends AbstractMultiPartCollectionSpaceResourceImpl { ensureCSID(csid, UPDATE); try { ServiceContext ctx = createServiceContext(theUpdate); - DocumentHandler handler = createDocumentHandler(ctx); - return update(csid, theUpdate, ctx, handler); //==> CALL implementation method, which subclasses may override. + return update(csid, theUpdate, ctx); //==> CALL implementation method, which subclasses may override. } catch (Exception e) { throw bigReThrow(e, ServiceMessages.UPDATE_FAILED, csid); } } + /** Subclasses may override this overload, which gets called from #udpate(String,MultipartInput) */ + protected MultipartOutput update(String csid, + MultipartInput theUpdate, + ServiceContext ctx) + throws Exception { + DocumentHandler handler = createDocumentHandler(ctx); + getRepositoryClient(ctx).update(ctx, csid, handler); + return (MultipartOutput) ctx.getOutput(); + } + /** Subclasses may override this overload, which gets called from #udpate(String,MultipartInput) */ protected MultipartOutput update(String csid, MultipartInput theUpdate, 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 c76c06b84..c0e565895 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 @@ -1,34 +1,124 @@ package org.collectionspace.services.common.blob; import java.io.File; +import java.io.InputStream; + +import javax.servlet.http.HttpServletRequest; + +import org.collectionspace.services.blob.BlobsCommonList; +import org.collectionspace.services.common.FileUtils; public class BlobInput { - private String mediaCsid; - private File blobFile; - private String blobUri; + private String blobCsid = null; + private File blobFile = null; + private String blobUri = null; - public static final String URI_CONTENT_PATH = "content"; - public static final String URI_DERIVATIVES_PATH = "derivatives"; + private String derivativeTerm; + private boolean derivativeListRequested = false; + private BlobsCommonList derivativeList; + + private boolean contentRequested = false; + private InputStream contentStream; - public static final String BLOB_DERIVATIVE_TERM_KEY = "derivative"; - public static final String BLOB_DERIVATIVE_LIST_KEY = "derivative.list"; - public static final String BLOB_CONTENT_KEY = "derivative.content.stream"; + private boolean schemaRequested = false; + public static final String URI_CONTENT_PATH = "content"; + public static final String URI_DERIVATIVES_PATH = "derivatives"; + + /* + * Constructors + */ + public BlobInput() { + /* Empty constructor */ + } + public BlobInput(File blobFile, String blobUri) { this.blobFile = blobFile; this.blobUri = blobUri; } - public String getMediaCsid() { - return mediaCsid; + /* + * Getters and Setters + */ + public boolean isSchemaRequested() { + return schemaRequested; } - + + public void setSchemaRequested(boolean schemaRequested) { + this.schemaRequested = schemaRequested; + } + + public String getBlobCsid() { + return blobCsid; + } + + public void setBlobCsid(String blobCsid) { + this.blobCsid = blobCsid; + } + public File getBlobFile() { return blobFile; } - + + public void setBlobFile(File blobFile) { + this.blobFile = blobFile; + } + public String getBlobUri() { return blobUri; } + + public void setBlobUri(String blobUri) { + this.blobUri = blobUri; + } + + public String getDerivativeTerm() { + return derivativeTerm; + } + + public void setDerivativeTerm(String derivativeTerm) { + this.derivativeTerm = derivativeTerm; + } + + public boolean isDerivativeListRequested() { + return derivativeListRequested; + } + + public void setDerivativeListRequested(boolean derivativesRequested) { + this.derivativeListRequested = derivativesRequested; + } + + public BlobsCommonList getDerivativeList() { + return derivativeList; + } + + public void setDerivativeList(BlobsCommonList derivativeList) { + this.derivativeList = derivativeList; + } + + public InputStream getContentStream() { + return contentStream; + } + + public void setContentStream(InputStream contentStream) { + this.contentStream = contentStream; + } + + public boolean isContentRequested() { + return contentRequested; + } + + public void setContentRequested(boolean contentRequested) { + this.contentRequested = contentRequested; + } + /* + * End of setters and getters + */ + + public void createBlobFile(HttpServletRequest req, String blobUri) { + File tmpFile = FileUtils.createTmpFile(req); + this.setBlobFile(tmpFile); + 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 3cab5df7b..3c04bc0d8 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 @@ -1,5 +1,34 @@ package org.collectionspace.services.common.blob; -public class BlobUtil { +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.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) { + BlobInput result = (BlobInput)ctx.getProperty(BlobInput.class.getName()); + if (result == null) { + result = new BlobInput(); + setBlobInput(ctx, result); + } + return result; + } + + public static BlobInput resetBlobInput(ServiceContext ctx) { + BlobInput blobInput = new BlobInput(); + setBlobInput(ctx, blobInput); + return blobInput; + } + + public static void setBlobInput(ServiceContext ctx, + BlobInput blobInput) { + ctx.setProperty(BlobInput.class.getName(), blobInput); + } + } diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java index 83750d475..d8d02f4b2 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java @@ -97,13 +97,21 @@ public abstract class RemoteDocumentModelHandlerImpl //return at least those document part(s) that were received Map partsMetaMap = getServiceContext().getPartsMetadata(); MultipartServiceContext ctx = (MultipartServiceContext) getServiceContext(); - List inputParts = ctx.getInput().getParts(); - for (InputPart part : inputParts) { - String partLabel = part.getHeaders().getFirst("label"); - ObjectPartType partMeta = partsMetaMap.get(partLabel); -// extractPart(docModel, partLabel, partMeta); - Map unQObjectProperties = extractPart(docModel, partLabel, partMeta); - addOutputPart(unQObjectProperties, partLabel, partMeta); + MultipartInput input = ctx.getInput(); + if (input != null) { + List inputParts = ctx.getInput().getParts(); + for (InputPart part : inputParts) { + String partLabel = part.getHeaders().getFirst("label"); + ObjectPartType partMeta = partsMetaMap.get(partLabel); + // extractPart(docModel, partLabel, partMeta); + Map unQObjectProperties = extractPart(docModel, partLabel, partMeta); + addOutputPart(unQObjectProperties, partLabel, partMeta); + } + } else { + if (logger.isWarnEnabled() == true) { + logger.warn("MultipartInput part was null for document id = " + + docModel.getName()); + } } } diff --git a/services/media/3rdparty/nuxeo-platform-cs-media/src/main/resources/schemas/media_common.xsd b/services/media/3rdparty/nuxeo-platform-cs-media/src/main/resources/schemas/media_common.xsd index 004c53e4e..23b789183 100644 --- a/services/media/3rdparty/nuxeo-platform-cs-media/src/main/resources/schemas/media_common.xsd +++ b/services/media/3rdparty/nuxeo-platform-cs-media/src/main/resources/schemas/media_common.xsd @@ -68,5 +68,6 @@ + diff --git a/services/media/jaxb/src/main/java/org/collectionspace/services/MediaJAXBSchema.java b/services/media/jaxb/src/main/java/org/collectionspace/services/MediaJAXBSchema.java index a982ef65f..0a41337ce 100644 --- a/services/media/jaxb/src/main/java/org/collectionspace/services/MediaJAXBSchema.java +++ b/services/media/jaxb/src/main/java/org/collectionspace/services/MediaJAXBSchema.java @@ -26,4 +26,5 @@ public interface MediaJAXBSchema { final static String title = "title"; final static String type = "type"; final static String uri = "uri"; + final static String blobCsid = "blobCsid"; } diff --git a/services/media/jaxb/src/main/resources/media_common.xsd b/services/media/jaxb/src/main/resources/media_common.xsd index 124f3ee8c..2e581577d 100644 --- a/services/media/jaxb/src/main/resources/media_common.xsd +++ b/services/media/jaxb/src/main/resources/media_common.xsd @@ -54,6 +54,7 @@ + diff --git a/services/media/service/pom.xml b/services/media/service/pom.xml index 62bc6c0d8..648ea3529 100644 --- a/services/media/service/pom.xml +++ b/services/media/service/pom.xml @@ -19,6 +19,16 @@ org.collectionspace.services.common ${project.version} + + org.collectionspace.services + org.collectionspace.services.jaxb + ${project.version} + + + org.collectionspace.services + org.collectionspace.services.blob.service + ${project.version} + org.collectionspace.services org.collectionspace.services.media.jaxb diff --git a/services/media/service/src/main/java/org/collectionspace/services/media/MediaResource.java b/services/media/service/src/main/java/org/collectionspace/services/media/MediaResource.java index f392b4888..97446a576 100644 --- a/services/media/service/src/main/java/org/collectionspace/services/media/MediaResource.java +++ b/services/media/service/src/main/java/org/collectionspace/services/media/MediaResource.java @@ -26,11 +26,33 @@ package org.collectionspace.services.media; import org.collectionspace.services.common.ResourceBase; import org.collectionspace.services.common.ClientType; import org.collectionspace.services.common.ServiceMain; +import org.collectionspace.services.common.ServiceMessages; +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.document.DocumentHandler; +import org.collectionspace.services.blob.BlobsCommon; +import org.collectionspace.services.blob.BlobsCommonList; +import org.collectionspace.services.blob.nuxeo.BlobDocumentModelHandler; +import org.collectionspace.services.blob.BlobResource; +import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; +import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; + +import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; + +import java.io.InputStream; import java.util.List; @Path("/media") @@ -41,8 +63,41 @@ public class MediaResource extends ResourceBase { @Override public String getServiceName(){ return "media"; - }; + } + + private BlobResource blobResource = new BlobResource(); + BlobResource getBlobResource() { + return blobResource; + } + +// /* +// * This member is used to get and set context for the blob document handler +// */ +// private BlobInput blobInput = new BlobInput(); +// +// public BlobInput getBlobInput(ServiceContext ctx) { +// // +// // Publish the blobInput to the current context on every get. Even though +// // it might already be published. +// // +// BlobUtil.setBlobInput(ctx, blobInput); +// return blobInput; +// } + private String getBlobCsid(String mediaCsid) throws Exception { + String result = null; + + ServiceContext mediaContext = createServiceContext(); + BlobInput blobInput = BlobUtil.getBlobInput(mediaContext); + blobInput.setSchemaRequested(true); + get(mediaCsid, mediaContext); //this call sets the blobInput.blobCsid field for us + result = blobInput.getBlobCsid(); + ensureCSID(result, READ); + + return result; + } + + //FIXME retrieve client type from configuration final static ClientType CLIENT_TYPE = ServiceMain.getInstance().getClientType(); @@ -57,6 +112,124 @@ public class MediaResource extends ResourceBase { return MediaCommon.class; } + @POST + @Path("{csid}") + @Consumes("multipart/form-data") + @Produces("application/xml") + public Response createBlob(@Context HttpServletRequest req, + @QueryParam("blobUri") String blobUri, + @PathParam("csid") String csid) { + MultipartInput input = null; + Response response = null; + try { + // + // First, create the blob + // + ServiceContext blobContext = createServiceContext(BlobUtil.BLOB_RESOURCE_NAME, input); + BlobInput blobInput = BlobUtil.getBlobInput(blobContext); + blobInput.createBlobFile(req, blobUri); + response = this.create(input, blobContext); + // + // Next, update the Media record to be linked to the blob + // + ServiceContext mediaContext = createServiceContext(); + BlobUtil.setBlobInput(mediaContext, blobInput); //and put the blobInput into the Media context + this.update(csid, input, mediaContext); + } catch (Exception e) { + throw bigReThrow(e, ServiceMessages.CREATE_FAILED); + } + + return response; + } + + @GET + @Path("{csid}/blob") + public MultipartOutput getBlobInfo(@PathParam("csid") String csid) { + MultipartOutput result = null; + + try { + String blobCsid = this.getBlobCsid(csid); + ServiceContext blobContext = createServiceContext(BlobUtil.BLOB_RESOURCE_NAME); + result = this.get(blobCsid, blobContext); + } catch (Exception e) { + throw bigReThrow(e, ServiceMessages.READ_FAILED, csid); + } + + return result; + } + @GET + @Path("{csid}/blob/content") + @Produces({"image/jpeg", "image/png", "image/tiff"}) + public InputStream getBlobContent( + @PathParam("csid") String csid) { + InputStream result = null; + + try { + ensureCSID(csid, READ); + String blobCsid = this.getBlobCsid(csid); + result = getBlobResource().getBlobContent(blobCsid); + } catch (Exception e) { + throw bigReThrow(e, ServiceMessages.READ_FAILED, csid); + } + + return result; + } + + @GET + @Path("{csid}/blob/derivatives/{derivativeTerm}/content") + @Produces({"image/jpeg", "image/png", "image/tiff"}) + public InputStream getDerivativeContent( + @PathParam("csid") String csid, + @PathParam("derivativeTerm") String derivativeTerm) { + InputStream result = null; + + try { + ensureCSID(csid, READ); + String blobCsid = this.getBlobCsid(csid); + result = getBlobResource().getDerivativeContent(blobCsid, derivativeTerm); + } catch (Exception e) { + throw bigReThrow(e, ServiceMessages.READ_FAILED, csid); + } + + return result; + } + + @GET + @Path("{csid}/blob/derivatives/{derivativeTerm}") + public MultipartOutput getDerivative(@PathParam("csid") String csid, + @PathParam("derivativeTerm") String derivativeTerm) { + MultipartOutput result = null; + + try { + ensureCSID(csid, READ); + String blobCsid = this.getBlobCsid(csid); + ServiceContext blobContext = createServiceContext(BlobUtil.BLOB_RESOURCE_NAME); + result = getBlobResource().getDerivative(blobCsid, derivativeTerm); + } catch (Exception e) { + throw bigReThrow(e, ServiceMessages.READ_FAILED, csid); + } + + return result; + } + + @GET + @Path("{csid}/blob/derivatives") + @Produces("application/xml") + public BlobsCommonList getDerivatives( + @PathParam("csid") String csid) { + BlobsCommonList result = null; + + try { + ensureCSID(csid, READ); + String blobCsid = this.getBlobCsid(csid); + ServiceContext blobContext = createServiceContext(BlobUtil.BLOB_RESOURCE_NAME); + result = getBlobResource().getDerivatives(blobCsid); + } catch (Exception e) { + throw bigReThrow(e, ServiceMessages.READ_FAILED, csid); + } + + return result; + } } diff --git a/services/media/service/src/main/java/org/collectionspace/services/media/nuxeo/MediaDocumentModelHandler.java b/services/media/service/src/main/java/org/collectionspace/services/media/nuxeo/MediaDocumentModelHandler.java index 3f3edeb81..03b808783 100644 --- a/services/media/service/src/main/java/org/collectionspace/services/media/nuxeo/MediaDocumentModelHandler.java +++ b/services/media/service/src/main/java/org/collectionspace/services/media/nuxeo/MediaDocumentModelHandler.java @@ -26,19 +26,30 @@ package org.collectionspace.services.media.nuxeo; import java.util.List; import org.collectionspace.services.MediaJAXBSchema; +import org.collectionspace.services.blob.BlobsCommon; import org.collectionspace.services.common.DocHandlerBase; +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.document.DocumentWrapper; +import org.collectionspace.services.common.document.DocumentHandler.Action; +import org.collectionspace.services.common.imaging.nuxeo.NuxeoImageUtils; import org.collectionspace.services.media.MediaCommon; import org.collectionspace.services.media.MediaCommonList; import org.collectionspace.services.media.MediaCommonList.MediaListItem; import org.collectionspace.services.jaxb.AbstractCommonList; +import org.collectionspace.services.jaxb.BlobJAXBSchema; +import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; +import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; import org.nuxeo.ecm.core.api.DocumentModel; +import org.nuxeo.ecm.core.api.repository.RepositoryInstance; /** * The Class MediaDocumentModelHandler. */ public class MediaDocumentModelHandler extends DocHandlerBase { - + public final String getNuxeoSchemaName(){ return "media"; } @@ -55,7 +66,17 @@ public class MediaDocumentModelHandler List list = ((MediaCommonList)commonList).getMediaListItem(); return list; } - + + private MediaCommon getCommonPartProperties(DocumentModel docModel) throws Exception { + String label = getServiceContext().getCommonPartLabel(); + MediaCommon result = new MediaCommon(); + + result.setBlobCsid((String) + docModel.getProperty(label, MediaJAXBSchema.blobCsid)); + + return result; + } + public Object createItemForCommonList(DocumentModel docModel, String label, String id) throws Exception { MediaListItem item = new MediaListItem(); item.setTitle((String) docModel.getProperty(label, MediaJAXBSchema.title)); @@ -66,5 +87,38 @@ public class MediaDocumentModelHandler item.setCsid(id); return item; } + + @Override + public void extractAllParts(DocumentWrapper wrapDoc) + throws Exception { + ServiceContext ctx = this.getServiceContext(); + + BlobInput blobInput = BlobUtil.getBlobInput(ctx); + if (blobInput != null && blobInput.isSchemaRequested()) { //Extract the blob info instead of the media info + DocumentModel docModel = wrapDoc.getWrappedObject(); + MediaCommon mediaCommon = this.getCommonPartProperties(docModel); + String blobCsid = mediaCommon.getBlobCsid(); //cache the value to pass to the blob retriever + blobInput.setBlobCsid(blobCsid); + } else { + super.extractAllParts(wrapDoc); + } + } + + @Override + public void fillAllParts(DocumentWrapper wrapDoc, Action action) throws Exception { + ServiceContext ctx = this.getServiceContext(); + BlobInput blobInput = BlobUtil.getBlobInput(ctx); + if (blobInput != null && blobInput.getBlobCsid() != null) { + String blobCsid = blobInput.getBlobCsid(); + // + // If getBlobCsid has a value then we just received a multipart/form-data file post + // + DocumentModel documentModel = wrapDoc.getWrappedObject(); + documentModel.setProperty(ctx.getCommonPartLabel(), MediaJAXBSchema.blobCsid, blobCsid); + } else { + super.fillAllParts(wrapDoc, action); + } + } + }