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