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