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