]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
456710a529a75a80b3a81ec6c821a9ff5e1ad9ac
[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 (c)) 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.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import javax.ws.rs.core.MediaType;
30 import javax.ws.rs.core.Response;
31
32 import org.collectionspace.services.PersonJAXBSchema;
33 import org.collectionspace.services.client.CollectionSpaceClient;
34 import org.collectionspace.services.client.ContactClient;
35 import org.collectionspace.services.client.ContactClientUtils;
36 import org.collectionspace.services.contact.ContactsCommon;
37 import org.collectionspace.services.contact.ContactsCommonList;
38 import org.collectionspace.services.client.PersonAuthorityClient;
39 import org.collectionspace.services.client.PersonAuthorityClientUtils;
40 import org.collectionspace.services.jaxb.AbstractCommonList;
41 import org.collectionspace.services.person.PersonauthoritiesCommon;
42 import org.collectionspace.services.person.PersonauthoritiesCommonList;
43 import org.collectionspace.services.person.PersonsCommon;
44 import org.collectionspace.services.person.PersonsCommonList;
45 import org.jboss.resteasy.client.ClientResponse;
46 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
47 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
48 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51 import org.testng.Assert;
52 import org.testng.annotations.AfterClass;
53 import org.testng.annotations.Test;
54
55 /**
56  * PersonAuthorityServiceTest, carries out tests against a
57  * deployed and running PersonAuthority Service.
58  *
59  * $LastChangedRevision: 753 $
60  * $LastChangedDate: 2009-09-23 11:03:36 -0700 (Wed, 23 Sep 2009) $
61  */
62 public class PersonAuthorityServiceTest extends AbstractServiceTestImpl {
63
64     /** The logger. */
65     private final String CLASS_NAME = PersonAuthorityServiceTest.class.getName();
66     private final Logger logger = LoggerFactory.getLogger(CLASS_NAME);
67
68     // Instance variables specific to this test.
69     /** The service path component. */
70     final String SERVICE_PATH_COMPONENT = "personauthorities";
71     
72     /** The item service path component. */
73     final String ITEM_SERVICE_PATH_COMPONENT = "items";
74     
75     /** The contact service path component. */
76     final String CONTACT_SERVICE_PATH_COMPONENT = "contacts";
77     
78     /** The test forename. */
79     final String TEST_FORE_NAME = "John";
80     
81     /** The test middle name. */
82     final String TEST_MIDDLE_NAME = null;
83     
84     /** The test surname. */
85     final String TEST_SUR_NAME = "Wayne";
86     
87     /** The test birthdate. */
88     final String TEST_BIRTH_DATE = "May 26, 1907";
89     
90     /** The test death date. */
91     final String TEST_DEATH_DATE = "June 11, 1979";
92
93     // Hold some values for a recently created item to verify upon read.
94     private String knownResourceId = null;
95     private String knownResourceShortIdentifer = null;
96     private String knownResourceRefName = null;
97     private String knownItemResourceId = null;
98     private String knownItemResourceShortIdentifer = null;
99
100     // The resource ID of an item resource used for partial term matching tests.
101     private String knownItemPartialTermResourceId = null;
102     
103     /** The known contact resource id. */
104     private String knownContactResourceId = null;
105     
106     /** The n items to create in list. */
107     private int nItemsToCreateInList = 3;
108     
109     /** The all item resource ids created. */
110     private Map<String, String> allItemResourceIdsCreated =
111         new HashMap<String, String>();
112     
113     /** The all contact resource ids created. */
114     private Map<String, String> allContactResourceIdsCreated =
115         new HashMap<String, String>();
116
117     protected void setKnownResource( String id, String shortIdentifer,
118                 String refName ) {
119         knownResourceId = id;
120         knownResourceShortIdentifer = shortIdentifer;
121         knownResourceRefName = refName;
122     }
123
124     protected void setKnownItemResource( String id, String shortIdentifer ) {
125         knownItemResourceId = id;
126         knownItemResourceShortIdentifer = shortIdentifer;
127     }
128
129     
130     /* (non-Javadoc)
131      * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
132      */
133     @Override
134     protected CollectionSpaceClient getClientInstance() {
135         return new PersonAuthorityClient();
136     }
137     
138     /* (non-Javadoc)
139      * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse)
140      */
141     @Override
142         protected AbstractCommonList getAbstractCommonList(
143                         ClientResponse<AbstractCommonList> response) {
144         return response.getEntity(PersonsCommonList.class);
145     }
146  
147     // ---------------------------------------------------------------
148     // CRUD tests : CREATE tests
149     // ---------------------------------------------------------------
150     // Success outcomes
151     /* (non-Javadoc)
152      * @see org.collectionspace.services.client.test.ServiceTest#create(java.lang.String)
153      */
154     @Override
155     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
156         groups = {"create"})
157     public void create(String testName) throws Exception {
158         
159         if (logger.isDebugEnabled()) {
160             logger.debug(testBanner(testName, CLASS_NAME));
161         }
162         // Perform setup, such as initializing the type of service request
163         // (e.g. CREATE, DELETE), its valid and expected status codes, and
164         // its associated HTTP method name (e.g. POST, DELETE).
165         setupCreate();
166
167         // Submit the request to the service and store the response.
168         PersonAuthorityClient client = new PersonAuthorityClient();
169         String shortId = createIdentifier();
170         String displayName = "displayName-" + shortId;
171         String baseRefName = PersonAuthorityClientUtils.createPersonAuthRefName(shortId, null);
172         MultipartOutput multipart = 
173             PersonAuthorityClientUtils.createPersonAuthorityInstance(
174             displayName, shortId, client.getCommonPartName());
175         
176         String newID = null;
177         ClientResponse<Response> res = client.create(multipart);
178         try {
179                 int statusCode = res.getStatus();
180         
181                 // Check the status code of the response: does it match
182                 // the expected response(s)?
183                 //
184                 // Specifically:
185                 // Does it fall within the set of valid status codes?
186                 // Does it exactly match the expected status code?
187                 if(logger.isDebugEnabled()){
188                     logger.debug(testName + ": status = " + statusCode);
189                 }
190                 Assert.assertTrue(this.REQUEST_TYPE.isValidStatusCode(statusCode),
191                         invalidStatusCodeMessage(this.REQUEST_TYPE, statusCode));
192                 Assert.assertEquals(statusCode, this.EXPECTED_STATUS_CODE);
193         
194                 newID = PersonAuthorityClientUtils.extractId(res);
195         } finally {
196                 res.releaseConnection();
197         }
198         // Save values for additional tests
199         if (knownResourceId == null){
200                 setKnownResource( newID, shortId, baseRefName ); 
201                 if (logger.isDebugEnabled()) {
202                 logger.debug(testName + ": knownResourceId=" + knownResourceId);
203             }
204         }
205         // Store the IDs from every resource created by tests,
206         // so they can be deleted after tests have been run.
207         allResourceIdsCreated.add(newID);
208     }
209
210     /**
211      * Creates the item.
212      *
213      * @param testName the test name
214      */
215     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
216         groups = {"create"}, dependsOnMethods = {"create"})
217     public void createItem(String testName) {
218         if (logger.isDebugEnabled()) {
219             logger.debug(testBanner(testName, CLASS_NAME));
220         }
221         setupCreate();
222         String newID = createItemInAuthority(knownResourceId, knownResourceRefName);
223     }
224
225     /**
226      * Creates the item with an empty short identifier.
227      *
228      * @param testName the test name
229      */
230  /*
231     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
232         groups = {"create"}, dependsOnMethods = {"create"})
233     public void createItemWithEmptyShortId(String testName) {
234         if (logger.isDebugEnabled()) {
235             logger.debug(testBanner(testName, CLASS_NAME));
236         }
237         setupCreate();
238
239         // Fill the property map
240         String shortId = "";
241         Map<String, String> fieldProperties = new HashMap<String,String>();
242         fieldProperties.put(PersonJAXBSchema.DISPLAY_NAME_COMPUTED, "false");
243         fieldProperties.put(PersonJAXBSchema.DISPLAY_NAME, "Rod Beck");
244         fieldProperties.put(PersonJAXBSchema.SHORT_DISPLAY_NAME_COMPUTED, "false");
245         fieldProperties.put(PersonJAXBSchema.SHORT_DISPLAY_NAME, "RodBeck");
246
247         final Map NULL_REPEATABLE_FIELD_PROPERTIES = null;
248         String newID = createItemInAuthority(knownResourceId, knownResourceRefName,
249                 shortId, fieldProperties, NULL_REPEATABLE_FIELD_PROPERTIES);
250         allResourceIdsCreated.add(newID);
251     }
252 */
253
254     /**
255      * Creates an item in an authority, using test data.
256      *
257      * @param vcsid the vcsid
258      * @param authRefName the auth ref name
259      * @return the string
260      */
261     private String createItemInAuthority(String vcsid, String authRefName) {
262
263         final String testName = "createItemInAuthority";
264         if(logger.isDebugEnabled()){
265             logger.debug(testName + ":"+vcsid+"...");
266         }
267
268         Map<String, String> johnWayneMap = new HashMap<String,String>();
269         //
270         // Fill the property map
271         //
272         String shortId = "johnWayneActor";
273         johnWayneMap.put(PersonJAXBSchema.DISPLAY_NAME_COMPUTED, "false");
274         johnWayneMap.put(PersonJAXBSchema.DISPLAY_NAME, "John Wayne");
275         johnWayneMap.put(PersonJAXBSchema.SHORT_DISPLAY_NAME_COMPUTED, "false");
276         johnWayneMap.put(PersonJAXBSchema.SHORT_DISPLAY_NAME, "JohnWayne");
277         johnWayneMap.put(PersonJAXBSchema.SHORT_IDENTIFIER, shortId);
278
279         johnWayneMap.put(PersonJAXBSchema.FORE_NAME, TEST_FORE_NAME);
280         johnWayneMap.put(PersonJAXBSchema.SUR_NAME, TEST_SUR_NAME);
281         johnWayneMap.put(PersonJAXBSchema.GENDER, "male");
282         johnWayneMap.put(PersonJAXBSchema.BIRTH_DATE, TEST_BIRTH_DATE);
283         johnWayneMap.put(PersonJAXBSchema.BIRTH_PLACE, "Winterset, Iowa");
284         johnWayneMap.put(PersonJAXBSchema.DEATH_DATE, TEST_DEATH_DATE);
285         johnWayneMap.put(PersonJAXBSchema.BIO_NOTE, "born Marion Robert Morrison and better" +
286             "known by his stage name John Wayne, was an American film actor, director " +
287             "and producer. He epitomized rugged masculinity and has become an enduring " +
288             "American icon. He is famous for his distinctive voice, walk and height. " +
289             "He was also known for his conservative political views and his support in " +
290             "the 1950s for anti-communist positions.");
291
292         Map<String, List<String>> johnWayneRepeatablesMap = new HashMap<String,List<String>>();
293         List<String> johnWayneGroups = new ArrayList<String>();
294         johnWayneGroups.add("Irish");
295         johnWayneGroups.add("Scottish");
296         johnWayneRepeatablesMap.put(PersonJAXBSchema.GROUPS, johnWayneGroups);
297
298         return createItemInAuthority(vcsid, authRefName, shortId, johnWayneMap, johnWayneRepeatablesMap);
299
300     }
301
302     /**
303      * Creates an item in an authority.
304      *
305      * @param vcsid the vcsid
306      * @param authRefName the auth ref name
307      * @param itemFieldProperties a set of properties specifying the values of fields.
308      * @param itemRepeatableFieldProperties a set of properties specifying the values of repeatable fields.
309      * @return the string
310      */
311     private String createItemInAuthority(String vcsid, String authRefName, String shortId,
312             Map itemFieldProperties, Map itemRepeatableFieldProperties) {
313
314         final String testName = "createItemInAuthority";
315         if(logger.isDebugEnabled()){
316             logger.debug(testName + ":"+vcsid+"...");
317         }
318
319         // Submit the request to the service and store the response.
320         PersonAuthorityClient client = new PersonAuthorityClient();
321         
322         MultipartOutput multipart = 
323             PersonAuthorityClientUtils.createPersonInstance(vcsid, authRefName, itemFieldProperties,
324                 itemRepeatableFieldProperties, client.getItemCommonPartName() );
325
326         String newID = null;
327         ClientResponse<Response> res = client.createItem(vcsid, multipart);
328         try {
329                 int statusCode = res.getStatus();
330                 // Check the status code of the response: does it match
331                 // the expected response(s)?
332                 if(logger.isDebugEnabled()){
333                     logger.debug(testName + ": status = " + statusCode);
334                 }
335                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
336                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
337                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
338
339                 newID = PersonAuthorityClientUtils.extractId(res);
340         } finally {
341                 res.releaseConnection();
342         }
343
344         // Store the ID returned from the first item resource created
345         // for additional tests below.
346         if (knownItemResourceId == null){
347                 setKnownItemResource(newID, shortId);
348             if (logger.isDebugEnabled()) {
349                 logger.debug(testName + ": knownItemResourceId=" + knownItemResourceId);                
350             }
351         }
352         if(logger.isDebugEnabled()){
353             logger.debug(testName + " (created):"+vcsid+"/("+newID+","+shortId+")");
354         }
355
356         // Store the IDs from any item resources created
357         // by tests, along with the IDs of their parents, so these items
358         // can be deleted after all tests have been run.
359         allItemResourceIdsCreated.put(newID, vcsid);
360
361         return newID;
362     }
363
364     /**
365      * Creates the contact.
366      *
367      * @param testName the test name
368      */
369     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
370         groups = {"create"}, dependsOnMethods = {"createItem"})
371     public void createContact(String testName) {
372         if (logger.isDebugEnabled()) {
373             logger.debug(testBanner(testName, CLASS_NAME));
374         }
375         setupCreate();
376         String newID = createContactInItem(knownResourceId, knownItemResourceId);
377     }
378
379    /**
380     * Creates the contact in item.
381     *
382     * @param parentcsid the parentcsid
383     * @param itemcsid the itemcsid
384     * @return the string
385     */
386    private String createContactInItem(String parentcsid, String itemcsid) {
387
388         final String testName = "createContactInItem";
389         if(logger.isDebugEnabled()){
390             logger.debug(testName + ":...");
391         }
392         
393         setupCreate();
394
395         // Submit the request to the service and store the response.
396         PersonAuthorityClient client = new PersonAuthorityClient();
397         String identifier = createIdentifier();
398         MultipartOutput multipart =
399             ContactClientUtils.createContactInstance(parentcsid,
400             itemcsid, identifier, new ContactClient().getCommonPartName());
401         
402         String newID = null;
403         ClientResponse<Response> res =
404              client.createContact(parentcsid, itemcsid, multipart);
405         try {
406                 int statusCode = res.getStatus();
407                 // Check the status code of the response: does it match
408                 // the expected response(s)?
409                 if(logger.isDebugEnabled()){
410                     logger.debug(testName + ": status = " + statusCode);
411                 }
412                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
413                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
414                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
415
416                 newID = PersonAuthorityClientUtils.extractId(res);
417         } finally {
418                 res.releaseConnection();
419         }
420
421         // Store the ID returned from the first contact resource created
422         // for additional tests below.
423         if (knownContactResourceId == null){
424             knownContactResourceId = newID;
425             if (logger.isDebugEnabled()) {
426                 logger.debug(testName + ": knownContactResourceId=" + knownContactResourceId);
427             }
428         }
429
430         // Store the IDs from any contact resources created
431         // by tests, along with the IDs of their parent items,
432         // so these items can be deleted after all tests have been run.
433         allContactResourceIdsCreated.put(newID, itemcsid);
434
435         return newID;
436     }
437
438     // Failure outcomes
439
440     // Placeholders until the three tests below can be uncommented.
441     // See Issue CSPACE-401.
442     /* (non-Javadoc)
443      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithEmptyEntityBody(java.lang.String)
444      */
445     @Override
446     public void createWithEmptyEntityBody(String testName) throws Exception {
447         //Should this really be empty?
448     }
449
450     /* (non-Javadoc)
451      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithMalformedXml(java.lang.String)
452      */
453     @Override
454     public void createWithMalformedXml(String testName) throws Exception {
455         //Should this really be empty?
456     }
457
458     /* (non-Javadoc)
459      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithWrongXmlSchema(java.lang.String)
460      */
461     @Override
462     public void createWithWrongXmlSchema(String testName) throws Exception {
463         //Should this really be empty?
464     }
465
466 /*
467     @Override
468     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
469         groups = {"create"}, dependsOnMethods = {"create", "testSubmitRequest"})
470     public void createWithEmptyEntityBody(String testName) throws Exception {
471
472         if (logger.isDebugEnabled()) {
473             logger.debug(testBanner(testName, CLASS_NAME));
474         }
475         // Perform setup.
476         setupCreateWithEmptyEntityBody();
477
478         // Submit the request to the service and store the response.
479         String method = REQUEST_TYPE.httpMethodName();
480         String url = getServiceRootURL();
481         String mediaType = MediaType.APPLICATION_XML;
482         final String entity = "";
483         int statusCode = submitRequest(method, url, mediaType, entity);
484
485         // Check the status code of the response: does it match
486         // the expected response(s)?
487         if(logger.isDebugEnabled()) {
488             logger.debug(testName + ": url=" + url +
489                 " status=" + statusCode);
490          }
491         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
492         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
493         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
494     }
495
496     @Override
497     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
498         groups = {"create"}, dependsOnMethods = {"create", "testSubmitRequest"})
499     public void createWithMalformedXml(String testName) throws Exception {
500
501         if (logger.isDebugEnabled()) {
502             logger.debug(testBanner(testName, CLASS_NAME));
503         }
504         // Perform setup.
505         setupCreateWithMalformedXml();
506
507         // Submit the request to the service and store the response.
508         String method = REQUEST_TYPE.httpMethodName();
509         String url = getServiceRootURL();
510         String mediaType = MediaType.APPLICATION_XML;
511         final String entity = MALFORMED_XML_DATA; // Constant from base class.
512         int statusCode = submitRequest(method, url, mediaType, entity);
513
514         // Check the status code of the response: does it match
515         // the expected response(s)?
516         if(logger.isDebugEnabled()){
517             logger.debug(testName + ": url=" + url +
518                 " status=" + statusCode);
519          }
520         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
521         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
522         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
523     }
524
525     @Override
526     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
527         groups = {"create"}, dependsOnMethods = {"create", "testSubmitRequest"})
528     public void createWithWrongXmlSchema(String testName) throws Exception {
529
530         if (logger.isDebugEnabled()) {
531             logger.debug(testBanner(testName, CLASS_NAME));
532         }
533         // Perform setup.
534         setupCreateWithWrongXmlSchema();
535
536         // Submit the request to the service and store the response.
537         String method = REQUEST_TYPE.httpMethodName();
538         String url = getServiceRootURL();
539         String mediaType = MediaType.APPLICATION_XML;
540         final String entity = WRONG_XML_SCHEMA_DATA;
541         int statusCode = submitRequest(method, url, mediaType, entity);
542
543         // Check the status code of the response: does it match
544         // the expected response(s)?
545         if(logger.isDebugEnabled()){
546             logger.debug(testName + ": url=" + url +
547                 " 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
555     /**
556      * Attempts to create an authority with an short identifier that contains
557      * non-word characters.
558      *
559      * @param testName the test name
560      */
561     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
562         groups = {"create", "nonWordCharsInShortId"})
563     public void createWithShortIdNonWordChars(String testName) throws Exception {
564         if (logger.isDebugEnabled()) {
565             logger.debug(testBanner(testName, CLASS_NAME));
566         }
567         EXPECTED_STATUS_CODE = STATUS_BAD_REQUEST;
568         REQUEST_TYPE = ServiceRequestType.CREATE;
569         testSetup(EXPECTED_STATUS_CODE, REQUEST_TYPE);
570
571         // Create the payload to be included in the body of the request
572         PersonAuthorityClient client = new PersonAuthorityClient();
573         String shortId = createIdentifier() + "*" + createIdentifier();
574         String displayName = "displayName-" + shortId;
575         MultipartOutput multipart =
576             PersonAuthorityClientUtils.createPersonAuthorityInstance(
577             displayName, shortId, client.getCommonPartName());
578
579         // Submit the request to the service and store the response.
580         ClientResponse<Response> res = client.create(multipart);
581
582         // Check the status code of the response: does it match
583         // the expected response(s)?
584         try {
585             int statusCode = res.getStatus();
586             if(logger.isDebugEnabled()){
587                 logger.debug(testName + ": status = " + statusCode);
588             }
589             Assert.assertTrue(this.REQUEST_TYPE.isValidStatusCode(statusCode),
590                     invalidStatusCodeMessage(this.REQUEST_TYPE, statusCode));
591             Assert.assertEquals(statusCode, this.EXPECTED_STATUS_CODE);
592         } finally {
593                 res.releaseConnection();
594         }
595
596     }
597
598     /**
599      * Attempts to create an item with an short identifier that contains
600      * non-word characters.
601      *
602      * @param testName the test name
603      */
604     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
605         groups = {"create", "nonWordCharsInShortId"}, dependsOnMethods = {"create"})
606     public void createItemWithShortIdNonWordChars(String testName) {
607         if (logger.isDebugEnabled()) {
608             logger.debug(testBanner(testName, CLASS_NAME));
609         }
610         EXPECTED_STATUS_CODE = STATUS_BAD_REQUEST;
611         REQUEST_TYPE = ServiceRequestType.CREATE;
612         testSetup(EXPECTED_STATUS_CODE, REQUEST_TYPE);
613
614          PersonAuthorityClient client = new PersonAuthorityClient();
615
616         // Create the payload to be included in the body of the request
617         String shortId = "7-Eleven";
618         Map<String, String> fieldProperties = new HashMap<String,String>();
619         fieldProperties.put(PersonJAXBSchema.DISPLAY_NAME_COMPUTED, "false");
620         fieldProperties.put(PersonJAXBSchema.DISPLAY_NAME, shortId);
621         fieldProperties.put(PersonJAXBSchema.SHORT_DISPLAY_NAME_COMPUTED, "false");
622         fieldProperties.put(PersonJAXBSchema.SHORT_DISPLAY_NAME, shortId);
623         fieldProperties.put(PersonJAXBSchema.SHORT_IDENTIFIER, shortId);
624         final Map NULL_REPEATABLE_FIELD_PROPERTIES = null;
625         MultipartOutput multipart =
626             PersonAuthorityClientUtils.createPersonInstance(knownResourceId,
627                 knownResourceRefName, fieldProperties,
628                 NULL_REPEATABLE_FIELD_PROPERTIES, client.getItemCommonPartName());
629         
630         // Send the request and receive a response
631         ClientResponse<Response> res = client.createItem(knownResourceId, multipart);
632
633         // Check the status code of the response: does it match
634         // the expected response(s)?
635         try {
636             int statusCode = res.getStatus();
637             // Check the status code of the response: does it match
638             // the expected response(s)?
639             if(logger.isDebugEnabled()){
640                 logger.debug(testName + ": status = " + statusCode);
641             }
642             Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
643                     invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
644             Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
645         } finally {
646                 res.releaseConnection();
647
648         }
649     }
650
651     // ---------------------------------------------------------------
652     // CRUD tests : CREATE LIST tests
653     // ---------------------------------------------------------------
654     // Success outcomes
655     /* (non-Javadoc)
656  * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createList(java.lang.String)
657  */
658     @Override
659     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
660         groups = {"createList"}, dependsOnGroups = {"create"})
661     public void createList(String testName) throws Exception {
662          if (logger.isDebugEnabled()) {
663             logger.debug(testBanner(testName, CLASS_NAME));
664         }
665         for (int i = 0; i < nItemsToCreateInList; i++) {
666             create(testName);
667         }
668     }
669
670     /**
671      * Creates the item list.
672      *
673      * @param testName the test name
674      * @throws Exception the exception
675      */
676     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
677         groups = {"createList"}, dependsOnMethods = {"createList"})
678     public void createItemList(String testName) throws Exception {
679         if (logger.isDebugEnabled()) {
680             logger.debug(testBanner(testName, CLASS_NAME));
681         }
682         // Add items to the initially-created, known parent record.
683         for (int j = 0; j < nItemsToCreateInList; j++) {
684             createItem(testName);
685         }
686     }
687
688     /**
689      * Creates the contact list.
690      *
691      * @param testName the test name
692      * @throws Exception the exception
693      */
694     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
695         groups = {"createList"}, dependsOnMethods = {"createItemList"})
696     public void createContactList(String testName) throws Exception {
697         // Add contacts to the initially-created, known item record.
698         for (int j = 0; j < nItemsToCreateInList; j++) {
699             createContact(testName);
700         }
701     }
702
703     // ---------------------------------------------------------------
704     // CRUD tests : READ tests
705     // ---------------------------------------------------------------
706     // Success outcomes
707     /* (non-Javadoc)
708      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#read(java.lang.String)
709      */
710     @Override
711     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
712         groups = {"read"}, dependsOnGroups = {"create"})
713     public void read(String testName) throws Exception {
714         readInternal(testName, knownResourceId, null);
715     }
716
717     /**
718      * Read by name.
719      *
720      * @param testName the test name
721      * @throws Exception the exception
722      */
723     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
724             groups = {"read"}, dependsOnMethods = {"read"})
725         public void readByName(String testName) throws Exception {
726         readInternal(testName, null, knownResourceShortIdentifer);
727     }
728     
729     protected void readInternal(String testName, String CSID, String shortId) {
730         if (logger.isDebugEnabled()) {
731             logger.debug(testBanner(testName, CLASS_NAME));
732         }
733         // Perform setup.
734         setupRead();
735
736         // Submit the request to the service and store the response.
737         PersonAuthorityClient client = new PersonAuthorityClient();
738         ClientResponse<MultipartInput> res = null;
739         if(CSID!=null) {
740             res = client.read(CSID);
741         } else if(shortId!=null) {
742                 res = client.readByName(shortId);
743         } else {
744                 Assert.fail("readInternal: Internal error. One of CSID or shortId must be non-null");
745         }
746         try {
747                 int statusCode = res.getStatus();
748                 // Check the status code of the response: does it match
749                 // the expected response(s)?
750                 if(logger.isDebugEnabled()){
751                     logger.debug(testName + ": status = " + statusCode);
752                 }
753                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
754                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
755                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
756                 //FIXME: remove the following try catch once Aron fixes signatures
757                 try {
758                     MultipartInput input = (MultipartInput) res.getEntity();
759                     PersonauthoritiesCommon personAuthority = (PersonauthoritiesCommon) extractPart(input,
760                             client.getCommonPartName(), PersonauthoritiesCommon.class);
761                     Assert.assertNotNull(personAuthority);
762                 } catch (Exception e) {
763                     throw new RuntimeException(e);
764                 }
765         } finally {
766                 res.releaseConnection();
767         }
768     }
769
770     /**
771      * Read item.
772      *
773      * @param testName the test name
774      * @throws Exception the exception
775      */
776     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
777                 groups = {"readItem"}, dependsOnGroups = {"read"})
778     public void readItem(String testName) throws Exception {
779         readItemInternal(testName, knownResourceId, null, knownItemResourceId, null);
780     }
781
782     /**
783      * Read item in Named Auth.
784      *
785      * @param testName the test name
786      * @throws Exception the exception
787      */
788     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
789                 groups = {"readItem"}, dependsOnMethods = {"readItem"})
790     public void readItemInNamedAuth(String testName) throws Exception {
791         readItemInternal(testName, null, knownResourceShortIdentifer, knownItemResourceId, null);
792     }
793
794     /**
795      * Read named item.
796      *
797      * @param testName the test name
798      * @throws Exception the exception
799      */
800     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
801                 groups = {"readItem"}, dependsOnMethods = {"readItem"})
802     public void readNamedItem(String testName) throws Exception {
803         readItemInternal(testName, knownResourceId, null, null, knownItemResourceShortIdentifer);
804     }
805
806     /**
807      * Read Named item in Named Auth.
808      *
809      * @param testName the test name
810      * @throws Exception the exception
811      */
812     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
813                 groups = {"readItem"}, dependsOnMethods = {"readItem"})
814     public void readNamedItemInNamedAuth(String testName) throws Exception {
815         readItemInternal(testName, null, knownResourceShortIdentifer, null, knownItemResourceShortIdentifer);
816     }
817
818     protected void readItemInternal(String testName, 
819                 String authCSID, String authShortId, String itemCSID, String itemShortId) 
820         throws Exception {
821
822         if (logger.isDebugEnabled()) {
823             logger.debug(testBanner(testName, CLASS_NAME));
824             logger.debug("Reading:"+((authCSID!=null)?authCSID:authShortId)+"/"+
825                         ((itemCSID!=null)?authCSID:itemShortId));
826         }
827         // Perform setup.
828         setupRead();
829
830         // Submit the request to the service and store the response.
831         PersonAuthorityClient client = new PersonAuthorityClient();
832         ClientResponse<MultipartInput> res = null;
833         if(authCSID!=null) {
834             if(itemCSID!=null) {
835                 res = client.readItem(authCSID, itemCSID);
836             } else if(itemShortId!=null) {
837                 res = client.readNamedItem(authCSID, itemShortId);
838             } else {
839                 Assert.fail("readInternal: Internal error. One of CSID or shortId must be non-null");
840             }
841         } else if(authShortId!=null) {
842             if(itemCSID!=null) {
843                 res = client.readItemInNamedAuthority(authShortId, itemCSID);
844             } else if(itemShortId!=null) {
845                 res = client.readNamedItemInNamedAuthority(authShortId, itemShortId);
846             } else {
847                 Assert.fail("readInternal: Internal error. One of CSID or shortId must be non-null");
848             }
849         } else {
850                 Assert.fail("readInternal: Internal error. One of authCSID or authShortId must be non-null");
851         }
852         try {
853                 int statusCode = res.getStatus();
854         
855                 // Check the status code of the response: does it match
856                 // the expected response(s)?
857                 if(logger.isDebugEnabled()){
858                     logger.debug(testName + ": status = " + statusCode);
859                 }
860                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
861                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
862                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
863         
864                 // Check whether we've received a person.
865                 MultipartInput input = (MultipartInput) res.getEntity();
866                 PersonsCommon person = (PersonsCommon) extractPart(input,
867                         client.getItemCommonPartName(), PersonsCommon.class);
868                 Assert.assertNotNull(person);
869                 boolean showFull = true;
870                 if(showFull && logger.isDebugEnabled()){
871                     logger.debug(testName + ": returned payload:");
872                     logger.debug(objectAsXmlString(person, PersonsCommon.class));
873                 }
874
875                 // Check that the person item is within the expected Person Authority.
876                 Assert.assertEquals(person.getInAuthority(), knownResourceId);
877
878                 // Verify the number and contents of values in a repeatable field,
879                 // as created in the instance record used for testing.
880                 List<String> groups = person.getGroups().getGroup();
881                 Assert.assertTrue(groups.size() > 0);
882                 Assert.assertNotNull(groups.get(0));
883
884         } finally {
885                 res.releaseConnection();
886         }
887     }
888
889     /**
890      * Verify item display name.
891      *
892      * @param testName the test name
893      * @throws Exception the exception
894      */
895     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
896                 groups = {"update"}, dependsOnMethods = {"updateItem"})
897     public void verifyItemDisplayNames(String testName) throws Exception {
898         
899          if (logger.isDebugEnabled()) {
900             logger.debug(testBanner(testName, CLASS_NAME));
901         }
902         // Perform setup.
903         setupUpdate();
904
905         // Submit the request to the service and store the response.
906         PersonAuthorityClient client = new PersonAuthorityClient();
907         MultipartInput input =null;
908         ClientResponse<MultipartInput> res = client.readItem(knownResourceId, knownItemResourceId);
909         try {
910                 int statusCode = res.getStatus();
911         
912                 // Check the status code of the response: does it match
913                 // the expected response(s)?
914                 if(logger.isDebugEnabled()){
915                     logger.debug(testName + ": status = " + statusCode);
916                 }
917                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
918                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
919                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
920         
921                 // Check whether person has expected displayName.
922                 input = (MultipartInput) res.getEntity();
923         } finally {
924                 res.releaseConnection();
925         }
926                 
927         PersonsCommon person = (PersonsCommon) extractPart(input,
928                 client.getItemCommonPartName(), PersonsCommon.class);
929         Assert.assertNotNull(person);
930         String displayName = person.getDisplayName();
931         // Make sure displayName matches computed form
932         String expectedDisplayName = 
933             PersonAuthorityClientUtils.prepareDefaultDisplayName(
934                 TEST_FORE_NAME, null, TEST_SUR_NAME,
935                 TEST_BIRTH_DATE, TEST_DEATH_DATE);
936         Assert.assertFalse(displayName.equals(expectedDisplayName));
937     
938         String shortDisplayName = person.getShortDisplayName();
939         // Make sure displayName matches computed form
940         String expectedShortDisplayName = 
941             PersonAuthorityClientUtils.prepareDefaultDisplayName(
942                         TEST_FORE_NAME, null, TEST_SUR_NAME,null, null);
943         Assert.assertFalse(expectedShortDisplayName.equals(shortDisplayName));
944     
945         // Update the forename and verify the computed name is updated.
946         person.setCsid(null);
947         person.setDisplayNameComputed(true);
948         person.setShortDisplayNameComputed(true);
949         person.setForeName("updated-" + TEST_FORE_NAME);
950         expectedDisplayName = 
951             PersonAuthorityClientUtils.prepareDefaultDisplayName(
952                 "updated-" + TEST_FORE_NAME, null, TEST_SUR_NAME, 
953                 TEST_BIRTH_DATE, TEST_DEATH_DATE);
954         expectedShortDisplayName = 
955             PersonAuthorityClientUtils.prepareDefaultDisplayName(
956                         "updated-" + TEST_FORE_NAME, null, TEST_SUR_NAME,null, null);
957
958         // Submit the updated resource to the service and store the response.
959         MultipartOutput output = new MultipartOutput();
960         OutputPart commonPart = output.addPart(person, MediaType.APPLICATION_XML_TYPE);
961         commonPart.getHeaders().add("label", client.getItemCommonPartName());
962         res = client.updateItem(knownResourceId, knownItemResourceId, output);
963         try {
964                 int statusCode = res.getStatus();
965         
966                 // Check the status code of the response: does it match the expected response(s)?
967                 if(logger.isDebugEnabled()){
968                     logger.debug("updateItem: status = " + statusCode);
969                 }
970                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
971                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
972                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
973         
974                 // Retrieve the updated resource and verify that its contents exist.
975                 input = (MultipartInput) res.getEntity();
976         } finally {
977                 res.releaseConnection();
978         }
979         
980         PersonsCommon updatedPerson =
981                 (PersonsCommon) extractPart(input,
982                         client.getItemCommonPartName(), PersonsCommon.class);
983         Assert.assertNotNull(updatedPerson);
984
985         // Verify that the updated resource received the correct data.
986         Assert.assertEquals(updatedPerson.getForeName(), person.getForeName(),
987             "Updated ForeName in Person did not match submitted data.");
988         // Verify that the updated resource computes the right displayName.
989         Assert.assertEquals(updatedPerson.getDisplayName(), expectedDisplayName,
990             "Updated ForeName in Person not reflected in computed DisplayName.");
991         // Verify that the updated resource computes the right displayName.
992         Assert.assertEquals(updatedPerson.getShortDisplayName(), expectedShortDisplayName,
993             "Updated ForeName in Person not reflected in computed ShortDisplayName.");
994
995         // Now Update the displayName, not computed and verify the computed name is overriden.
996         person.setDisplayNameComputed(false);
997         expectedDisplayName = "TestName";
998         person.setDisplayName(expectedDisplayName);
999         person.setShortDisplayNameComputed(false);
1000         person.setShortDisplayName(expectedDisplayName);
1001
1002         // Submit the updated resource to the service and store the response.
1003         output = new MultipartOutput();
1004         commonPart = output.addPart(person, MediaType.APPLICATION_XML_TYPE);
1005         commonPart.getHeaders().add("label", client.getItemCommonPartName());
1006         res = client.updateItem(knownResourceId, knownItemResourceId, output);
1007         try {
1008                 int statusCode = res.getStatus();
1009         
1010                 // Check the status code of the response: does it match the expected response(s)?
1011                 if(logger.isDebugEnabled()){
1012                     logger.debug("updateItem: status = " + statusCode);
1013                 }
1014                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1015                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1016                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1017         
1018                 // Retrieve the updated resource and verify that its contents exist.
1019                 input = (MultipartInput) res.getEntity();
1020         } finally {
1021                 res.releaseConnection();
1022         }
1023         
1024         updatedPerson =
1025                 (PersonsCommon) extractPart(input,
1026                         client.getItemCommonPartName(), PersonsCommon.class);
1027         Assert.assertNotNull(updatedPerson);
1028
1029         // Verify that the updated resource received the correct data.
1030         Assert.assertEquals(updatedPerson.isDisplayNameComputed(), false,
1031                 "Updated displayNameComputed in Person did not match submitted data.");
1032         // Verify that the updated resource computes the right displayName.
1033         Assert.assertEquals(updatedPerson.getDisplayName(),
1034                         expectedDisplayName,
1035                 "Updated DisplayName (not computed) in Person not stored.");
1036         // Verify that the updated resource received the correct data.
1037         Assert.assertEquals(updatedPerson.isShortDisplayNameComputed(), false,
1038                 "Updated shortDisplayNameComputed in Person did not match submitted data.");
1039         // Verify that the updated resource computes the right displayName.
1040         Assert.assertEquals(updatedPerson.getShortDisplayName(),
1041                         expectedDisplayName,
1042                 "Updated ShortDisplayName (not computed) in Person not stored.");
1043     }
1044
1045     /**
1046      * Verify illegal item display name.
1047      *
1048      * @param testName the test name
1049      * @throws Exception the exception
1050      */
1051     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1052                 groups = {"update"}, dependsOnMethods = {"verifyItemDisplayNames"})
1053     public void verifyIllegalItemDisplayName(String testName) throws Exception {
1054
1055         if (logger.isDebugEnabled()) {
1056             logger.debug(testBanner(testName, CLASS_NAME));
1057         }
1058         // Perform setup.
1059         testSetup(STATUS_BAD_REQUEST, ServiceRequestType.UPDATE);
1060         // setupUpdateWithWrongXmlSchema(testName);
1061
1062         // Submit the request to the service and store the response.
1063         PersonAuthorityClient client = new PersonAuthorityClient();
1064         MultipartInput input = null;
1065         ClientResponse<MultipartInput> res = client.readItem(knownResourceId, knownItemResourceId);
1066         try {
1067                 int statusCode = res.getStatus();
1068         
1069                 // Check the status code of the response: does it match
1070                 // the expected response(s)?
1071                 if(logger.isDebugEnabled()){
1072                     logger.debug(testName + ": status = " + statusCode);
1073                 }
1074                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1075                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1076                 Assert.assertEquals(statusCode, Response.Status.OK.getStatusCode());
1077         
1078                 // Check whether Person has expected displayName.
1079                 input = (MultipartInput) res.getEntity();
1080         } finally {
1081                 res.releaseConnection();
1082         }
1083         
1084         PersonsCommon person = (PersonsCommon) extractPart(input,
1085                 client.getItemCommonPartName(), PersonsCommon.class);
1086         Assert.assertNotNull(person);
1087         // Try to Update with computed false and no displayName
1088         person.setDisplayNameComputed(false);
1089         person.setDisplayName(null);
1090
1091         // Submit the updated resource to the service and store the response.
1092         MultipartOutput output = new MultipartOutput();
1093         OutputPart commonPart = output.addPart(person, MediaType.APPLICATION_XML_TYPE);
1094         commonPart.getHeaders().add("label", client.getItemCommonPartName());
1095         res = client.updateItem(knownResourceId, knownItemResourceId, output);
1096         try {
1097                 int statusCode = res.getStatus();
1098         
1099                 // Check the status code of the response: does it match the expected response(s)?
1100                 if(logger.isDebugEnabled()){
1101                     logger.debug("updateItem: status = " + statusCode);
1102                 }
1103                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1104                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1105                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1106         } finally {
1107                 res.releaseConnection();
1108         }
1109     }
1110     
1111     /**
1112      * Read contact.
1113      *
1114      * @param testName the test name
1115      * @throws Exception the exception
1116      */
1117     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1118         groups = {"readItem"}, dependsOnMethods = {"readItem"})
1119     public void readContact(String testName) throws Exception {
1120         
1121         if (logger.isDebugEnabled()) {
1122             logger.debug(testBanner(testName, CLASS_NAME));
1123         }
1124         // Perform setup.
1125         setupRead();
1126
1127         // Submit the request to the service and store the response.
1128         PersonAuthorityClient client = new PersonAuthorityClient();
1129         MultipartInput input = null;
1130         ClientResponse<MultipartInput> res =
1131             client.readContact(knownResourceId, knownItemResourceId,
1132             knownContactResourceId);
1133         try {
1134                 int statusCode = res.getStatus();
1135         
1136                 // Check the status code of the response: does it match
1137                 // the expected response(s)?
1138                 if(logger.isDebugEnabled()){
1139                     logger.debug(testName + ": status = " + statusCode);
1140                 }
1141                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1142                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1143                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1144         
1145                 // Check whether we've received a contact.
1146                 input = (MultipartInput) res.getEntity();
1147         } finally {
1148                 res.releaseConnection();
1149         }
1150         
1151         ContactsCommon contact = (ContactsCommon) extractPart(input,
1152                 new ContactClient().getCommonPartName(), ContactsCommon.class);
1153         Assert.assertNotNull(contact);
1154         boolean showFull = true;
1155         if(showFull && logger.isDebugEnabled()){
1156             logger.debug(testName + ": returned payload:");
1157             logger.debug(objectAsXmlString(contact, ContactsCommon.class));
1158         }
1159         Assert.assertEquals(contact.getInAuthority(), knownResourceId);
1160         Assert.assertEquals(contact.getInItem(), knownItemResourceId);
1161
1162     }
1163
1164     // Failure outcomes
1165     /* (non-Javadoc)
1166      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readNonExistent(java.lang.String)
1167      */
1168     @Override
1169     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1170         groups = {"read"}, dependsOnMethods = {"read"})
1171     public void readNonExistent(String testName) {
1172
1173         if (logger.isDebugEnabled()) {
1174             logger.debug(testBanner(testName, CLASS_NAME));
1175         }
1176         // Perform setup.
1177         setupReadNonExistent();
1178
1179         // Submit the request to the service and store the response.
1180         PersonAuthorityClient client = new PersonAuthorityClient();
1181         ClientResponse<MultipartInput> res = client.read(NON_EXISTENT_ID);
1182         try {
1183                 int statusCode = res.getStatus();
1184                 // Check the status code of the response: does it match
1185                 // the expected response(s)?
1186                 if(logger.isDebugEnabled()){
1187                     logger.debug(testName + ": status = " + statusCode);
1188                 }
1189                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1190                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1191                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1192         } finally {
1193                 res.releaseConnection();
1194         }
1195     }
1196
1197     /**
1198      * Read item non existent.
1199      *
1200      * @param testName the test name
1201      */
1202     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1203         groups = {"readItem"}, dependsOnMethods = {"readItem"})
1204     public void readItemNonExistent(String testName) {
1205
1206         if (logger.isDebugEnabled()) {
1207             logger.debug(testBanner(testName, CLASS_NAME));
1208         }
1209         // Perform setup.
1210         setupReadNonExistent();
1211
1212         // Submit the request to the service and store the response.
1213         PersonAuthorityClient client = new PersonAuthorityClient();
1214         ClientResponse<MultipartInput> res = client.readItem(knownResourceId, NON_EXISTENT_ID);
1215         try {
1216                 int statusCode = res.getStatus();
1217         
1218                 // Check the status code of the response: does it match
1219                 // the expected response(s)?
1220                 if(logger.isDebugEnabled()){
1221                     logger.debug(testName + ": status = " + statusCode);
1222                 }
1223                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1224                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1225                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1226         } finally {
1227                 res.releaseConnection();
1228         }
1229     }
1230
1231     /**
1232      * Read contact non existent.
1233      *
1234      * @param testName the test name
1235      */
1236     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1237         groups = {"readItem"}, dependsOnMethods = {"readContact"})
1238     public void readContactNonExistent(String testName) {
1239
1240         if (logger.isDebugEnabled()) {
1241             logger.debug(testBanner(testName, CLASS_NAME));
1242         }
1243         // Perform setup.
1244         setupReadNonExistent();
1245
1246         // Submit the request to the service and store the response.
1247         PersonAuthorityClient client = new PersonAuthorityClient();
1248         ClientResponse<MultipartInput> res =
1249             client.readContact(knownResourceId, knownItemResourceId, NON_EXISTENT_ID);
1250         try {
1251                 int statusCode = res.getStatus();
1252         
1253                 // Check the status code of the response: does it match
1254                 // the expected response(s)?
1255                 if(logger.isDebugEnabled()){
1256                     logger.debug(testName + ": status = " + statusCode);
1257                 }
1258                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1259                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1260                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1261         } finally {
1262                 res.releaseConnection();
1263         }
1264     }
1265
1266     // ---------------------------------------------------------------
1267     // CRUD tests : READ_LIST tests
1268     // ---------------------------------------------------------------
1269     // Success outcomes
1270
1271     /* (non-Javadoc)
1272      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readList(java.lang.String)
1273      */
1274     @Override
1275     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1276         groups = {"readList"}, dependsOnGroups = {"createList", "read"})
1277     public void readList(String testName) throws Exception {
1278
1279         if (logger.isDebugEnabled()) {
1280             logger.debug(testBanner(testName, CLASS_NAME));
1281         }
1282         // Perform setup.
1283         setupReadList();
1284
1285         // Submit the request to the service and store the response.
1286         PersonAuthorityClient client = new PersonAuthorityClient();
1287         PersonauthoritiesCommonList list = null;
1288         ClientResponse<PersonauthoritiesCommonList> res = client.readList();
1289         try {
1290                 int statusCode = res.getStatus();
1291         
1292                 // Check the status code of the response: does it match
1293                 // the expected response(s)?
1294                 if(logger.isDebugEnabled()){
1295                     logger.debug(testName + ": status = " + statusCode);
1296                 }
1297                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1298                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1299                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1300         
1301                 list = res.getEntity();
1302         } finally {
1303                 res.releaseConnection();
1304         }
1305
1306         // Optionally output additional data about list members for debugging.
1307         boolean iterateThroughList = false;
1308         if (iterateThroughList && logger.isDebugEnabled()) {
1309             List<PersonauthoritiesCommonList.PersonauthorityListItem> items =
1310                     list.getPersonauthorityListItem();
1311             int i = 0;
1312             for (PersonauthoritiesCommonList.PersonauthorityListItem item : items) {
1313                 String csid = item.getCsid();
1314                 logger.debug(testName + ": list-item[" + i + "] csid=" +
1315                         csid);
1316                 logger.debug(testName + ": list-item[" + i + "] displayName=" +
1317                         item.getDisplayName());
1318                 logger.debug(testName + ": list-item[" + i + "] URI=" +
1319                         item.getUri());
1320                 readItemList(csid, null, testName);
1321                 i++;
1322             }
1323         }
1324     }
1325
1326     /**
1327      * Read item list.
1328      */
1329     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1330                 groups = {"readList"}, dependsOnMethods = {"readList"})
1331     public void readItemList(String testName) {
1332         readItemList(knownResourceId, null, testName);
1333     }
1334
1335     /**
1336      * Read item list by authority name.
1337      */
1338     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1339                 groups = {"readList"}, dependsOnMethods = {"readItemList"})
1340     public void readItemListByAuthorityName(String testName) {
1341         readItemList(null, knownResourceShortIdentifer, testName);
1342     }
1343     
1344     /**
1345      * Read item list.
1346      *
1347      * @param vcsid the vcsid
1348      * @param name the name
1349      */
1350     private void readItemList(String vcsid, String name, String testName) {
1351
1352         // Perform setup.
1353         setupReadList();
1354         
1355         // Submit the request to the service and store the response.
1356         PersonAuthorityClient client = new PersonAuthorityClient();
1357         ClientResponse<PersonsCommonList> res = null;
1358         if (vcsid!= null) {
1359                 res = client.readItemList(vcsid, null, null);
1360         } else if (name!= null) {
1361                 res = client.readItemListForNamedAuthority(name, null, null);
1362         } else {
1363                 Assert.fail("readItemList passed null csid and name!");
1364         }
1365         PersonsCommonList list = null;
1366         try {
1367                 int statusCode = res.getStatus();
1368         
1369                 // Check the status code of the response: does it match
1370                 // the expected response(s)?
1371                 if(logger.isDebugEnabled()){
1372                     logger.debug(testName + ": status = " + statusCode);
1373                 }
1374                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1375                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1376                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1377
1378                 list = res.getEntity();
1379         } finally {
1380                 res.releaseConnection();
1381         }
1382
1383         List<PersonsCommonList.PersonListItem> items =
1384             list.getPersonListItem();
1385         int nItemsReturned = items.size();
1386         // There will be one item created, associated with a
1387         // known parent resource, by the createItem test.
1388         //
1389         // In addition, there will be 'nItemsToCreateInList'
1390         // additional items created by the createItemList test,
1391         // all associated with the same parent resource.
1392         int nExpectedItems = nItemsToCreateInList + 1;
1393         if(logger.isDebugEnabled()){
1394             logger.debug(testName + ": Expected "
1395                         + nExpectedItems +" items; got: "+nItemsReturned);
1396         }
1397         Assert.assertEquals(nItemsReturned, nExpectedItems);
1398
1399         int i = 0;
1400         for (PersonsCommonList.PersonListItem item : items) {
1401                 Assert.assertTrue((null != item.getRefName()), "Item refName is null!");
1402                 Assert.assertTrue((null != item.getDisplayName()), "Item displayName is null!");
1403                 // Optionally output additional data about list members for debugging.
1404                 boolean showDetails = true;
1405                 if (showDetails && logger.isDebugEnabled()) {
1406                 logger.debug("  " + testName + ": list-item[" + i + "] csid=" +
1407                         item.getCsid());
1408                 logger.debug("  " + testName + ": list-item[" + i + "] refName=" +
1409                         item.getRefName());
1410                 logger.debug("  " + testName + ": list-item[" + i + "] displayName=" +
1411                         item.getDisplayName());
1412                 logger.debug("  " + testName + ": list-item[" + i + "] URI=" +
1413                         item.getUri());
1414             }
1415             i++;
1416         }
1417     }
1418
1419     /**
1420      * Read contact list.
1421      */
1422     @Test(groups = {"readList"}, dependsOnMethods = {"readItemList"})
1423     public void readContactList() {
1424         readContactList(knownResourceId, knownItemResourceId);
1425     }
1426
1427     /**
1428      * Read contact list.
1429      *
1430      * @param parentcsid the parentcsid
1431      * @param itemcsid the itemcsid
1432      */
1433     private void readContactList(String parentcsid, String itemcsid) {
1434         final String testName = "readContactList";
1435
1436         // Perform setup.
1437         setupReadList();
1438
1439         // Submit the request to the service and store the response.
1440         PersonAuthorityClient client = new PersonAuthorityClient();
1441         ContactsCommonList list = null;
1442         ClientResponse<ContactsCommonList> res =
1443                 client.readContactList(parentcsid, itemcsid);
1444         try {
1445                 int statusCode = res.getStatus();
1446         
1447                 // Check the status code of the response: does it match
1448                 // the expected response(s)?
1449                 if(logger.isDebugEnabled()){
1450                     logger.debug(testName + ": status = " + statusCode);
1451                 }
1452                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1453                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1454                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1455         
1456                 list = res.getEntity();
1457         } finally {
1458                 res.releaseConnection();
1459         }
1460         
1461         List<ContactsCommonList.ContactListItem> listitems =
1462             list.getContactListItem();
1463         int nItemsReturned = listitems.size();
1464         // There will be one item created, associated with a
1465         // known parent resource, by the createItem test.
1466         //
1467         // In addition, there will be 'nItemsToCreateInList'
1468         // additional items created by the createItemList test,
1469         // all associated with the same parent resource.
1470         int nExpectedItems = nItemsToCreateInList + 1;
1471         if(logger.isDebugEnabled()){
1472             logger.debug(testName + ": Expected "
1473                         + nExpectedItems +" items; got: "+nItemsReturned);
1474         }
1475         Assert.assertEquals(nItemsReturned, nExpectedItems);
1476
1477         int i = 0;
1478         for (ContactsCommonList.ContactListItem listitem : listitems) {
1479                 // Optionally output additional data about list members for debugging.
1480                 boolean showDetails = false;
1481                 if (showDetails && logger.isDebugEnabled()) {
1482                 logger.debug("  " + testName + ": list-item[" + i + "] csid=" +
1483                         listitem.getCsid());
1484                 logger.debug("  " + testName + ": list-item[" + i + "] addressPlace=" +
1485                         listitem.getAddressPlace());
1486                 logger.debug("  " + testName + ": list-item[" + i + "] URI=" +
1487                         listitem.getUri());
1488             }
1489             i++;
1490         }
1491     }
1492
1493     // Failure outcomes
1494
1495     // There are no failure outcome tests at present.
1496
1497     // ---------------------------------------------------------------
1498     // CRUD tests : UPDATE tests
1499     // ---------------------------------------------------------------
1500     // Success outcomes
1501     /* (non-Javadoc)
1502      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#update(java.lang.String)
1503      */
1504     @Override
1505     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1506         groups = {"update"}, dependsOnGroups = {"readItem", "readList"})
1507     public void update(String testName) throws Exception {
1508
1509         if (logger.isDebugEnabled()) {
1510             logger.debug(testBanner(testName, CLASS_NAME));
1511         }
1512         // Perform setup.
1513         setupUpdate();
1514
1515         // Retrieve the contents of a resource to update.
1516         PersonAuthorityClient client = new PersonAuthorityClient();
1517         MultipartInput input = null;
1518         ClientResponse<MultipartInput> res = client.read(knownResourceId);
1519         try {
1520                 if(logger.isDebugEnabled()){
1521                     logger.debug(testName + ": read status = " + res.getStatus());
1522                 }
1523                 Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
1524         
1525                 if(logger.isDebugEnabled()){
1526                     logger.debug("got PersonAuthority to update with ID: " + knownResourceId);
1527                 }
1528                 input = res.getEntity();
1529         } finally {
1530                 res.releaseConnection();
1531         }
1532         
1533         PersonauthoritiesCommon personAuthority = (PersonauthoritiesCommon) extractPart(input,
1534                 client.getCommonPartName(), PersonauthoritiesCommon.class);
1535         Assert.assertNotNull(personAuthority);
1536
1537         // Update the contents of this resource.
1538         personAuthority.setDisplayName("updated-" + personAuthority.getDisplayName());
1539         personAuthority.setVocabType("updated-" + personAuthority.getVocabType());
1540         if(logger.isDebugEnabled()){
1541             logger.debug("to be updated PersonAuthority");
1542             logger.debug(objectAsXmlString(personAuthority, PersonauthoritiesCommon.class));
1543         }
1544
1545         // Submit the updated resource to the service and store the response.
1546         MultipartOutput output = new MultipartOutput();
1547         OutputPart commonPart = output.addPart(personAuthority, MediaType.APPLICATION_XML_TYPE);
1548         commonPart.getHeaders().add("label", client.getCommonPartName());
1549         res = client.update(knownResourceId, output);
1550         try {
1551                 int statusCode = res.getStatus();
1552         
1553                 // Check the status code of the response: does it match the expected response(s)?
1554                 if(logger.isDebugEnabled()){
1555                     logger.debug(testName + ": status = " + statusCode);
1556                 }
1557                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1558                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1559                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1560         
1561                 // Retrieve the updated resource and verify that its contents exist.
1562                 input = (MultipartInput) res.getEntity();
1563         } finally {
1564                 res.releaseConnection();
1565         }
1566         
1567         PersonauthoritiesCommon updatedPersonAuthority =
1568                 (PersonauthoritiesCommon) extractPart(input,
1569                         client.getCommonPartName(), PersonauthoritiesCommon.class);
1570         Assert.assertNotNull(updatedPersonAuthority);
1571
1572         // Verify that the updated resource received the correct data.
1573         Assert.assertEquals(updatedPersonAuthority.getDisplayName(),
1574                 personAuthority.getDisplayName(),
1575                 "Data in updated object did not match submitted data.");
1576     }
1577
1578     /**
1579      * Update item.
1580      *
1581      * @param testName the test name
1582      * @throws Exception the exception
1583      */
1584     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1585         groups = {"update"}, dependsOnMethods = {"update"})
1586     public void updateItem(String testName) throws Exception {
1587
1588         if (logger.isDebugEnabled()) {
1589             logger.debug(testBanner(testName, CLASS_NAME));
1590         }
1591         // Perform setup.
1592         setupUpdate();
1593
1594         // Retrieve the contents of a resource to update.
1595         PersonAuthorityClient client = new PersonAuthorityClient();
1596         MultipartInput input = null;
1597         ClientResponse<MultipartInput> res =
1598                 client.readItem(knownResourceId, knownItemResourceId);
1599         try {
1600                 if(logger.isDebugEnabled()){
1601                     logger.debug(testName + ": read status = " + res.getStatus());
1602                 }
1603                 Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
1604         
1605                 if(logger.isDebugEnabled()){
1606                     logger.debug("got Person to update with ID: " +
1607                         knownItemResourceId +
1608                         " in PersonAuthority: " + knownResourceId );
1609                 }
1610                 input = res.getEntity();
1611         } finally {
1612                 res.releaseConnection();
1613         }
1614         
1615         PersonsCommon person = (PersonsCommon) extractPart(input,
1616                 client.getItemCommonPartName(), PersonsCommon.class);
1617         Assert.assertNotNull(person);
1618         
1619         if (logger.isDebugEnabled() == true) {
1620                 logger.debug("About to update the following person...");
1621                 logger.debug(objectAsXmlString(person, PersonsCommon.class));
1622         }
1623
1624         // Update the contents of this resource.
1625         person.setCsid(null);
1626         person.setForeName("updated-" + person.getForeName());
1627         if(logger.isDebugEnabled()){
1628             logger.debug("to be updated Person");
1629             logger.debug(objectAsXmlString(person,
1630                 PersonsCommon.class));
1631         }    
1632         
1633         // Submit the updated resource to the service and store the response.
1634         MultipartOutput output = new MultipartOutput();
1635         OutputPart commonPart = output.addPart(person, MediaType.APPLICATION_XML_TYPE);
1636         commonPart.getHeaders().add("label", client.getItemCommonPartName());
1637         res = client.updateItem(knownResourceId, knownItemResourceId, output);
1638         try {
1639                 int statusCode = res.getStatus();
1640         
1641                 // Check the status code of the response: does it match the expected response(s)?
1642                 if(logger.isDebugEnabled()){
1643                     logger.debug(testName + ": status = " + statusCode);
1644                 }
1645                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1646                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1647                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1648         
1649                 // Retrieve the updated resource and verify that its contents exist.
1650                 input = (MultipartInput) res.getEntity();
1651         } finally {
1652                 res.releaseConnection();
1653         }
1654         
1655         PersonsCommon updatedPerson =
1656                 (PersonsCommon) extractPart(input,
1657                         client.getItemCommonPartName(), PersonsCommon.class);
1658         Assert.assertNotNull(updatedPerson);
1659         
1660         if (logger.isDebugEnabled() == true) {
1661                 logger.debug("Updated to following person to:");
1662                 logger.debug(objectAsXmlString(updatedPerson, PersonsCommon.class));
1663         }        
1664
1665         // Verify that the updated resource received the correct data.
1666         Assert.assertEquals(updatedPerson.getForeName(),
1667                 person.getForeName(),
1668                 "Data in updated Person did not match submitted data.");
1669     }
1670
1671     /**
1672      * Update contact.
1673      *
1674      * @param testName the test name
1675      * @throws Exception the exception
1676      */
1677     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1678         groups = {"update"}, dependsOnMethods = {"updateItem"})
1679     public void updateContact(String testName) throws Exception {
1680         
1681         if (logger.isDebugEnabled()) {
1682             logger.debug(testBanner(testName, CLASS_NAME));
1683         }
1684         // Perform setup.
1685         setupUpdate();
1686
1687         // Retrieve the contents of a resource to update.
1688         PersonAuthorityClient client = new PersonAuthorityClient();
1689         MultipartInput input = null;
1690         ClientResponse<MultipartInput> res =
1691                 client.readContact(knownResourceId, knownItemResourceId, knownContactResourceId);
1692         try {
1693                 if(logger.isDebugEnabled()){
1694                     logger.debug(testName + ": read status = " + res.getStatus());
1695                 }
1696                 Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
1697         
1698                 if(logger.isDebugEnabled()){
1699                     logger.debug("got Contact to update with ID: " +
1700                         knownContactResourceId +
1701                         " in item: " + knownItemResourceId +
1702                         " in parent: " + knownResourceId );
1703                 }
1704                 input = res.getEntity();
1705         } finally {
1706                 res.releaseConnection();
1707         }
1708         
1709         ContactsCommon contact = (ContactsCommon) extractPart(input,
1710                 new ContactClient().getCommonPartName(), ContactsCommon.class);
1711         Assert.assertNotNull(contact);
1712
1713         // Update the contents of this resource.
1714         contact.setAddressPlace("updated-" + contact.getAddressPlace());
1715         if(logger.isDebugEnabled()){
1716             logger.debug("to be updated Contact");
1717             logger.debug(objectAsXmlString(contact,
1718                 ContactsCommon.class));
1719         }
1720
1721         // Submit the updated resource to the service and store the response.
1722         MultipartOutput output = new MultipartOutput();
1723         OutputPart commonPart = output.addPart(contact, MediaType.APPLICATION_XML_TYPE);
1724         commonPart.getHeaders().add("label", new ContactClient().getCommonPartName());
1725         res = client.updateContact(knownResourceId, knownItemResourceId, knownContactResourceId, output);
1726         try {
1727                 int statusCode = res.getStatus();
1728         
1729                 // Check the status code of the response: does it match the expected response(s)?
1730                 if(logger.isDebugEnabled()){
1731                     logger.debug(testName + ": status = " + statusCode);
1732                 }
1733                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1734                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1735                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1736         
1737                 // Retrieve the updated resource and verify that its contents exist.
1738                 input = (MultipartInput) res.getEntity();
1739         } finally {
1740                 res.releaseConnection();
1741         }
1742         ContactsCommon updatedContact =
1743                 (ContactsCommon) extractPart(input,
1744                         new ContactClient().getCommonPartName(), ContactsCommon.class);
1745         Assert.assertNotNull(updatedContact);
1746
1747         // Verify that the updated resource received the correct data.
1748         Assert.assertEquals(updatedContact.getAddressPlace(),
1749                 contact.getAddressPlace(),
1750                 "Data in updated Contact did not match submitted data.");
1751     }
1752
1753     // Failure outcomes
1754     // Placeholders until the three tests below can be uncommented.
1755     // See Issue CSPACE-401.
1756     /* (non-Javadoc)
1757      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithEmptyEntityBody(java.lang.String)
1758      */
1759     @Override
1760     public void updateWithEmptyEntityBody(String testName) throws Exception {
1761         //Should this really be empty?
1762     }
1763
1764     /* (non-Javadoc)
1765      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithMalformedXml(java.lang.String)
1766      */
1767     @Override
1768     public void updateWithMalformedXml(String testName) throws Exception {
1769         //Should this really be empty?
1770     }
1771
1772     /* (non-Javadoc)
1773      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithWrongXmlSchema(java.lang.String)
1774      */
1775     @Override
1776     public void updateWithWrongXmlSchema(String testName) throws Exception {
1777         //Should this really be empty?
1778     }
1779
1780 /*
1781     @Override
1782     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
1783         groups = {"update"}, dependsOnMethods = {"update", "testSubmitRequest"})
1784     public void updateWithEmptyEntityBody(String testName) throws Exception {
1785
1786         if (logger.isDebugEnabled()) {
1787             logger.debug(testBanner(testName, CLASS_NAME));
1788         }
1789         // Perform setup.
1790         setupUpdateWithEmptyEntityBody(testName, logger);
1791
1792         // Submit the request to the service and store the response.
1793         String method = REQUEST_TYPE.httpMethodName();
1794         String url = getResourceURL(knownResourceId);
1795         String mediaType = MediaType.APPLICATION_XML;
1796         final String entity = "";
1797         int statusCode = submitRequest(method, url, mediaType, entity);
1798
1799         // Check the status code of the response: does it match
1800         // the expected response(s)?
1801         if(logger.isDebugEnabled()){
1802             logger.debug(testName + ": url=" + url +
1803                 " status=" + statusCode);
1804          }
1805         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1806         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1807         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1808     }
1809
1810     @Override
1811     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
1812         groups = {"update"}, dependsOnMethods = {"update", "testSubmitRequest"})
1813     public void updateWithMalformedXml(String testName) throws Exception {
1814
1815         if (logger.isDebugEnabled()) {
1816             logger.debug(testBanner(testName, CLASS_NAME));
1817         }
1818         // Perform setup.
1819         setupUpdateWithMalformedXml();
1820
1821         // Submit the request to the service and store the response.
1822         String method = REQUEST_TYPE.httpMethodName();
1823         String url = getResourceURL(knownResourceId);
1824         String mediaType = MediaType.APPLICATION_XML;
1825         final String entity = MALFORMED_XML_DATA;
1826         int statusCode = submitRequest(method, url, mediaType, entity);
1827
1828         // Check the status code of the response: does it match
1829         // the expected response(s)?
1830         if(logger.isDebugEnabled()){
1831             logger.debug(testName + ": url=" + url +
1832                " status=" + statusCode);
1833          }
1834         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1835         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1836         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1837     }
1838
1839     @Override
1840     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
1841         groups = {"update"}, dependsOnMethods = {"update", "testSubmitRequest"})
1842     public void updateWithWrongXmlSchema(String testName) throws Exception {
1843
1844         if (logger.isDebugEnabled()) {
1845             logger.debug(testBanner(testName, CLASS_NAME));
1846         }
1847         // Perform setup.
1848         setupUpdateWithWrongXmlSchema();
1849
1850         // Submit the request to the service and store the response.
1851         String method = REQUEST_TYPE.httpMethodName();
1852         String url = getResourceURL(knownResourceId);
1853         String mediaType = MediaType.APPLICATION_XML;
1854         final String entity = WRONG_XML_SCHEMA_DATA;
1855         int statusCode = submitRequest(method, url, mediaType, entity);
1856
1857         // Check the status code of the response: does it match
1858         // the expected response(s)?
1859         if(logger.isDebugEnabled()){
1860             logger.debug("updateWithWrongXmlSchema: url=" + url +
1861                 " status=" + statusCode);
1862          }
1863         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1864         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1865         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1866     }
1867 */
1868
1869     /* (non-Javadoc)
1870  * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateNonExistent(java.lang.String)
1871  */
1872 @Override
1873     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1874         groups = {"update"}, dependsOnMethods = {"update", "testSubmitRequest"})
1875     public void updateNonExistent(String testName) throws Exception {
1876
1877         if (logger.isDebugEnabled()) {
1878             logger.debug(testBanner(testName, CLASS_NAME));
1879         }
1880         // Perform setup.
1881         setupUpdateNonExistent();
1882
1883         // Submit the request to the service and store the response.
1884         // Note: The ID(s) used when creating the request payload may be arbitrary.
1885         // The only relevant ID may be the one used in update(), below.
1886         PersonAuthorityClient client = new PersonAuthorityClient();
1887         String displayName = "displayName-NON_EXISTENT_ID";
1888         MultipartOutput multipart = PersonAuthorityClientUtils.createPersonAuthorityInstance(
1889                                 displayName, "NON_EXISTENT_SHORT_ID", client.getCommonPartName());
1890         ClientResponse<MultipartInput> res =
1891                 client.update(NON_EXISTENT_ID, multipart);
1892         try {
1893                 int statusCode = res.getStatus();
1894         
1895                 // Check the status code of the response: does it match
1896                 // the expected response(s)?
1897                 if(logger.isDebugEnabled()){
1898                     logger.debug(testName + ": status = " + statusCode);
1899                 }
1900                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1901                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1902                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1903         } finally {
1904                 res.releaseConnection();
1905         }
1906     }
1907
1908     /**
1909      * Update non existent item.
1910      *
1911      * @param testName the test name
1912      * @throws Exception the exception
1913      */
1914     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1915         groups = {"update"}, dependsOnMethods = {"updateItem", "testItemSubmitRequest"})
1916     public void updateNonExistentItem(String testName) throws Exception {
1917
1918         if (logger.isDebugEnabled()) {
1919             logger.debug(testBanner(testName, CLASS_NAME));
1920         }
1921         // Perform setup.
1922         setupUpdateNonExistent();
1923
1924         // Submit the request to the service and store the response.
1925         // Note: The ID used in this 'create' call may be arbitrary.
1926         // The only relevant ID may be the one used in update(), below.
1927         PersonAuthorityClient client = new PersonAuthorityClient();
1928         Map<String, String> nonexMap = new HashMap<String,String>();
1929         nonexMap.put(PersonJAXBSchema.SHORT_IDENTIFIER, "nonEX");
1930         nonexMap.put(PersonJAXBSchema.FORE_NAME, "John");
1931         nonexMap.put(PersonJAXBSchema.SUR_NAME, "Wayne");
1932         nonexMap.put(PersonJAXBSchema.GENDER, "male");
1933         Map<String, List<String>> nonexRepeatablesMap = new HashMap<String, List<String>>();
1934         MultipartOutput multipart = 
1935         PersonAuthorityClientUtils.createPersonInstance(NON_EXISTENT_ID, 
1936                         PersonAuthorityClientUtils.createPersonAuthRefName(NON_EXISTENT_ID, null),
1937                         nonexMap, nonexRepeatablesMap, client.getItemCommonPartName() );
1938         ClientResponse<MultipartInput> res =
1939                 client.updateItem(knownResourceId, NON_EXISTENT_ID, multipart);
1940         try {
1941                 int statusCode = res.getStatus();
1942         
1943                 // Check the status code of the response: does it match
1944                 // the expected response(s)?
1945                 if(logger.isDebugEnabled()){
1946                     logger.debug(testName + ": status = " + statusCode);
1947                 }
1948                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
1949                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
1950                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
1951         } finally {
1952                 res.releaseConnection();
1953         }
1954     }
1955
1956     /**
1957      * Update non existent contact.
1958      *
1959      * @param testName the test name
1960      * @throws Exception the exception
1961      */
1962     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
1963         groups = {"update"}, dependsOnMethods = {"updateContact", "testContactSubmitRequest"})
1964     public void updateNonExistentContact(String testName) throws Exception {
1965         // Currently a no-op test
1966     }
1967
1968     // ---------------------------------------------------------------
1969     // CRUD tests : DELETE tests
1970     // ---------------------------------------------------------------
1971     // Success outcomes
1972
1973     // Note: delete sub-resources in ascending hierarchical order,
1974     // before deleting their parents.
1975
1976     /**
1977      * Delete contact.
1978      *
1979      * @param testName the test name
1980      * @throws Exception the exception
1981      */
1982     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, 
1983         groups = {"delete"}, dependsOnGroups = {"update"})
1984     public void deleteContact(String testName) throws Exception {
1985
1986         if (logger.isDebugEnabled()) {
1987             logger.debug(testBanner(testName, CLASS_NAME));
1988         }
1989         // Perform setup.
1990         setupDelete();
1991
1992          if(logger.isDebugEnabled()){
1993             logger.debug("parentcsid =" + knownResourceId +
1994                 " itemcsid = " + knownItemResourceId +
1995                 " csid = " + knownContactResourceId);
1996         }
1997
1998         // Submit the request to the service and store the response.
1999         PersonAuthorityClient client = new PersonAuthorityClient();
2000         ClientResponse<Response> res =
2001             client.deleteContact(knownResourceId, knownItemResourceId, knownContactResourceId);
2002         try {
2003                 int statusCode = res.getStatus();
2004         
2005                 // Check the status code of the response: does it match
2006                 // the expected response(s)?
2007                 if(logger.isDebugEnabled()){
2008                     logger.debug(testName + ": status = " + statusCode);
2009                 }
2010                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
2011                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
2012                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
2013             } finally {
2014                 res.releaseConnection();
2015             }
2016     }
2017
2018    /**
2019     * Delete item.
2020     *
2021     * @param testName the test name
2022     * @throws Exception the exception
2023     */
2024    @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
2025         groups = {"delete"}, dependsOnMethods = {"deleteContact"})
2026     public void deleteItem(String testName) throws Exception {
2027
2028         if (logger.isDebugEnabled()) {
2029             logger.debug(testBanner(testName, CLASS_NAME));
2030         }
2031         // Perform setup.
2032         setupDelete();
2033
2034         if(logger.isDebugEnabled()){
2035             logger.debug("parentcsid =" + knownResourceId +
2036                 " itemcsid = " + knownItemResourceId);
2037         }
2038
2039         // Submit the request to the service and store the response.
2040         PersonAuthorityClient client = new PersonAuthorityClient();
2041         ClientResponse<Response> res = client.deleteItem(knownResourceId, knownItemResourceId);
2042         try {
2043                 int statusCode = res.getStatus();
2044         
2045                 // Check the status code of the response: does it match
2046                 // the expected response(s)?
2047                 if(logger.isDebugEnabled()){
2048                     logger.debug(testName + ": status = " + statusCode);
2049                 }
2050                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
2051                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
2052                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
2053             } finally {
2054                 res.releaseConnection();
2055             }
2056     }
2057
2058     /* (non-Javadoc)
2059      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#delete(java.lang.String)
2060      */
2061     @Override
2062     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
2063         groups = {"delete"}, dependsOnMethods = {"deleteItem"})
2064     public void delete(String testName) throws Exception {
2065
2066         if (logger.isDebugEnabled()) {
2067             logger.debug(testBanner(testName, CLASS_NAME));
2068         }
2069         // Perform setup.
2070         setupDelete();
2071
2072         if(logger.isDebugEnabled()){
2073             logger.debug("parentcsid =" + knownResourceId);
2074         }
2075
2076         // Submit the request to the service and store the response.
2077         PersonAuthorityClient client = new PersonAuthorityClient();
2078         ClientResponse<Response> res = client.delete(knownResourceId);
2079         try {
2080                 int statusCode = res.getStatus();
2081         
2082                 // Check the status code of the response: does it match
2083                 // the expected response(s)?
2084                 if(logger.isDebugEnabled()){
2085                     logger.debug(testName + ": status = " + statusCode);
2086                 }
2087                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
2088                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
2089                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
2090             } finally {
2091                 res.releaseConnection();
2092             }
2093     }
2094
2095     // Failure outcomes
2096     /* (non-Javadoc)
2097      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#deleteNonExistent(java.lang.String)
2098      */
2099     @Override
2100     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
2101         groups = {"delete"}, dependsOnMethods = {"delete"})
2102     public void deleteNonExistent(String testName) throws Exception {
2103
2104         if (logger.isDebugEnabled()) {
2105             logger.debug(testBanner(testName, CLASS_NAME));
2106         }
2107         // Perform setup.
2108         setupDeleteNonExistent();
2109
2110         // Submit the request to the service and store the response.
2111         PersonAuthorityClient client = new PersonAuthorityClient();
2112         ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
2113         try {
2114                 int statusCode = res.getStatus();
2115         
2116                 // Check the status code of the response: does it match
2117                 // the expected response(s)?
2118                 if(logger.isDebugEnabled()){
2119                     logger.debug(testName + ": status = " + statusCode);
2120                 }
2121                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
2122                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
2123                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
2124             } finally {
2125                 res.releaseConnection();
2126             }
2127     }
2128
2129     /**
2130      * Delete non existent item.
2131      *
2132      * @param testName the test name
2133      */
2134     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
2135         groups = {"delete"}, dependsOnMethods = {"deleteItem"})
2136     public void deleteNonExistentItem(String testName) {
2137
2138         if (logger.isDebugEnabled()) {
2139             logger.debug(testBanner(testName, CLASS_NAME));
2140         }
2141         // Perform setup.
2142         setupDeleteNonExistent();
2143
2144         // Submit the request to the service and store the response.
2145         PersonAuthorityClient client = new PersonAuthorityClient();
2146         ClientResponse<Response> res = client.deleteItem(knownResourceId, NON_EXISTENT_ID);
2147         try {
2148                 int statusCode = res.getStatus();
2149         
2150                 // Check the status code of the response: does it match
2151                 // the expected response(s)?
2152                 if(logger.isDebugEnabled()){
2153                     logger.debug(testName + ": status = " + statusCode);
2154                 }
2155                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
2156                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
2157                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
2158             } finally {
2159                 res.releaseConnection();
2160             }
2161     }
2162
2163     /**
2164      * Delete non existent contact.
2165      *
2166      * @param testName the test name
2167      */
2168     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
2169         groups = {"delete"}, dependsOnMethods = {"deleteContact"})
2170     public void deleteNonExistentContact(String testName) {
2171
2172         if (logger.isDebugEnabled()) {
2173             logger.debug(testBanner(testName, CLASS_NAME));
2174         }
2175         // Perform setup.
2176         setupDeleteNonExistent();
2177
2178         // Submit the request to the service and store the response.
2179         PersonAuthorityClient client = new PersonAuthorityClient();
2180         ClientResponse<Response> res =
2181             client.deleteContact(knownResourceId, knownItemResourceId, NON_EXISTENT_ID);
2182         try {
2183                 int statusCode = res.getStatus();
2184         
2185                 // Check the status code of the response: does it match
2186                 // the expected response(s)?
2187                 if(logger.isDebugEnabled()){
2188                     logger.debug(testName + ": status = " + statusCode);
2189                 }
2190                 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
2191                         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
2192                 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
2193             } finally {
2194                 res.releaseConnection();
2195             }
2196     }
2197
2198     // ---------------------------------------------------------------
2199     // Utility tests : tests of code used in tests above
2200     // ---------------------------------------------------------------
2201     /**
2202      * Tests the code for manually submitting data that is used by several
2203      * of the methods above.
2204      */
2205     @Test(dependsOnMethods = {"create", "read"})
2206     public void testSubmitRequest() {
2207
2208         // Expected status code: 200 OK
2209         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
2210
2211         // Submit the request to the service and store the response.
2212         String method = ServiceRequestType.READ.httpMethodName();
2213         String url = getResourceURL(knownResourceId);
2214         int statusCode = submitRequest(method, url);
2215
2216         // Check the status code of the response: does it match
2217         // the expected response(s)?
2218         if(logger.isDebugEnabled()){
2219             logger.debug("testSubmitRequest: url=" + url +
2220                 " status=" + statusCode);
2221         }
2222         Assert.assertEquals(statusCode, EXPECTED_STATUS);
2223
2224     }
2225
2226     /**
2227      * Test item submit request.
2228      */
2229     @Test(dependsOnMethods = {"createItem", "readItem", "testSubmitRequest"})
2230     public void testItemSubmitRequest() {
2231
2232         // Expected status code: 200 OK
2233         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
2234
2235         // Submit the request to the service and store the response.
2236         String method = ServiceRequestType.READ.httpMethodName();
2237         String url = getItemResourceURL(knownResourceId, knownItemResourceId);
2238         int statusCode = submitRequest(method, url);
2239
2240         // Check the status code of the response: does it match
2241         // the expected response(s)?
2242         if(logger.isDebugEnabled()){
2243             logger.debug("testItemSubmitRequest: url=" + url +
2244                 " status=" + statusCode);
2245         }
2246         Assert.assertEquals(statusCode, EXPECTED_STATUS);
2247
2248     }
2249
2250     /**
2251      * Test contact submit request.
2252      */
2253     @Test(dependsOnMethods = {"createContact", "readContact", "testItemSubmitRequest"})
2254     public void testContactSubmitRequest() {
2255
2256         // Expected status code: 200 OK
2257         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
2258
2259         // Submit the request to the service and store the response.
2260         String method = ServiceRequestType.READ.httpMethodName();
2261         String url = getContactResourceURL(knownResourceId,
2262             knownItemResourceId, knownContactResourceId);
2263         int statusCode = submitRequest(method, url);
2264
2265         // Check the status code of the response: does it match
2266         // the expected response(s)?
2267         if(logger.isDebugEnabled()){
2268             logger.debug("testItemSubmitRequest: url=" + url +
2269                 " status=" + statusCode);
2270         }
2271         Assert.assertEquals(statusCode, EXPECTED_STATUS);
2272
2273     }
2274
2275
2276     // ---------------------------------------------------------------
2277     // Cleanup of resources created during testing
2278     // ---------------------------------------------------------------
2279     
2280     /**
2281      * Deletes all resources created by tests, after all tests have been run.
2282      *
2283      * This cleanup method will always be run, even if one or more tests fail.
2284      * For this reason, it attempts to remove all resources created
2285      * at any point during testing, even if some of those resources
2286      * may be expected to be deleted by certain tests.
2287      */
2288
2289     @AfterClass(alwaysRun=true)
2290     @Override
2291     public void cleanUp() {
2292         String noTest = System.getProperty("noTestCleanup");
2293         if(Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
2294             if (logger.isDebugEnabled()) {
2295                 logger.debug("Skipping Cleanup phase ...");
2296             }
2297             return;
2298         }
2299         if (logger.isDebugEnabled()) {
2300             logger.debug("Cleaning up temporary resources created for testing ...");
2301         }
2302         String parentResourceId;
2303         String itemResourceId;
2304         String contactResourceId;
2305         // Clean up contact resources.
2306         PersonAuthorityClient client = new PersonAuthorityClient();
2307         parentResourceId = knownResourceId;
2308         for (Map.Entry<String, String> entry : allContactResourceIdsCreated.entrySet()) {
2309             contactResourceId = entry.getKey();
2310             itemResourceId = entry.getValue();
2311             // Note: Any non-success responses from the delete operation
2312             // below are ignored and not reported.
2313             ClientResponse<Response> res =
2314                 client.deleteContact(parentResourceId, itemResourceId, contactResourceId);
2315             res.releaseConnection();
2316         }
2317         // Clean up item resources.
2318         for (Map.Entry<String, String> entry : allItemResourceIdsCreated.entrySet()) {
2319             itemResourceId = entry.getKey();
2320             parentResourceId = entry.getValue();
2321             // Note: Any non-success responses from the delete operation
2322             // below are ignored and not reported.
2323             ClientResponse<Response> res =
2324                 client.deleteItem(parentResourceId, itemResourceId);
2325             res.releaseConnection();
2326         }
2327         // Clean up parent resources.
2328         super.cleanUp();
2329     }
2330
2331     // ---------------------------------------------------------------
2332     // Utility methods used by tests above
2333     // ---------------------------------------------------------------
2334     /* (non-Javadoc)
2335      * @see org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent()
2336      */
2337     @Override
2338     public String getServicePathComponent() {
2339         return SERVICE_PATH_COMPONENT;
2340     }
2341
2342     /**
2343      * Gets the item service path component.
2344      *
2345      * @return the item service path component
2346      */
2347     public String getItemServicePathComponent() {
2348         return ITEM_SERVICE_PATH_COMPONENT;
2349     }
2350
2351     /**
2352      * Gets the contact service path component.
2353      *
2354      * @return the contact service path component
2355      */
2356     public String getContactServicePathComponent() {
2357         return CONTACT_SERVICE_PATH_COMPONENT;
2358     }
2359
2360     /**
2361      * Returns the root URL for the item service.
2362      *
2363      * This URL consists of a base URL for all services, followed by
2364      * a path component for the owning parent, followed by the
2365      * path component for the items.
2366      *
2367      * @param  parentResourceIdentifier  An identifier (such as a UUID) for the
2368      * parent authority resource of the relevant item resource.
2369      *
2370      * @return The root URL for the item service.
2371      */
2372     protected String getItemServiceRootURL(String parentResourceIdentifier) {
2373         return getResourceURL(parentResourceIdentifier) + "/" + getItemServicePathComponent();
2374     }
2375
2376     /**
2377      * Returns the URL of a specific item resource managed by a service, and
2378      * designated by an identifier (such as a universally unique ID, or UUID).
2379      *
2380      * @param  parentResourceIdentifier  An identifier (such as a UUID) for the
2381      * parent authority resource of the relevant item resource.
2382      *
2383      * @param  itemResourceIdentifier  An identifier (such as a UUID) for an
2384      * item resource.
2385      *
2386      * @return The URL of a specific item resource managed by a service.
2387      */
2388     protected String getItemResourceURL(String parentResourceIdentifier, String itemResourceIdentifier) {
2389         return getItemServiceRootURL(parentResourceIdentifier) + "/" + itemResourceIdentifier;
2390     }
2391
2392
2393     /**
2394      * Returns the root URL for the contact service.
2395      *
2396      * This URL consists of a base URL for all services, followed by
2397      * a path component for the owning authority, followed by the
2398      * path component for the owning item, followed by the path component
2399      * for the contact service.
2400      *
2401      * @param  parentResourceIdentifier  An identifier (such as a UUID) for the
2402      * parent authority resource of the relevant item resource.
2403      *
2404      * @param  itemResourceIdentifier  An identifier (such as a UUID) for an
2405      * item resource.
2406      *
2407      * @return The root URL for the contact service.
2408      */
2409     protected String getContactServiceRootURL(String parentResourceIdentifier,
2410         String itemResourceIdentifier) {
2411         return getItemResourceURL(parentResourceIdentifier, itemResourceIdentifier) + "/" +
2412                 getContactServicePathComponent();
2413     }
2414
2415     /**
2416      * Returns the URL of a specific contact resource managed by a service, and
2417      * designated by an identifier (such as a universally unique ID, or UUID).
2418      *
2419      * @param  parentResourceIdentifier  An identifier (such as a UUID) for the
2420      * parent resource of the relevant item resource.
2421      *
2422      * @param  resourceIdentifier  An identifier (such as a UUID) for an
2423      * item resource.
2424      *
2425      * @return The URL of a specific resource managed by a service.
2426      */
2427     protected String getContactResourceURL(String parentResourceIdentifier,
2428         String itemResourceIdentifier, String contactResourceIdentifier) {
2429         return getContactServiceRootURL(parentResourceIdentifier,
2430             itemResourceIdentifier) + "/" + contactResourceIdentifier;
2431     }
2432 }