From 7991da0aaeabbc45415370adabd4dbf70c637108 Mon Sep 17 00:00:00 2001 From: Patrick Schmitz Date: Mon, 15 Feb 2010 19:31:01 +0000 Subject: [PATCH] CSPACE-879, CSPACE-908 Added support for displayNameComputed flag, added validation support to verify displayNameComputed and displayName logic. Added tests to verify this functionality. --- .../src/main/config/tenant-bindings.xml | 3 + .../main/resources/schemas/persons_common.xsd | 1 + .../client/PersonAuthorityClientUtils.java | 28 ++- .../test/PersonAuthorityServiceTest.java | 169 +++++++++++++++++- .../services/PersonJAXBSchema.java | 2 +- .../jaxb/src/main/resources/person_common.xsd | 1 + .../person/PersonAuthorityResource.java | 9 + .../nuxeo/PersonDocumentModelHandler.java | 54 ++---- 8 files changed, 219 insertions(+), 48 deletions(-) diff --git a/services/common/src/main/config/tenant-bindings.xml b/services/common/src/main/config/tenant-bindings.xml index 33f41fc43..5f6399457 100644 --- a/services/common/src/main/config/tenant-bindings.xml +++ b/services/common/src/main/config/tenant-bindings.xml @@ -276,6 +276,9 @@ org.collectionspace.services.person.nuxeo.PersonDocumentModelHandler + + org.collectionspace.services.person.nuxeo.PersonValidatorHandler + + diff --git a/services/person/client/src/main/java/org/collectionspace/services/client/PersonAuthorityClientUtils.java b/services/person/client/src/main/java/org/collectionspace/services/client/PersonAuthorityClientUtils.java index ac5d68575..fb28b2979 100644 --- a/services/person/client/src/main/java/org/collectionspace/services/client/PersonAuthorityClientUtils.java +++ b/services/person/client/src/main/java/org/collectionspace/services/client/PersonAuthorityClientUtils.java @@ -47,6 +47,9 @@ public class PersonAuthorityClientUtils { person.setInAuthority(inAuthority); person.setRefName(personRefName); String value = null; + value = personInfo.get(PersonJAXBSchema.DISPLAY_NAME_COMPUTED); + boolean displayNameComputed = (value==null) || value.equalsIgnoreCase("true"); + person.setDisplayNameComputed(displayNameComputed); if((value = (String)personInfo.get(PersonJAXBSchema.FORE_NAME))!=null) person.setForeName(value); if((value = (String)personInfo.get(PersonJAXBSchema.MIDDLE_NAME))!=null) @@ -102,13 +105,24 @@ public class PersonAuthorityClientUtils { int EXPECTED_STATUS_CODE = Response.Status.CREATED.getStatusCode(); // Type of service request being tested ServiceRequestType REQUEST_TYPE = ServiceRequestType.CREATE; - String displayName = - prepareDefaultDisplayName( - personMap.get(PersonJAXBSchema.FORE_NAME), - personMap.get(PersonJAXBSchema.MIDDLE_NAME), - personMap.get(PersonJAXBSchema.SUR_NAME), - personMap.get(PersonJAXBSchema.BIRTH_DATE), - personMap.get(PersonJAXBSchema.DEATH_DATE)); + + String displayName = personMap.get(PersonJAXBSchema.DISPLAY_NAME); + String displayNameComputedStr = personMap.get(PersonJAXBSchema.DISPLAY_NAME_COMPUTED); + boolean displayNameComputed = (displayNameComputedStr==null) || displayNameComputedStr.equalsIgnoreCase("true"); + if( displayName == null ) { + if(!displayNameComputed) { + throw new RuntimeException( + "CreateItem: Must supply a displayName if displayNameComputed is set to false."); + } + displayName = + prepareDefaultDisplayName( + personMap.get(PersonJAXBSchema.FORE_NAME), + personMap.get(PersonJAXBSchema.MIDDLE_NAME), + personMap.get(PersonJAXBSchema.SUR_NAME), + personMap.get(PersonJAXBSchema.BIRTH_DATE), + personMap.get(PersonJAXBSchema.DEATH_DATE)); + } + String refName = createPersonRefName(personAuthorityRefName, displayName, true); if(logger.isDebugEnabled()){ diff --git a/services/person/client/src/test/java/org/collectionspace/services/client/test/PersonAuthorityServiceTest.java b/services/person/client/src/test/java/org/collectionspace/services/client/test/PersonAuthorityServiceTest.java index 957b2f298..3c4d389cd 100644 --- a/services/person/client/src/test/java/org/collectionspace/services/client/test/PersonAuthorityServiceTest.java +++ b/services/person/client/src/test/java/org/collectionspace/services/client/test/PersonAuthorityServiceTest.java @@ -69,6 +69,12 @@ public class PersonAuthorityServiceTest extends AbstractServiceTestImpl { private ContactClient contactClient = new ContactClient(); final String SERVICE_PATH_COMPONENT = "personauthorities"; final String ITEM_SERVICE_PATH_COMPONENT = "items"; + final String TEST_FORE_NAME = "John"; + final String TEST_MIDDLE_NAME = null; + final String TEST_SUR_NAME = "Wayne"; + final String TEST_BIRTH_DATE = "May 26, 1907"; + final String TEST_DEATH_DATE = "June 11, 1979"; + private String knownResourceId = null; private String lastPersonAuthId = null; private String knownResourceRefName = null; @@ -156,12 +162,12 @@ public class PersonAuthorityServiceTest extends AbstractServiceTestImpl { // Submit the request to the service and store the response. String identifier = createIdentifier(); Map johnWayneMap = new HashMap(); - johnWayneMap.put(PersonJAXBSchema.FORE_NAME, "John"); - johnWayneMap.put(PersonJAXBSchema.SUR_NAME, "Wayne"); + johnWayneMap.put(PersonJAXBSchema.FORE_NAME, TEST_FORE_NAME); + johnWayneMap.put(PersonJAXBSchema.SUR_NAME, TEST_SUR_NAME); johnWayneMap.put(PersonJAXBSchema.GENDER, "male"); - johnWayneMap.put(PersonJAXBSchema.BIRTH_DATE, "May 26, 1907"); + johnWayneMap.put(PersonJAXBSchema.BIRTH_DATE, TEST_BIRTH_DATE); johnWayneMap.put(PersonJAXBSchema.BIRTH_PLACE, "Winterset, Iowa"); - johnWayneMap.put(PersonJAXBSchema.DEATH_DATE, "June 11, 1979"); + johnWayneMap.put(PersonJAXBSchema.DEATH_DATE, TEST_DEATH_DATE); johnWayneMap.put(PersonJAXBSchema.BIO_NOTE, "born Marion Robert Morrison and better" + "known by his stage name John Wayne, was an American film actor, director " + "and producer. He epitomized rugged masculinity and has become an enduring " + @@ -475,6 +481,159 @@ public class PersonAuthorityServiceTest extends AbstractServiceTestImpl { } + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, + dependsOnMethods = {"readItem", "updateItem"}) + public void verifyItemDisplayName(String testName) throws Exception { + + // Perform setup. + setupUpdate(testName); + + // Submit the request to the service and store the response. + ClientResponse res = client.readItem(knownResourceId, knownItemResourceId); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + // Check whether person has expected displayName. + MultipartInput input = (MultipartInput) res.getEntity(); + PersonsCommon person = (PersonsCommon) extractPart(input, + client.getItemCommonPartName(), PersonsCommon.class); + Assert.assertNotNull(person); + String displayName = person.getDisplayName(); + // Make sure displayName matches computed form + String expectedDisplayName = + PersonAuthorityClientUtils.prepareDefaultDisplayName( + TEST_FORE_NAME, null, TEST_SUR_NAME, + TEST_BIRTH_DATE, TEST_DEATH_DATE); + Assert.assertNotNull(displayName, expectedDisplayName); + + // Update the shortName and verify the computed name is updated. + person.setDisplayNameComputed(true); + person.setForeName("updated-" + TEST_FORE_NAME); + expectedDisplayName = + PersonAuthorityClientUtils.prepareDefaultDisplayName( + "updated-" + TEST_FORE_NAME, null, TEST_SUR_NAME, + TEST_BIRTH_DATE, TEST_DEATH_DATE); + + // Submit the updated resource to the service and store the response. + MultipartOutput output = new MultipartOutput(); + OutputPart commonPart = output.addPart(person, MediaType.APPLICATION_XML_TYPE); + commonPart.getHeaders().add("label", client.getItemCommonPartName()); + res = client.updateItem(knownResourceId, knownItemResourceId, output); + statusCode = res.getStatus(); + + // Check the status code of the response: does it match the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug("updateItem: status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + // Retrieve the updated resource and verify that its contents exist. + input = (MultipartInput) res.getEntity(); + PersonsCommon updatedPerson = + (PersonsCommon) extractPart(input, + client.getItemCommonPartName(), PersonsCommon.class); + Assert.assertNotNull(updatedPerson); + + // Verify that the updated resource received the correct data. + Assert.assertEquals(updatedPerson.getForeName(), + person.getForeName(), + "Updated ForeName in Person did not match submitted data."); + // Verify that the updated resource computes the right displayName. + Assert.assertEquals(updatedPerson.getDisplayName(), + expectedDisplayName, + "Updated ForeName in Person not reflected in computed DisplayName."); + + // Now Update the displayName, not computed and verify the computed name is overriden. + person.setDisplayNameComputed(false); + expectedDisplayName = "TestName"; + person.setDisplayName(expectedDisplayName); + + // Submit the updated resource to the service and store the response. + output = new MultipartOutput(); + commonPart = output.addPart(person, MediaType.APPLICATION_XML_TYPE); + commonPart.getHeaders().add("label", client.getItemCommonPartName()); + res = client.updateItem(knownResourceId, knownItemResourceId, output); + statusCode = res.getStatus(); + + // Check the status code of the response: does it match the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug("updateItem: status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + // Retrieve the updated resource and verify that its contents exist. + input = (MultipartInput) res.getEntity(); + updatedPerson = + (PersonsCommon) extractPart(input, + client.getItemCommonPartName(), PersonsCommon.class); + Assert.assertNotNull(updatedPerson); + + // Verify that the updated resource received the correct data. + Assert.assertEquals(updatedPerson.isDisplayNameComputed(), false, + "Updated displayNameComputed in Person did not match submitted data."); + // Verify that the updated resource computes the right displayName. + Assert.assertEquals(updatedPerson.getDisplayName(), + expectedDisplayName, + "Updated DisplayName (not computed) in Person not stored."); + } + + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, + dependsOnMethods = {"verifyItemDisplayName"}) + public void verifyIllegalItemDisplayName(String testName) throws Exception { + + // Perform setup. + setupUpdateWithWrongXmlSchema(testName); + + // Submit the request to the service and store the response. + ClientResponse res = client.readItem(knownResourceId, knownItemResourceId); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, Response.Status.OK.getStatusCode()); + + // Check whether Person has expected displayName. + MultipartInput input = (MultipartInput) res.getEntity(); + PersonsCommon person = (PersonsCommon) extractPart(input, + client.getItemCommonPartName(), PersonsCommon.class); + Assert.assertNotNull(person); + // Try to Update with computed false and no displayName + person.setDisplayNameComputed(false); + person.setDisplayName(null); + + // Submit the updated resource to the service and store the response. + MultipartOutput output = new MultipartOutput(); + OutputPart commonPart = output.addPart(person, MediaType.APPLICATION_XML_TYPE); + commonPart.getHeaders().add("label", client.getItemCommonPartName()); + res = client.updateItem(knownResourceId, knownItemResourceId, output); + statusCode = res.getStatus(); + + // Check the status code of the response: does it match the expected response(s)? + if(logger.isDebugEnabled()){ + logger.debug("updateItem: status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + } + @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, dependsOnMethods = {"create", "createItem", "createContact", "read", "readItem"}) @@ -995,7 +1154,7 @@ public class PersonAuthorityServiceTest extends AbstractServiceTestImpl { @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class, dependsOnMethods = {"createItem", "readItemList", "testItemSubmitRequest", - "updateItem"}) + "updateItem", "verifyIllegalItemDisplayName"}) public void deleteItem(String testName) throws Exception { // Perform setup. diff --git a/services/person/jaxb/src/main/java/org/collectionspace/services/PersonJAXBSchema.java b/services/person/jaxb/src/main/java/org/collectionspace/services/PersonJAXBSchema.java index 87aaf3155..0c8992fb4 100644 --- a/services/person/jaxb/src/main/java/org/collectionspace/services/PersonJAXBSchema.java +++ b/services/person/jaxb/src/main/java/org/collectionspace/services/PersonJAXBSchema.java @@ -13,7 +13,7 @@ public interface PersonJAXBSchema { final static String IN_AUTHORITY = "inAuthority"; final static String REF_NAME = "refName"; final static String DISPLAY_NAME = "displayName"; - final static String DN_COMPUTED = "dnComputed"; + final static String DISPLAY_NAME_COMPUTED = "displayNameComputed"; final static String FORE_NAME = "foreName"; final static String MIDDLE_NAME = "middleName"; final static String SUR_NAME = "surName"; diff --git a/services/person/jaxb/src/main/resources/person_common.xsd b/services/person/jaxb/src/main/resources/person_common.xsd index c74ebc699..c4980a942 100644 --- a/services/person/jaxb/src/main/resources/person_common.xsd +++ b/services/person/jaxb/src/main/resources/person_common.xsd @@ -22,6 +22,7 @@ + diff --git a/services/person/service/src/main/java/org/collectionspace/services/person/PersonAuthorityResource.java b/services/person/service/src/main/java/org/collectionspace/services/person/PersonAuthorityResource.java index fbbd27c47..62dfd9805 100644 --- a/services/person/service/src/main/java/org/collectionspace/services/person/PersonAuthorityResource.java +++ b/services/person/service/src/main/java/org/collectionspace/services/person/PersonAuthorityResource.java @@ -48,6 +48,7 @@ import org.collectionspace.services.common.ServiceMain; import org.collectionspace.services.common.context.MultipartServiceContext; import org.collectionspace.services.common.context.MultipartServiceContextFactory; import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.document.BadRequestException; import org.collectionspace.services.common.document.DocumentFilter; import org.collectionspace.services.common.document.DocumentHandler; import org.collectionspace.services.common.document.DocumentNotFoundException; @@ -353,6 +354,10 @@ public class PersonAuthorityResource extends AbstractCollectionSpaceResourceImpl path.path(parentcsid + "/items/" + itemcsid); Response response = Response.created(path.build()).build(); return response; + } catch (BadRequestException bre) { + Response response = Response.status( + Response.Status.BAD_REQUEST).entity("Create failed reason " + bre.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); } catch (UnauthorizedException ue) { Response response = Response.status( Response.Status.UNAUTHORIZED).entity("Create failed reason " + ue.getErrorReason()).type("text/plain").build(); @@ -505,6 +510,10 @@ public class PersonAuthorityResource extends AbstractCollectionSpaceResourceImpl DocumentHandler handler = createItemDocumentHandler(ctx, parentcsid); getRepositoryClient(ctx).update(ctx, itemcsid, handler); result = (MultipartOutput) ctx.getOutput(); + } catch (BadRequestException bre) { + Response response = Response.status( + Response.Status.BAD_REQUEST).entity("Create failed reason " + bre.getErrorReason()).type("text/plain").build(); + throw new WebApplicationException(response); } catch (UnauthorizedException ue) { Response response = Response.status( Response.Status.UNAUTHORIZED).entity("Update failed reason " + ue.getErrorReason()).type("text/plain").build(); diff --git a/services/person/service/src/main/java/org/collectionspace/services/person/nuxeo/PersonDocumentModelHandler.java b/services/person/service/src/main/java/org/collectionspace/services/person/nuxeo/PersonDocumentModelHandler.java index 483bc96cf..5e59d2dd1 100644 --- a/services/person/service/src/main/java/org/collectionspace/services/person/nuxeo/PersonDocumentModelHandler.java +++ b/services/person/service/src/main/java/org/collectionspace/services/person/nuxeo/PersonDocumentModelHandler.java @@ -83,48 +83,32 @@ public class PersonDocumentModelHandler public void handleCreate(DocumentWrapper wrapDoc) throws Exception { // first fill all the parts of the document super.handleCreate(wrapDoc); - handleGetDisplayName(wrapDoc.getWrappedObject()); + handleDisplayName(wrapDoc.getWrappedObject()); } - private String handleGetDisplayName(DocumentModel docModel) throws Exception { - return handleGetDisplayName(docModel, true); - } - - private String handleGetDisplayName(DocumentModel docModel, boolean updateDocModel) throws Exception { - String displayName = (String) docModel.getProperty(getServiceContext().getCommonPartLabel("persons"), - PersonJAXBSchema.DISPLAY_NAME); - if (displayName == null) { - displayName = prepareDefaultDisplayName(docModel); - if (updateDocModel == true) { - docModel.setProperty(getServiceContext().getCommonPartLabel( - "persons"), PersonJAXBSchema.DISPLAY_NAME, displayName); - } - } - - return displayName; - } - - /* Override handleGet so we can deal with defaulting the displayName - * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#handleGet(org.collectionspace.services.common.document.DocumentWrapper) - */ @Override - public void handleGet(DocumentWrapper wrapDoc) throws Exception { - handleGetDisplayName(wrapDoc.getWrappedObject()); - super.handleGet(wrapDoc); + public void handleUpdate(DocumentWrapper wrapDoc) throws Exception { + super.handleUpdate(wrapDoc); + handleDisplayName(wrapDoc.getWrappedObject()); } - - private String prepareDefaultDisplayName(DocumentModel docModel) throws Exception { + + private void handleDisplayName(DocumentModel docModel) throws Exception { String commonPartLabel = getServiceContext().getCommonPartLabel("persons"); - return prepareDefaultDisplayName( + Boolean displayNameComputed = (Boolean) docModel.getProperty(commonPartLabel, + PersonJAXBSchema.DISPLAY_NAME_COMPUTED); + if (displayNameComputed) { + String displayName = prepareDefaultDisplayName( (String)docModel.getProperty(commonPartLabel, PersonJAXBSchema.FORE_NAME ), (String)docModel.getProperty(commonPartLabel, PersonJAXBSchema.MIDDLE_NAME ), (String)docModel.getProperty(commonPartLabel, PersonJAXBSchema.SUR_NAME ), (String)docModel.getProperty(commonPartLabel, PersonJAXBSchema.BIRTH_DATE ), (String)docModel.getProperty(commonPartLabel, PersonJAXBSchema.DEATH_DATE ) ); + docModel.setProperty(commonPartLabel, PersonJAXBSchema.DISPLAY_NAME, + displayName); + } } - - + /** * Produces a default displayName from the basic name and dates fields. * @see PersonAuthorityClientUtils.prepareDefaultDisplayName() which @@ -234,14 +218,14 @@ public class PersonDocumentModelHandler //FIXME: iterating over a long list of documents is not a long term //strategy...need to change to more efficient iterating in future Iterator iter = docList.iterator(); + String commonPartLabel = getServiceContext().getCommonPartLabel("persons"); while(iter.hasNext()){ DocumentModel docModel = iter.next(); PersonListItem ilistItem = new PersonListItem(); - // We look for a set display name, and fall back to teh short name if there is none - String displayName = handleGetDisplayName(docModel, false); - ilistItem.setDisplayName(displayName); - ilistItem.setRefName((String) docModel.getProperty(getServiceContext().getCommonPartLabel( - "persons"), PersonJAXBSchema.REF_NAME)); + ilistItem.setDisplayName((String) + docModel.getProperty(commonPartLabel, PersonJAXBSchema.DISPLAY_NAME)); + ilistItem.setRefName((String) + docModel.getProperty(commonPartLabel, PersonJAXBSchema.REF_NAME)); String id = NuxeoUtils.extractId(docModel.getPathAsString()); ilistItem.setUri("/personauthorities/"+inAuthority+"/items/" + id); ilistItem.setCsid(id); -- 2.47.3