]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
2bb1a1c21124b9a3e0d38f62269619293a863d4d
[tmp/jakarta-migration.git] /
1 /**
2  * This document is a part of the source code and related artifacts
3  * for CollectionSpace, an open source collections management system
4  * for museums and related institutions:
5  *
6  * http://www.collectionspace.org
7  * http://wiki.collectionspace.org
8  *
9  * Copyright © 2009 Regents of the University of California
10  *
11  * Licensed under the Educational Community License (ECL), Version 2.0.
12  * You may not use this file except in compliance with this License.
13  *
14  * You may obtain a copy of the ECL 2.0 License at
15  * https://source.collectionspace.org/collection-space/LICENSE.txt
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 package org.collectionspace.services.client.test;
24
25 import java.util.ArrayList;
26 import java.util.List;
27 import javax.ws.rs.core.MediaType;
28 import javax.ws.rs.core.Response;
29
30 import org.collectionspace.services.client.CollectionObjectClient;
31 import org.collectionspace.services.collectionobject.CollectionobjectsCommon;
32 import org.collectionspace.services.collectionobject.domain.naturalhistory.CollectionobjectsNaturalhistory;
33 import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
34 import org.collectionspace.services.collectionobject.OtherNumberList;
35 import org.jboss.resteasy.client.ClientResponse;
36
37 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
38 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
39 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
40 import org.testng.Assert;
41 import org.testng.annotations.AfterClass;
42 import org.testng.annotations.Test;
43
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 /**
48  * CollectionObjectServiceTest, carries out tests against a
49  * deployed and running CollectionObject Service.
50  * 
51  * $LastChangedRevision$
52  * $LastChangedDate$
53  */
54 public class CollectionObjectServiceTest extends AbstractServiceTest {
55
56     private final Logger logger =
57             LoggerFactory.getLogger(CollectionObjectServiceTest.class);
58     // Instance variables specific to this test.
59     private CollectionObjectClient client = new CollectionObjectClient();
60     private String knownResourceId = null;
61     private List<String> additionalResourceIds = new ArrayList();
62
63     /*
64      * This method is called only by the parent class, AbstractServiceTest
65      */
66     @Override
67     protected String getServicePathComponent() {
68         return client.getServicePathComponent();
69     }
70
71     // ---------------------------------------------------------------
72     // CRUD tests : CREATE tests
73     // ---------------------------------------------------------------
74     // Success outcomes
75     @Override
76     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class)
77     public void create(String testName) throws Exception {
78
79         // Perform setup, such as initializing the type of service request
80         // (e.g. CREATE, DELETE), its valid and expected status codes, and
81         // its associated HTTP method name (e.g. POST, DELETE).
82         setupCreate(testName);
83
84         // Submit the request to the service and store the response.
85         String identifier = createIdentifier();
86         MultipartOutput multipart =
87                 createCollectionObjectInstance(client.getCommonPartName(), identifier);
88         ClientResponse<Response> res = client.create(multipart);
89         int statusCode = res.getStatus();
90
91         // Check the status code of the response: does it match
92         // the expected response(s)?
93         //
94         // Specifically:
95         // Does it fall within the set of valid status codes?
96         // Does it exactly match the expected status code?
97         if (logger.isDebugEnabled()) {
98             logger.debug(testName + ": status = " + statusCode);
99         }
100         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
101                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
102         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
103
104         // Store the ID returned from the first resource created
105         // for additional tests below.
106         if (knownResourceId == null){
107             knownResourceId = extractId(res);
108             if (logger.isDebugEnabled()) {
109                 logger.debug(testName + ": knownResourceId=" + knownResourceId);
110             }
111         // Store the IDs from any additional resources created by tests,
112         // so they can be deleted after all tests have been run.
113         } else {
114             additionalResourceIds.add(extractId(res));
115         }
116     }
117
118     /* (non-Javadoc)
119      * @see org.collectionspace.services.client.test.ServiceTest#createList()
120      */
121     @Override
122     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
123     dependsOnMethods = {"create"})
124     public void createList(String testName) throws Exception {
125         for (int i = 0; i < 3; i++) {
126             create(testName);
127         }
128     }
129
130     // Failure outcomes
131     // Placeholders until the three tests below can be uncommented.
132     // See Issue CSPACE-401.
133     @Override
134     public void createWithEmptyEntityBody(String testName) throws Exception {
135     }
136
137     @Override
138     public void createWithMalformedXml(String testName) throws Exception {
139     }
140
141     @Override
142     public void createWithWrongXmlSchema(String testName) throws Exception {
143     }
144
145
146     /*
147     @Override
148     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
149     dependsOnMethods = {"create", "testSubmitRequest"})
150     public void createWithEmptyEntityBody(String testName) throwsException {
151     
152     // Perform setup.
153     setupCreateWithEmptyEntityBody(testName);
154
155     // Submit the request to the service and store the response.
156     String method = REQUEST_TYPE.httpMethodName();
157     String url = getServiceRootURL();
158     String mediaType = MediaType.APPLICATION_XML;
159     final String entity = "";
160     int statusCode = submitRequest(method, url, mediaType, entity);
161
162     // Check the status code of the response: does it match
163     // the expected response(s)?
164     if(logger.isDebugEnabled()){
165     logger.debug(testName + ": url=" + url +
166     " status=" + statusCode);
167     }
168     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
169     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
170     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
171     }
172
173     @Override
174     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
175     dependsOnMethods = {"create", "testSubmitRequest"})
176     public void createWithMalformedXml(String testName) throws Exception {
177     
178     // Perform setup.
179     setupCreateWithMalformedXml(testName);
180
181     // Submit the request to the service and store the response.
182     String method = REQUEST_TYPE.httpMethodName();
183     String url = getServiceRootURL();
184     String mediaType = MediaType.APPLICATION_XML;
185     final String entity = MALFORMED_XML_DATA; // Constant from base class.
186     int statusCode = submitRequest(method, url, mediaType, entity);
187
188     // Check the status code of the response: does it match
189     // the expected response(s)?
190     if(logger.isDebugEnabled()){
191     logger.debug(testName + ": url=" + url +
192     " status=" + statusCode);
193     }
194     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
195     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
196     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
197     }
198
199     @Override
200     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
201     dependsOnMethods = {"create", "testSubmitRequest"})
202     public void createWithWrongXmlSchema(String testName) throws Exception {
203     
204     // Perform setup.
205     setupCreateWithWrongXmlSchema(testName);
206
207     // Submit the request to the service and store the response.
208     String method = REQUEST_TYPE.httpMethodName();
209     String url = getServiceRootURL();
210     String mediaType = MediaType.APPLICATION_XML;
211     final String entity = WRONG_XML_SCHEMA_DATA;
212     int statusCode = submitRequest(method, url, mediaType, entity);
213
214     // Check the status code of the response: does it match
215     // the expected response(s)?
216     if(logger.isDebugEnabled()){
217     logger.debug(testName + ": url=" + url +
218     " status=" + statusCode);
219     }
220     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
221     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
222     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
223     }
224      */
225     // ---------------------------------------------------------------
226     // CRUD tests : READ tests
227     // ---------------------------------------------------------------
228     // Success outcomes
229     @Override
230     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
231     dependsOnMethods = {"create"})
232     public void read(String testName) throws Exception {
233
234         // Perform setup.
235         setupRead(testName);
236
237         // Submit the request to the service and store the response.
238         ClientResponse<MultipartInput> res = client.read(knownResourceId);
239         int statusCode = res.getStatus();
240
241         // Check the status code of the response: does it match
242         // the expected response(s)?
243         if (logger.isDebugEnabled()) {
244             logger.debug(testName + ": status = " + statusCode);
245         }
246         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
247                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
248         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
249
250         MultipartInput input = (MultipartInput) res.getEntity();
251
252         if (logger.isDebugEnabled()) {
253             logger.debug(testName + ": Reading Common part ...");
254         }
255         CollectionobjectsCommon collectionObject =
256                 (CollectionobjectsCommon) extractPart(input,
257                 client.getCommonPartName(), CollectionobjectsCommon.class);
258         Assert.assertNotNull(collectionObject);
259
260         if (logger.isDebugEnabled()) {
261             logger.debug(testName + ": Reading Natural History part ...");
262         }
263         CollectionobjectsNaturalhistory conh =
264                 (CollectionobjectsNaturalhistory) extractPart(input,
265                 getNHPartName(), CollectionobjectsNaturalhistory.class);
266         Assert.assertNotNull(conh);
267     }
268
269     // Failure outcomes
270     @Override
271     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
272     dependsOnMethods = {"read"})
273     public void readNonExistent(String testName) throws Exception {
274
275         // Perform setup.
276         setupReadNonExistent(testName);
277
278         // Submit the request to the service and store the response.
279         ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
280         int statusCode = res.getStatus();
281
282         // Check the status code of the response: does it match
283         // the expected response(s)?
284         if (logger.isDebugEnabled()) {
285             logger.debug(testName + ": status = " + statusCode);
286         }
287         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
288                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
289         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
290     }
291
292     // ---------------------------------------------------------------
293     // CRUD tests : READ_LIST tests
294     // ---------------------------------------------------------------
295     // Success outcomes
296     @Override
297     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
298     dependsOnMethods = {"createList", "read"})
299     public void readList(String testName) throws Exception {
300
301         // Perform setup.
302         setupReadList(testName);
303
304         // Submit the request to the service and store the response.
305         ClientResponse<CollectionobjectsCommonList> res = client.readList();
306         CollectionobjectsCommonList list = res.getEntity();
307         int statusCode = res.getStatus();
308
309         // Check the status code of the response: does it match
310         // the expected response(s)?
311         if (logger.isDebugEnabled()) {
312             logger.debug(testName + ": status = " + statusCode);
313         }
314         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
315                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
316         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
317
318         // Optionally output additional data about list members for debugging.
319         boolean iterateThroughList = false;
320         if (iterateThroughList && logger.isDebugEnabled()) {
321             List<CollectionobjectsCommonList.CollectionObjectListItem> items =
322                     list.getCollectionObjectListItem();
323             int i = 0;
324
325             for (CollectionobjectsCommonList.CollectionObjectListItem item : items) {
326                 logger.debug(testName + ": list-item[" + i + "] csid=" +
327                         item.getCsid());
328                 logger.debug(testName + ": list-item[" + i + "] objectNumber=" +
329                         item.getObjectNumber());
330                 logger.debug(testName + ": list-item[" + i + "] URI=" +
331                         item.getUri());
332                 i++;
333
334             }
335         }
336     }
337
338     // Failure outcomes
339     // None at present.
340     // ---------------------------------------------------------------
341     // CRUD tests : UPDATE tests
342     // ---------------------------------------------------------------
343     // Success outcomes
344     @Override
345     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
346     dependsOnMethods = {"read"})
347     public void update(String testName) throws Exception {
348
349         // Perform setup.
350         setupUpdate(testName);
351
352         ClientResponse<MultipartInput> res =
353                 client.read(knownResourceId);
354         if (logger.isDebugEnabled()) {
355             logger.debug(testName + ": read status = " + res.getStatus());
356         }
357         Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
358
359         if (logger.isDebugEnabled()) {
360             logger.debug("got object to update with ID: " + knownResourceId);
361         }
362         MultipartInput input = (MultipartInput) res.getEntity();
363         CollectionobjectsCommon collectionObject =
364                 (CollectionobjectsCommon) extractPart(input,
365                 client.getCommonPartName(), CollectionobjectsCommon.class);
366         Assert.assertNotNull(collectionObject);
367
368         // Update the content of this resource.
369         collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
370         collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
371         if (logger.isDebugEnabled()) {
372             logger.debug("updated object");
373             logger.debug(objectAsXmlString(collectionObject,
374                 CollectionobjectsCommon.class));
375         }
376
377         // Submit the request to the service and store the response.
378         MultipartOutput output = new MultipartOutput();
379         OutputPart commonPart = output.addPart(collectionObject, MediaType.APPLICATION_XML_TYPE);
380         commonPart.getHeaders().add("label", client.getCommonPartName());
381
382         res = client.update(knownResourceId, output);
383         int statusCode = res.getStatus();
384         // Check the status code of the response: does it match the expected response(s)?
385         if (logger.isDebugEnabled()) {
386             logger.debug(testName + ": status = " + statusCode);
387         }
388         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
389                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
390         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
391
392
393         input = (MultipartInput) res.getEntity();
394         CollectionobjectsCommon updatedCollectionObject =
395                 (CollectionobjectsCommon) extractPart(input,
396                 client.getCommonPartName(), CollectionobjectsCommon.class);
397         Assert.assertNotNull(updatedCollectionObject);
398
399         Assert.assertEquals(updatedCollectionObject.getObjectName(),
400                 collectionObject.getObjectName(),
401                 "Data in updated object did not match submitted data.");
402
403     }
404
405     // Failure outcomes
406     // Placeholders until the three tests below can be uncommented.
407     // See Issue CSPACE-401.
408     @Override
409     public void updateWithEmptyEntityBody(String testName) throws Exception {
410     }
411
412     @Override
413     public void updateWithMalformedXml(String testName) throws Exception {
414     }
415
416     @Override
417     public void updateWithWrongXmlSchema(String testName) throws Exception {
418     }
419
420     /*
421     @Override
422     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
423     dependsOnMethods = {"create", "update", "testSubmitRequest"})
424     public void updateWithEmptyEntityBody(String testName) throws Exception {
425     
426     // Perform setup.
427     setupUpdateWithEmptyEntityBody(testName);
428
429     // Submit the request to the service and store the response.
430     String method = REQUEST_TYPE.httpMethodName();
431     String url = getResourceURL(knownResourceId);
432     String mediaType = MediaType.APPLICATION_XML;
433     final String entity = "";
434     int statusCode = submitRequest(method, url, mediaType, entity);
435
436     // Check the status code of the response: does it match
437     // the expected response(s)?
438     if(logger.isDebugEnabled()){
439     logger.debug(testName + ": url=" + url +
440     " status=" + statusCode);
441     }
442     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
443     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
444     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
445     }
446
447     @Override
448     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
449     dependsOnMethods = {"create", "update", "testSubmitRequest"})
450     public void updateWithMalformedXml() throws Exception {
451
452     // Perform setup.
453     setupUpdateWithMalformedXml(testName);
454
455     // Submit the request to the service and store the response.
456     String method = REQUEST_TYPE.httpMethodName();
457     String url = getResourceURL(knownResourceId);
458     final String entity = MALFORMED_XML_DATA;
459     String mediaType = MediaType.APPLICATION_XML;
460     int statusCode = submitRequest(method, url, mediaType, entity);
461
462     // Check the status code of the response: does it match
463     // the expected response(s)?
464     if(logger.isDebugEnabled()){
465     logger.debug(testName + ": url=" + url +
466     " status=" + statusCode);
467     }
468     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
469     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
470     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
471     }
472
473     @Override
474     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
475     dependsOnMethods = {"create", "update", "testSubmitRequest"})
476     public void updateWithWrongXmlSchema(String testName) throws Exception {
477     
478     // Perform setup.
479     setupUpdateWithWrongXmlSchema(String testName);
480
481     // Submit the request to the service and store the response.
482     String method = REQUEST_TYPE.httpMethodName();
483     String url = getResourceURL(knownResourceId);
484     String mediaType = MediaType.APPLICATION_XML;
485     final String entity = WRONG_XML_SCHEMA_DATA;
486     int statusCode = submitRequest(method, url, mediaType, entity);
487
488     // Check the status code of the response: does it match
489     // the expected response(s)?
490     if(logger.isDebugEnabled()){
491     logger.debug(testName + ": url=" + url +
492     " status=" + statusCode);
493     }
494     Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
495     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
496     Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
497     }
498      */
499     @Override
500     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
501     dependsOnMethods = {"update", "testSubmitRequest"})
502     public void updateNonExistent(String testName) throws Exception {
503
504         // Perform setup.
505         setupUpdateNonExistent(testName);
506
507         // Submit the request to the service and store the response.
508         //
509         // Note: The ID used in this 'create' call may be arbitrary.
510         // The only relevant ID may be the one used in updateCollectionObject(), below.
511         MultipartOutput multipart =
512                 createCollectionObjectInstance(client.getCommonPartName(),
513                 NON_EXISTENT_ID);
514         ClientResponse<MultipartInput> res =
515                 client.update(NON_EXISTENT_ID, multipart);
516         int statusCode = res.getStatus();
517
518         // Check the status code of the response: does it match
519         // the expected response(s)?
520         if (logger.isDebugEnabled()) {
521             logger.debug(testName + ": status = " + statusCode);
522         }
523         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
524                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
525         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
526     }
527
528     // ---------------------------------------------------------------
529     // CRUD tests : DELETE tests
530     // ---------------------------------------------------------------
531     // Success outcomes
532     @Override
533     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
534     dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
535     public void delete(String testName) throws Exception {
536
537         // Perform setup.
538         setupDelete(testName);
539
540         // Submit the request to the service and store the response.
541         ClientResponse<Response> res = client.delete(knownResourceId);
542         int statusCode = res.getStatus();
543
544         // Check the status code of the response: does it match
545         // the expected response(s)?
546         if (logger.isDebugEnabled()) {
547             logger.debug(testName + ": status = " + statusCode);
548         }
549         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
550                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
551         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
552     }
553
554     // Failure outcomes
555     @Override
556     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
557     dependsOnMethods = {"delete"})
558     public void deleteNonExistent(String testName) throws Exception {
559
560         // Perform setup.
561         setupDeleteNonExistent(testName);
562
563         // Submit the request to the service and store the response.
564         ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
565         int statusCode = res.getStatus();
566
567         // Check the status code of the response: does it match
568         // the expected response(s)?
569         if (logger.isDebugEnabled()) {
570             logger.debug(testName + ": status = " + statusCode);
571         }
572         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
573                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
574         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
575     }
576
577     // ---------------------------------------------------------------
578     // Utility tests : tests of code used in tests above
579     // ---------------------------------------------------------------
580     /**
581      * Tests the code for manually submitting data that is used by several
582      * of the methods above.
583      */
584     @Test(dependsOnMethods = {"create", "read"})
585     public void testSubmitRequest() throws Exception {
586
587         // Expected status code: 200 OK
588         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
589
590         // Submit the request to the service and store the response.
591         String method = ServiceRequestType.READ.httpMethodName();
592         String url = getResourceURL(knownResourceId);
593         int statusCode = submitRequest(method, url);
594
595         // Check the status code of the response: does it match
596         // the expected response(s)?
597         if (logger.isDebugEnabled()) {
598             logger.debug("testSubmitRequest: url=" + url +
599                     " status=" + statusCode);
600         }
601         Assert.assertEquals(statusCode, EXPECTED_STATUS);
602
603     }
604
605     // ---------------------------------------------------------------
606     // Cleanup of resources created during testing
607     // ---------------------------------------------------------------
608     
609     /**
610      * Deletes any additional resources created by tests,
611      * after all tests have been run.
612      */
613     @AfterClass
614     public void cleanUp() {
615         if (logger.isDebugEnabled()) {
616             logger.debug("Cleaning up temporary resources created for testing ...");
617         }
618         for (String resourceId : additionalResourceIds) {
619             ClientResponse<Response> res = client.delete(resourceId);
620         }
621     }
622
623     // ---------------------------------------------------------------
624     // Utility methods used by tests above
625     // ---------------------------------------------------------------
626     private MultipartOutput createCollectionObjectInstance(String commonPartName,
627             String identifier) {
628         return createCollectionObjectInstance(commonPartName,
629                 "objectNumber-" + identifier,
630                 "objectName-" + identifier);
631     }
632
633     private MultipartOutput createCollectionObjectInstance(String commonPartName,
634             String objectNumber, String objectName) {
635         CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
636         OtherNumberList onList = new OtherNumberList();
637         List<String> ons = onList.getOtherNumber();
638         ons.add("urn:org.collectionspace.id:24082390");
639         ons.add("urn:org.walkerart.id:123");
640         collectionObject.setOtherNumbers(onList);
641         collectionObject.setObjectNumber(objectNumber);
642         collectionObject.setObjectName(objectName);
643         collectionObject.setAge(""); //test for null string
644         collectionObject.setBriefDescription("Papier mache bird mask with horns, " +
645                 "painted red with black and yellow spots. " +
646                 "Puerto Rico. ca. 8&quot; high, 6&quot; wide, projects 10&quot; (with horns).");
647         MultipartOutput multipart = new MultipartOutput();
648         OutputPart commonPart = multipart.addPart(collectionObject,
649                 MediaType.APPLICATION_XML_TYPE);
650         commonPart.getHeaders().add("label", commonPartName);
651
652         if (logger.isDebugEnabled()) {
653             logger.debug("to be created, collectionobject common");
654             logger.debug(objectAsXmlString(collectionObject,
655                 CollectionobjectsCommon.class));
656         }
657
658         CollectionobjectsNaturalhistory conh = new CollectionobjectsNaturalhistory();
659         conh.setNhString("test-string");
660         conh.setNhInt(999);
661         conh.setNhLong(9999);
662         OutputPart nhPart = multipart.addPart(conh, MediaType.APPLICATION_XML_TYPE);
663         nhPart.getHeaders().add("label", getNHPartName());
664
665         if (logger.isDebugEnabled()) {
666             logger.debug("to be created, collectionobject nhistory");
667             logger.debug(objectAsXmlString(conh,
668                 CollectionobjectsNaturalhistory.class));
669         }
670         return multipart;
671
672     }
673
674     private String getNHPartName() {
675         return "collectionobjects_naturalhistory";
676     }
677 }