//HTTP query param string for specifying a URI source to blob bits.
public static final String BLOB_URI_PARAM = "blobUri";
+ public static final String BLOB_CSID_PARAM = "blobCsid";
//Image blob metadata labels
public static final String IMAGE_MEASURED_PART_LABEL = "digitalImage";
private final static BigDecimal KNOWN_IMAGE_WIDTH = new BigDecimal(640.0);
private final static BigDecimal KNOWN_IMAGE_HEIGHT = new BigDecimal(480.0);
+ private final static String PUBLIC_URL_BIRD = "http://farm6.static.flickr.com/5289/5688023100_15e00cde47_o.jpg";
+ private final static String PUBLIC_URL_DECK = "http://farm8.staticflickr.com/7231/6962564226_4bdfc17599_k_d.jpg";
+
private boolean blobCleanup = true;
@Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
dependsOnMethods = {"CRUDTests"})
- public void createBlobWithURL(String testName) throws Exception {
- createBlob(testName, true /*with URI*/, "http://farm6.static.flickr.com/5289/5688023100_15e00cde47_o.jpg");
+ public void createBlobWithURL1(String testName) throws Exception {
+ createBlob(testName, true /*with URI*/, PUBLIC_URL_BIRD);
+ }
+
+ @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+ dependsOnMethods = {"CRUDTests"})
+ public void createBlobWithURL2(String testName) throws Exception {
+ createBlob(testName, true /*with URI*/, PUBLIC_URL_DECK);
}
@Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
return ctx;\r
}\r
\r
+ protected ServiceContext<IT, OT> createServiceContext(\r
+ IT input,\r
+ MultivaluedMap<String, String> queryParams) throws Exception {\r
+ return createServiceContext(this.getServiceName(),\r
+ input,\r
+ queryParams,\r
+ null /* the class of the input type */);\r
+ }\r
+ \r
/**\r
* Creates the service context.\r
* \r
public Response create(@Context ResourceMap resourceMap,\r
@Context UriInfo ui,\r
String xmlPayload) {\r
- return this.create(null, resourceMap, ui, xmlPayload);\r
+ return this.create(null, resourceMap, ui, xmlPayload); \r
}\r
\r
- public Response create(ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx,\r
+ public Response create(ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx, // REM: 8/13/2012 - Some sub-classes will override this method -e.g., MediaResource does.\r
@Context ResourceMap resourceMap,\r
@Context UriInfo ui,\r
String xmlPayload) {\r
\r
try {\r
PoxPayloadIn input = new PoxPayloadIn(xmlPayload);\r
- ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(input);\r
+ ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(input, ui.getQueryParameters());\r
ctx.setResourceMap(resourceMap);\r
if (parentCtx != null && parentCtx.getCurrentRepositorySession() != null) {\r
ctx.setCurrentRepositorySession(parentCtx.getCurrentRepositorySession()); // Reuse the current repo session if one exists\r
/**
* @param media
* @return
+ *
+ * Creates a new blob resource from the form data and associates it with an existing media resource
*
*/
- public ClientResponse<Response> createBlobFromFormData(String csid,
+ public ClientResponse<Response> createBlobFromFormData(String csid, // this is the Media resource CSID
MultipartFormDataOutput formDataOutput) {
return getProxy().createBlobFromFormData(csid, formDataOutput);
}
/**
* @param media
* @return
+ *
+ * Creates a new blob
*
*/
public ClientResponse<Response> createBlobFromUri(String csid, String blobUri) {
return getProxy().createBlobFromUri(csid, blobUri, blobUri); //send the URI as both a query param and as content
- }
+ }
+
+ /*
+ * Create both a new media record
+ */
+ public ClientResponse<Response> createMediaAndBlobWithUri(PoxPayloadOut xmlPayload, String blobUri) {
+ return getProxy().createMediaAndBlobWithUri(xmlPayload.getBytes(), blobUri);
+ }
/**
* @param csid
ClientResponse<Response>createBlobFromUri(@PathParam("csid") String csid,
@QueryParam(BlobClient.BLOB_URI_PARAM) String blobUri,
String emptyXML); //this "emptyXML" param is needed to force RESTEasy to produce a Content-Type header for this POST
+
+ @POST
+ @Produces("application/xml")
+ @Consumes("application/xml")
+ ClientResponse<Response>createMediaAndBlobWithUri(byte[] xmlPayload,
+ @QueryParam(BlobClient.BLOB_URI_PARAM) String blobUri);
}
private final String CLASS_NAME = MediaServiceTest.class.getName();
private final Logger logger = LoggerFactory.getLogger(MediaServiceTest.class);
+ private final static String PUBLIC_URL_DECK = "http://farm8.staticflickr.com/7231/6962564226_4bdfc17599_k_d.jpg";
private boolean mediaCleanup = true;
createBlob(testName, true /*with URI*/);
}
+ @Test(dataProvider = "testName",
+ dependsOnMethods = {"createWithBlobUri"})
+ public void createMediaAndBlobWithUri(String testName) throws Exception {
+ MediaClient client = new MediaClient();
+ PoxPayloadOut multipart = createMediaInstance(createIdentifier());
+ ClientResponse<Response> mediaRes = client.createMediaAndBlobWithUri(multipart, PUBLIC_URL_DECK);
+ String mediaCsid = null;
+ try {
+ assertStatusCode(mediaRes, testName);
+ mediaCsid = extractId(mediaRes);
+ } finally {
+ if (mediaRes != null) {
+ mediaRes.releaseConnection();
+ }
+ }
+ }
+
+
@Test(dataProvider = "testName",
dependsOnMethods = {"createWithBlobUri"})
public void createWithBlobPost(String testName) throws Exception {
import org.collectionspace.services.blob.BlobResource;
import org.collectionspace.services.client.BlobClient;
+import org.collectionspace.services.client.CollectionSpaceClientUtils;
+import org.collectionspace.services.client.IQueryManager;
import org.collectionspace.services.client.MediaClient;
import org.collectionspace.services.client.PayloadOutputPart;
import org.collectionspace.services.client.PoxPayloadIn;
import org.collectionspace.services.client.PoxPayloadOut;
import org.collectionspace.services.common.ResourceBase;
-import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.ResourceMap;
import org.collectionspace.services.common.ServiceMessages;
import org.collectionspace.services.common.blob.BlobInput;
import org.collectionspace.services.common.blob.BlobUtil;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
-import java.io.InputStream;
+import javax.ws.rs.core.UriInfo;
@Path(MediaClient.SERVICE_PATH)
@Consumes("application/xml")
return result;
}
- //FIXME retrieve client type from configuration
-// final static ClientType CLIENT_TYPE = ServiceMain.getInstance().getClientType();
-
@Override
protected String getVersionString() {
final String lastChangeRevision = "$LastChangedRevision: 2108 $";
return MediaCommon.class;
}
+ /*
+ * Creates a new media record/resource AND creates a new blob (using a URL pointing to a media file/resource) and associates
+ * it with the new media record/resource.
+ */
+ protected Response createBlobWithUri(ResourceMap resourceMap, UriInfo ui, String xmlPayload, String blobUri) {
+ Response response = null;
+
+ try {
+ ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(BlobClient.SERVICE_NAME, (PoxPayloadIn)null); // The blobUri argument is our payload
+ BlobInput blobInput = BlobUtil.getBlobInput(ctx); // the blob doc handler will look for this in the context
+ blobInput.createBlobFile(blobUri);
+ response = this.create((PoxPayloadIn)null, ctx); // By now the binary bits have been created and we just need to create the metadata blob record -this info is in the blobInput var
+ } catch (Exception e) {
+ throw bigReThrow(e, ServiceMessages.CREATE_FAILED);
+ }
+
+ return response;
+ }
+
+ /*
+ * Looks for a blobUri query param from a POST. If it finds one then it creates a blob and a media resource and associates them.
+ * (non-Javadoc)
+ * @see org.collectionspace.services.common.ResourceBase#create(org.collectionspace.services.common.context.ServiceContext, org.collectionspace.services.common.ResourceMap, javax.ws.rs.core.UriInfo, java.lang.String)
+ */
+ @Override
+ public Response create(ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx,
+ @Context ResourceMap resourceMap,
+ @Context UriInfo ui,
+ String xmlPayload) {
+ Response result = null;
+
+ //
+ // If we find a "blobUri" query param, then we need to create a blob resource/record first and then the media resource/record
+ //
+ MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
+ String blobUri = queryParams.getFirst(BlobClient.BLOB_URI_PARAM);
+ if (blobUri != null && blobUri.isEmpty() == false) {
+ result = createBlobWithUri(resourceMap, ui, xmlPayload, blobUri);
+ String blobCsid = CollectionSpaceClientUtils.extractId(result);
+ queryParams.add(BlobClient.BLOB_CSID_PARAM, blobCsid); // Add the new blob's csid as an artificial query param -the media doc handler will look for this
+ }
+
+ result = super.create(parentCtx, resourceMap, ui, xmlPayload); // Now call the parent to finish the media resource POST request
+
+ return result;
+ }
+
+
+ /*
+ * Creates a new blob (using a URL pointing to a media file/resource) and associates it with an existing media record/resource.
+ */
@POST
@Path("{csid}")
@Consumes("application/xml")
@Produces("application/xml")
- public Response createBlobWithUri(@PathParam("csid") String csid,
+ public Response createBlobWithUriAndUpdateMedia(@PathParam("csid") String csid,
@QueryParam(BlobClient.BLOB_URI_PARAM) String blobUri) {
Response response = null;
PoxPayloadIn input = null;
return response;
}
+ /*
+ * Creates a new blob (using the incoming multipart form data) and associates it with an existing media record/resource.
+ * If a URL query param is passed in as well, we use the URL to create the new blob instead of the multipart form data.
+ */
@POST
@Path("{csid}")
@Consumes("multipart/form-data")
this.update(csid, input, mediaContext);
} else {
//A URI query param overrides the incoming multipart/form-data payload in the request
- response = createBlobWithUri(csid, blobUri);
+ response = createBlobWithUriAndUpdateMedia(csid, blobUri);
}
} catch (Exception e) {
throw bigReThrow(e, ServiceMessages.CREATE_FAILED);
import org.collectionspace.services.MediaJAXBSchema;
import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
+import org.collectionspace.services.client.BlobClient;
import org.collectionspace.services.common.blob.BlobInput;
import org.collectionspace.services.common.blob.BlobUtil;
import org.collectionspace.services.common.context.ServiceContext;
import java.util.ArrayList;
import java.util.List;
+import javax.ws.rs.core.MultivaluedMap;
+
/**
* The Class MediaDocumentModelHandler.
*/
@Override
public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception {
ServiceContext ctx = this.getServiceContext();
+ String blobCsid = null;
+
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);
+ blobCsid = blobInput.getBlobCsid(); // If getBlobCsid has a value then we just finishing a multipart/form-data file post, created a blob, and now associating it with an existing media resource
} else {
+ MultivaluedMap<String, String> queryParams = this.getServiceContext().getQueryParams();
+ blobCsid = queryParams.getFirst(BlobClient.BLOB_CSID_PARAM); // if the blobUri query param is set, it's probably set from the MediaResource.create method -we're creating a blob from a URI and creating a new media resource as well
+ // extract all the other fields from the input payload
super.fillAllParts(wrapDoc, action);
}
+
+ //
+ if (blobCsid != null) {
+ DocumentModel documentModel = wrapDoc.getWrappedObject();
+ documentModel.setProperty(ctx.getCommonPartLabel(), MediaJAXBSchema.blobCsid, blobCsid);
+ }
}
}