From: Sanjay Dalal Date: Tue, 2 Mar 2010 01:34:41 +0000 (+0000) Subject: CSPACE-1026 recognizes whitespaces in repeated fields, was already recognizing elsewhere X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=ce8eae799c3660660d04d38239edfe7a4e70c769;p=tmp%2Fjakarta-migration.git CSPACE-1026 recognizes whitespaces in repeated fields, was already recognizing elsewhere added tests that read raw xml from a file without jaxb unmarshaller. added utility methods in AbstractServiceTestImpl for the same. test: collectionobject tests M services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java A services/collectionobject/client/src/test/resources/test-data/repfield_whitesp3.xml A services/collectionobject/client/src/test/resources/test-data/repfield_whitesp4.xml A services/collectionobject/client/src/test/resources/test-data/repfield_whitesp1.xml A services/collectionobject/client/src/test/resources/test-data/repfield_whitesp2.xml M services/common/src/main/java/org/collectionspace/services/common/document/DocumentUtils.java M services/pom.xml M services/client/src/main/java/org/collectionspace/services/client/test/AbstractServiceTestImpl.java M services/client/pom.xml --- diff --git a/services/client/pom.xml b/services/client/pom.xml index aaf527faf..47433f674 100644 --- a/services/client/pom.xml +++ b/services/client/pom.xml @@ -27,9 +27,13 @@ slf4j-log4j12 - org.apache.maven.plugins - maven-surefire-plugin - 2.4.3 + org.apache.maven.plugins + maven-surefire-plugin + 2.4.3 + + + commons-io + commons-io org.jboss.resteasy @@ -60,7 +64,7 @@ 5.6 - + javax.security jaas @@ -74,12 +78,12 @@ 1.6.1 provided - + - + collectionspace-services-client diff --git a/services/client/src/main/java/org/collectionspace/services/client/test/BaseServiceTest.java b/services/client/src/main/java/org/collectionspace/services/client/test/BaseServiceTest.java index 1d4cfbd3c..7234718b7 100644 --- a/services/client/src/main/java/org/collectionspace/services/client/test/BaseServiceTest.java +++ b/services/client/src/main/java/org/collectionspace/services/client/test/BaseServiceTest.java @@ -14,12 +14,14 @@ import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; +import javax.xml.parsers.DocumentBuilderFactory; import org.apache.commons.httpclient.methods.DeleteMethod; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.apache.commons.io.FileUtils; import org.collectionspace.services.client.TestServiceClient; import org.jboss.resteasy.client.ClientResponse; import org.jboss.resteasy.plugins.providers.multipart.InputPart; @@ -27,6 +29,7 @@ import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.annotations.DataProvider; +import org.w3c.dom.Document; public abstract class BaseServiceTest { @@ -343,6 +346,22 @@ public abstract class BaseServiceTest { return getObjectFromStream(jaxbClass, is); } + protected Document getXmlDocument(String fileName) throws Exception { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + File f = new File(fileName); + if (!f.exists()) { + throw new IllegalArgumentException("test data file " + fileName + " not found!"); + } + // Create the builder and parse the file + return factory.newDocumentBuilder().parse(f); + } + + protected String getXmlDocumentAsString(String fileName) throws Exception { + byte[] b = FileUtils.readFileToByteArray(new File(fileName)); + return new String(b); + } + + /** * getObjectFromStream get object of given class from given inputstream * @param jaxbClass diff --git a/services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java b/services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java index f534e4301..5bbc7fdf0 100644 --- a/services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java +++ b/services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java @@ -117,34 +117,28 @@ public class CollectionObjectServiceTest extends AbstractServiceTestImpl { } @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class) - public void createFromXml(String testName) throws Exception { + public void createFromXmlCambridge(String testName) throws Exception { + createFromXmlFile(testName, "./test-data/testCambridge.xml", true); + } - // Perform setup, such as initializing the type of service request - // (e.g. CREATE, DELETE), its valid and expected status codes, and - // its associated HTTP method name (e.g. POST, DELETE). - setupCreate(testName); + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class) + public void createFromXmlRFWS1(String testName) throws Exception { + createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp1.xml", false); + } - // Submit the request to the service and store the response. - String identifier = createIdentifier(); - MultipartOutput multipart = - createCollectionObjectInstanceFromXml(client.getCommonPartName(), - "test-data/testCambridge.xml"); - ClientResponse res = client.create(multipart); - int statusCode = res.getStatus(); + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class) + public void createFromXmlRFWS2(String testName) throws Exception { + createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp2.xml", false); + } - // Check the status code of the response: does it match - // the expected response(s)? - // - // Specifically: - // Does it fall within the set of valid status codes? - // Does it exactly match the expected status code? - if (logger.isDebugEnabled()) { - logger.debug(testName + ": status = " + statusCode); - } - Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), - invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); - Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); - allResourceIdsCreated.add(extractId(res)); + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class) + public void createFromXmlRFWS3(String testName) throws Exception { + createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp3.xml", false); + } + + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class) + public void createFromXmlRFWS4(String testName) throws Exception { + createFromXmlFile(testName, "./target/test-classes/test-data/repfield_whitesp4.xml", false); } /* (non-Javadoc) @@ -802,10 +796,19 @@ public class CollectionObjectServiceTest extends AbstractServiceTestImpl { } - private MultipartOutput createCollectionObjectInstanceFromXml(String commonPartName, + /** + * createCollectionObjectInstanceFromXml uses JAXB unmarshaller to retrieve + * collectionobject from given file + * @param commonPartName + * @param commonPartFileName + * @return + * @throws Exception + */ + private MultipartOutput createCollectionObjectInstanceFromXml(String testName, String commonPartName, String commonPartFileName) throws Exception { - CollectionobjectsCommon collectionObject = (CollectionobjectsCommon) getObjectFromFile(CollectionobjectsCommon.class, + CollectionobjectsCommon collectionObject = + (CollectionobjectsCommon) getObjectFromFile(CollectionobjectsCommon.class, commonPartFileName); MultipartOutput multipart = new MultipartOutput(); OutputPart commonPart = multipart.addPart(collectionObject, @@ -813,10 +816,33 @@ public class CollectionObjectServiceTest extends AbstractServiceTestImpl { commonPart.getHeaders().add("label", commonPartName); if (logger.isDebugEnabled()) { - logger.debug("to be created, collectionobject common"); + logger.debug(testName + " to be created, collectionobject common"); logger.debug(objectAsXmlString(collectionObject, CollectionobjectsCommon.class)); } + return multipart; + + } + + /** + * createCollectionObjectInstanceFromRawXml uses stringified collectionobject + * retrieve from given file + * @param commonPartName + * @param commonPartFileName + * @return + * @throws Exception + */ + private MultipartOutput createCollectionObjectInstanceFromRawXml(String testName, String commonPartName, + String commonPartFileName) throws Exception { + + MultipartOutput multipart = new MultipartOutput(); + String stringObject = getXmlDocumentAsString(commonPartFileName); + if (logger.isDebugEnabled()) { + logger.debug(testName + " to be created, collectionobject common " + "\n" + stringObject); + } + OutputPart commonPart = multipart.addPart(stringObject, + MediaType.APPLICATION_XML_TYPE); + commonPart.getHeaders().add("label", commonPartName); return multipart; @@ -825,4 +851,31 @@ public class CollectionObjectServiceTest extends AbstractServiceTestImpl { private String getNHPartName() { return "collectionobjects_naturalhistory"; } + + private void createFromXmlFile(String testName, String fileName, boolean useJaxb) throws Exception { + // Perform setup, such as initializing the type of service request + // (e.g. CREATE, DELETE), its valid and expected status codes, and + // its associated HTTP method name (e.g. POST, DELETE). + setupCreate(testName); + + MultipartOutput multipart = null; + + if (useJaxb) { + multipart = createCollectionObjectInstanceFromXml(testName, + client.getCommonPartName(), fileName); + } else { + multipart = createCollectionObjectInstanceFromRawXml(testName, + client.getCommonPartName(), fileName); + } + ClientResponse res = client.create(multipart); + int statusCode = res.getStatus(); + + if (logger.isDebugEnabled()) { + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + allResourceIdsCreated.add(extractId(res)); + } } diff --git a/services/collectionobject/client/src/test/resources/test-data/repfield_whitesp1.xml b/services/collectionobject/client/src/test/resources/test-data/repfield_whitesp1.xml new file mode 100644 index 000000000..b7b659f29 --- /dev/null +++ b/services/collectionobject/client/src/test/resources/test-data/repfield_whitesp1.xml @@ -0,0 +1,98 @@ + + +objectNumber + +XXX +otherNumberType +briefDescription +comments +distFeatures +numberOfObjects +objectName +objectNameCurrency +XXX +objectNameNote +objectNameSystem +objectNameType + +objectNameLanguage + + responsibleDept1responsibleDept2 +title +objectTitleLanguage +titleTranslation +titleType +age +ageQualifier +ageUnit +color +contentActivity +contentConcept +XXX +contentDescription +contentEventName +contentEventNameType +contentNote +contentLanguage +contentObject +contentObjectType +contentOrganization +contentOther +contentOtherType +contentPeople +contentPerson +contentPlace +contentPosition +XXX +copyNumber +dimension +dimensionMeasuredPart +dimensionMeasurementUnit +dimensionValue +XXX +dimensionValueQualifier +editionNumber +
form
+inscriptionContent +inscriber +inscriptionDate +inscriptionInterpretation +inscriptionLanguage +inscriptionMethod +inscriptionPosition +inscriptionScript +inscriptionTranslation +inscriptionTransliteration +inscriptionType +inscriptionDescription +inscriptionDescriptionInscriber +inscriptionDescriptionDate +inscriptionDescriptionInterpretation +inscriptionDescriptionMethod +inscriptionDescriptionPosition +inscriptionDescriptionType +material +materialComponent +materialComponentNote +materialName +materialSource +objectStatus +phase +physicalDescription +sex + +technicalAttribute +technicalAttributeMeasurement +technicalAttributeMeasurementUnit +objectComponentName +objectComponentInformation +dateAssociation +{"level":"objectLevel","content-script":"descContentScript","content-method":"descContentMethod","otherNumber":"otherNumber"} +dateEarliestSingleCertainty +dateEarlierstSingleQualifier +XXX +dateLatestCertainty +dateLatestQualifier +datePeriod +dateText +
diff --git a/services/collectionobject/client/src/test/resources/test-data/repfield_whitesp2.xml b/services/collectionobject/client/src/test/resources/test-data/repfield_whitesp2.xml new file mode 100644 index 000000000..1af625071 --- /dev/null +++ b/services/collectionobject/client/src/test/resources/test-data/repfield_whitesp2.xml @@ -0,0 +1,102 @@ + + +objectNumber + +XXX +otherNumberType +briefDescription +comments +distFeatures +numberOfObjects +objectName +objectNameCurrency +XXX +objectNameNote +objectNameSystem +objectNameType + +objectNameLanguage + + +responsibleDept1 +responsibleDept2 + + +title +objectTitleLanguage +titleTranslation +titleType +age +ageQualifier +ageUnit +color +contentActivity +contentConcept +XXX +contentDescription +contentEventName +contentEventNameType +contentNote +contentLanguage +contentObject +contentObjectType +contentOrganization +contentOther +contentOtherType +contentPeople +contentPerson +contentPlace +contentPosition +XXX +copyNumber +dimension +dimensionMeasuredPart +dimensionMeasurementUnit +dimensionValue +XXX +dimensionValueQualifier +editionNumber +
form
+inscriptionContent +inscriber +inscriptionDate +inscriptionInterpretation +inscriptionLanguage +inscriptionMethod +inscriptionPosition +inscriptionScript +inscriptionTranslation +inscriptionTransliteration +inscriptionType +inscriptionDescription +inscriptionDescriptionInscriber +inscriptionDescriptionDate +inscriptionDescriptionInterpretation +inscriptionDescriptionMethod +inscriptionDescriptionPosition +inscriptionDescriptionType +material +materialComponent +materialComponentNote +materialName +materialSource +objectStatus +phase +physicalDescription +sex + +technicalAttribute +technicalAttributeMeasurement +technicalAttributeMeasurementUnit +objectComponentName +objectComponentInformation +dateAssociation +{"level":"objectLevel","content-script":"descContentScript","content-method":"descContentMethod","otherNumber":"otherNumber"} +dateEarliestSingleCertainty +dateEarlierstSingleQualifier +XXX +dateLatestCertainty +dateLatestQualifier +datePeriod +dateText +
diff --git a/services/collectionobject/client/src/test/resources/test-data/repfield_whitesp3.xml b/services/collectionobject/client/src/test/resources/test-data/repfield_whitesp3.xml new file mode 100644 index 000000000..2d47eee1a --- /dev/null +++ b/services/collectionobject/client/src/test/resources/test-data/repfield_whitesp3.xml @@ -0,0 +1,103 @@ + + +objectNumber + +XXX +otherNumberType +briefDescription +comments +distFeatures +numberOfObjects +objectName +objectNameCurrency +XXX +objectNameNote +objectNameSystem +objectNameType + +objectNameLanguage + + + + responsibleDept1 +responsibleDept2 + + +title +objectTitleLanguage +titleTranslation +titleType +age +ageQualifier +ageUnit +color +contentActivity +contentConcept +XXX +contentDescription +contentEventName +contentEventNameType +contentNote +contentLanguage +contentObject +contentObjectType +contentOrganization +contentOther +contentOtherType +contentPeople +contentPerson +contentPlace +contentPosition +XXX +copyNumber +dimension +dimensionMeasuredPart +dimensionMeasurementUnit +dimensionValue +XXX +dimensionValueQualifier +editionNumber +
form
+inscriptionContent +inscriber +inscriptionDate +inscriptionInterpretation +inscriptionLanguage +inscriptionMethod +inscriptionPosition +inscriptionScript +inscriptionTranslation +inscriptionTransliteration +inscriptionType +inscriptionDescription +inscriptionDescriptionInscriber +inscriptionDescriptionDate +inscriptionDescriptionInterpretation +inscriptionDescriptionMethod +inscriptionDescriptionPosition +inscriptionDescriptionType +material +materialComponent +materialComponentNote +materialName +materialSource +objectStatus +phase +physicalDescription +sex + +technicalAttribute +technicalAttributeMeasurement +technicalAttributeMeasurementUnit +objectComponentName +objectComponentInformation +dateAssociation +{"level":"objectLevel","content-script":"descContentScript","content-method":"descContentMethod","otherNumber":"otherNumber"} +dateEarliestSingleCertainty +dateEarlierstSingleQualifier +XXX +dateLatestCertainty +dateLatestQualifier +datePeriod +dateText +
diff --git a/services/collectionobject/client/src/test/resources/test-data/repfield_whitesp4.xml b/services/collectionobject/client/src/test/resources/test-data/repfield_whitesp4.xml new file mode 100644 index 000000000..b17b621d4 --- /dev/null +++ b/services/collectionobject/client/src/test/resources/test-data/repfield_whitesp4.xml @@ -0,0 +1,102 @@ + + +objectNumber + +XXX +otherNumberType +briefDescription +comments +distFeatures +numberOfObjects +objectName +objectNameCurrency +XXX +objectNameNote +objectNameSystem +objectNameType + +objectNameLanguage + + + responsibleDept1 + responsibleDept2 + + +title +objectTitleLanguage +titleTranslation +titleType +age +ageQualifier +ageUnit +color +contentActivity +contentConcept +XXX +contentDescription +contentEventName +contentEventNameType +contentNote +contentLanguage +contentObject +contentObjectType +contentOrganization +contentOther +contentOtherType +contentPeople +contentPerson +contentPlace +contentPosition +XXX +copyNumber +dimension +dimensionMeasuredPart +dimensionMeasurementUnit +dimensionValue +XXX +dimensionValueQualifier +editionNumber +
form
+inscriptionContent +inscriber +inscriptionDate +inscriptionInterpretation +inscriptionLanguage +inscriptionMethod +inscriptionPosition +inscriptionScript +inscriptionTranslation +inscriptionTransliteration +inscriptionType +inscriptionDescription +inscriptionDescriptionInscriber +inscriptionDescriptionDate +inscriptionDescriptionInterpretation +inscriptionDescriptionMethod +inscriptionDescriptionPosition +inscriptionDescriptionType +material +materialComponent +materialComponentNote +materialName +materialSource +objectStatus +phase +physicalDescription +sex + +technicalAttribute +technicalAttributeMeasurement +technicalAttributeMeasurementUnit +objectComponentName +objectComponentInformation +dateAssociation +{"level":"objectLevel","content-script":"descContentScript","content-method":"descContentMethod","otherNumber":"otherNumber"} +dateEarliestSingleCertainty +dateEarlierstSingleQualifier +XXX +dateLatestCertainty +dateLatestQualifier +datePeriod +dateText +
diff --git a/services/common/src/main/java/org/collectionspace/services/common/document/DocumentUtils.java b/services/common/src/main/java/org/collectionspace/services/common/document/DocumentUtils.java index 57c580f23..32658cf42 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/document/DocumentUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/document/DocumentUtils.java @@ -97,19 +97,25 @@ public class DocumentUtils { HashMap objectProps = new HashMap(); // Get a list of all elements in the document Node root = document.getFirstChild(); - NodeList nodeChildren = root.getChildNodes(); - for (int i = 0; i < nodeChildren.getLength(); i++) { - Node node = nodeChildren.item(i); + NodeList rootChildren = root.getChildNodes(); + for (int i = 0; i < rootChildren.getLength(); i++) { + Node node = rootChildren.item(i); + String name = node.getNodeName(); if (node.getNodeType() == Node.ELEMENT_NODE) { - NodeList childNodes = node.getChildNodes(); - Node cnode = childNodes.item(0); - if (cnode != null) { - if (cnode.getNodeType() == Node.TEXT_NODE) { - objectProps.put(node.getNodeName(), getTextNodeValue(node)); + NodeList nodeChildren = node.getChildNodes(); + int nodeChildrenLen = nodeChildren.getLength(); + Node firstChild = nodeChildren.item(0); + Object value = null; + if (firstChild != null) { + //first child node could be a whitespace char CSPACE-1026 + //so, check for number of children too + if (firstChild.getNodeType() == Node.TEXT_NODE + && nodeChildrenLen == 1) { + value = getTextNodeValue(node); } else { - String[] vals = getMultiValues(node); - objectProps.put(node.getNodeName(), vals); + value = getMultiValues(node); } + objectProps.put(name, value); } } } @@ -118,15 +124,25 @@ public class DocumentUtils { /** * getMultiValues retrieve multi-value element values + * assumption: backend does not support more than 1 level deep hierarchy * @param node * @return */ private static String[] getMultiValues(Node node) { ArrayList vals = new ArrayList(); - NodeList children = node.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - Node cnode = children.item(i); - vals.add(qualify(cnode.getNodeName(), getTextNodeValue(cnode))); + NodeList nodeChildren = node.getChildNodes(); + for (int i = 0; i < nodeChildren.getLength(); i++) { + Node child = nodeChildren.item(i); + String name = child.getNodeName(); + //assumption: backend does not support more than 1 level deep + //hierarchy + String value = null; + if (child.getNodeType() == Node.ELEMENT_NODE) { + value = getTextNodeValue(child); + vals.add(qualify(name, value)); + } else { + //skip text nodes with whitespaces + } } return vals.toArray(new String[0]); } @@ -142,7 +158,7 @@ public class DocumentUtils { if (ccnode != null && ccnode.getNodeType() == Node.TEXT_NODE) { value = ccnode.getNodeValue(); } - return value; + return value.trim(); } /** diff --git a/services/pom.xml b/services/pom.xml index 95bb2eff1..a797a30ea 100644 --- a/services/pom.xml +++ b/services/pom.xml @@ -211,6 +211,11 @@ commons-httpclient 3.1 + + commons-io + commons-io + 1.4 + com.sun.xml.bind jaxb-impl