]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-515, CSPACE-266 Added support for multivalue elements in schema. Supports...
authorSanjay Dalal <sanjay.dalal@berkeley.edu>
Fri, 6 Nov 2009 00:59:20 +0000 (00:59 +0000)
committerSanjay Dalal <sanjay.dalal@berkeley.edu>
Fri, 6 Nov 2009 00:59:20 +0000 (00:59 +0000)
    <otherNumbers>
        <otherNumber>urn:org.collectionspace.id:24082390</otherNumber>
        <otherNumber>urn:org.walkerart.id:123</otherNumber>
    </otherNumbers>
woudl be stored by nuxeo with each item (otherNumber) having value such as "otherNumber|urn:org.collectionspace.id:24082390". marshalling and unmarshalling code takes care of qualifying or unqualifying the value with the name of the property.
test: collectionobjects, all service tests. will require re-initializing nuxeo db

M    collectionobject/jaxb/src/main/resources/collectionobjects_common.xsd
M    collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/schemas/collectionobjects_common.xsd
M    collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java
M    common/src/main/java/org/collectionspace/services/common/repository/DocumentUtils.java

services/collectionobject/3rdparty/nuxeo-platform-cs-collectionobject/src/main/resources/schemas/collectionobjects_common.xsd
services/collectionobject/client/src/test/java/org/collectionspace/services/client/test/CollectionObjectServiceTest.java
services/collectionobject/jaxb/src/main/resources/collectionobjects_common.xsd
services/common/src/main/java/org/collectionspace/services/common/repository/DocumentUtils.java

index c0190676054780783917b5a8e33990b01bf1fb5c..c3545ded98d10162f863ee1c52f0942c8dfee682 100644 (file)
     version="0.1">\r
 \r
                 <!-- Object identification information -->\r
-                <xs:element name="objectNumber" type="xs:string"/>\r
-                <xs:element name="otherNumber" type="xs:string"/>\r
-                <xs:element name="otherNumberType" type="xs:string"/>\r
-                <xs:element name="briefDescription" type="xs:string"/>\r
-                <xs:element name="comments" type="xs:string"/>\r
-                <xs:element name="distFeatures" type="xs:string"/>\r
-                <xs:element name="numberOfObjects" type="xs:string"/>\r
-                <xs:element name="objectName" type="xs:string"/>\r
-                <xs:element name="objectNameCurrency" type="xs:string"/>\r
-                <xs:element name="objectNameNote" type="xs:string"/>\r
-                <xs:element name="objectNameSystem" type="xs:string"/>\r
-                <xs:element name="objectNameType" type="xs:string"/>\r
-                <xs:element name="objectNameLanguage" type="xs:string"/>\r
-                <xs:element name="responsibleDept" type="xs:string"/>\r
-                <xs:element name="title" type="xs:string"/>\r
-                <xs:element name="objectTitleLanguage" type="xs:string"/>\r
-                <xs:element name="titleTranslation" type="xs:string"/>\r
-                <xs:element name="titleType" type="xs:string"/>\r
+    <xs:element name="objectNumber" type="xs:string"/>\r
+    <xs:element name="otherNumbers">\r
+        <xs:complexType>\r
+            <xs:sequence>\r
+                <xs:element name="otherNumber" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>\r
+            </xs:sequence>\r
+        </xs:complexType>\r
+    </xs:element>\r
+    <xs:element name="otherNumberType" type="xs:string"/>\r
+    <xs:element name="briefDescription" type="xs:string"/>\r
+    <xs:element name="comments" type="xs:string"/>\r
+    <xs:element name="distFeatures" type="xs:string"/>\r
+    <xs:element name="numberOfObjects" type="xs:string"/>\r
+    <xs:element name="objectName" type="xs:string"/>\r
+    <xs:element name="objectNameCurrency" type="xs:string"/>\r
+    <xs:element name="objectNameNote" type="xs:string"/>\r
+    <xs:element name="objectNameSystem" type="xs:string"/>\r
+    <xs:element name="objectNameType" type="xs:string"/>\r
+    <xs:element name="objectNameLanguage" type="xs:string"/>\r
+    <xs:element name="responsibleDept" type="xs:string"/>\r
+    <xs:element name="title" type="xs:string"/>\r
+    <xs:element name="objectTitleLanguage" type="xs:string"/>\r
+    <xs:element name="titleTranslation" type="xs:string"/>\r
+    <xs:element name="titleType" type="xs:string"/>\r
                 \r
                        <!-- Object description information -->\r
-                <xs:element name="age" type="xs:string" />\r
-                <xs:element name="ageQualifier" type="xs:string" />\r
-                <xs:element name="ageUnit" type="xs:string" />\r
-                <xs:element name="color" type="xs:string" />\r
+    <xs:element name="age" type="xs:string" />\r
+    <xs:element name="ageQualifier" type="xs:string" />\r
+    <xs:element name="ageUnit" type="xs:string" />\r
+    <xs:element name="color" type="xs:string" />\r
 \r
                        <!-- Object description Content information -->                \r
-                <xs:element name="contentActivity" type="xs:string" />\r
-                <xs:element name="contentConcept" type="xs:string" />\r
-                <xs:element name="contentDate" type="xs:string" />\r
-                <xs:element name="contentDescription" type="xs:string" />\r
-                <xs:element name="contentEventName" type="xs:string" />\r
-                <xs:element name="contentEventNameType" type="xs:string" />\r
-                <xs:element name="contentNote" type="xs:string" />\r
-                <xs:element name="contentLanguage" type="xs:string" />\r
-                <xs:element name="contentObject" type="xs:string" />\r
-                <xs:element name="contentObjectType" type="xs:string" />\r
-                <xs:element name="contentOrganization" type="xs:string" />\r
-                <xs:element name="contentOther" type="xs:string" />\r
-                <xs:element name="contentOtherType" type="xs:string" />\r
-                <xs:element name="contentPeople" type="xs:string" />\r
-                <xs:element name="contentPerson" type="xs:string" />\r
-                <xs:element name="contentPlace" type="xs:string" />\r
-                <xs:element name="contentPosition" type="xs:string" />\r
-                <xs:element name="copyNumber" type="xs:string" />\r
+    <xs:element name="contentActivity" type="xs:string" />\r
+    <xs:element name="contentConcept" type="xs:string" />\r
+    <xs:element name="contentDate" type="xs:string" />\r
+    <xs:element name="contentDescription" type="xs:string" />\r
+    <xs:element name="contentEventName" type="xs:string" />\r
+    <xs:element name="contentEventNameType" type="xs:string" />\r
+    <xs:element name="contentNote" type="xs:string" />\r
+    <xs:element name="contentLanguage" type="xs:string" />\r
+    <xs:element name="contentObject" type="xs:string" />\r
+    <xs:element name="contentObjectType" type="xs:string" />\r
+    <xs:element name="contentOrganization" type="xs:string" />\r
+    <xs:element name="contentOther" type="xs:string" />\r
+    <xs:element name="contentOtherType" type="xs:string" />\r
+    <xs:element name="contentPeople" type="xs:string" />\r
+    <xs:element name="contentPerson" type="xs:string" />\r
+    <xs:element name="contentPlace" type="xs:string" />\r
+    <xs:element name="contentPosition" type="xs:string" />\r
+    <xs:element name="copyNumber" type="xs:string" />\r
 \r
                        <!-- Object description Dimension information -->\r
-                <xs:element name="dimension" type="xs:string" />\r
-                <xs:element name="dimensionMeasuredPart" type="xs:string" />\r
-                <xs:element name="dimensionMeasurementUnit" type="xs:string" />\r
-                <xs:element name="dimensionValue" type="xs:string" />\r
-                <xs:element name="dimensionValueDate" type="xs:string" />\r
-                <xs:element name="dimensionValueQualifier" type="xs:string" />\r
+    <xs:element name="dimension" type="xs:string" />\r
+    <xs:element name="dimensionMeasuredPart" type="xs:string" />\r
+    <xs:element name="dimensionMeasurementUnit" type="xs:string" />\r
+    <xs:element name="dimensionValue" type="xs:string" />\r
+    <xs:element name="dimensionValueDate" type="xs:string" />\r
+    <xs:element name="dimensionValueQualifier" type="xs:string" />\r
                 \r
-                <xs:element name="editionNumber" type="xs:string" />\r
-                <xs:element name="form" type="xs:string" />\r
+    <xs:element name="editionNumber" type="xs:string" />\r
+    <xs:element name="form" type="xs:string" />\r
 \r
                        <!-- Object description Inscription content information -->\r
-                <xs:element name="inscriptionContent" type="xs:string" />\r
-                <xs:element name="inscriber" type="xs:string" />\r
-                <xs:element name="inscriptionDate" type="xs:string" />\r
-                <xs:element name="inscriptionInterpretation" type="xs:string" />\r
-                <xs:element name="inscriptionLanguage" type="xs:string" />\r
-                <xs:element name="inscriptionMethod" type="xs:string" />\r
-                <xs:element name="inscriptionPosition" type="xs:string" />\r
-                <xs:element name="inscriptionScript" type="xs:string" />\r
-                <xs:element name="inscriptionTranslation" type="xs:string" />\r
-                <xs:element name="inscriptionTransliteration" type="xs:string" />\r
-                <xs:element name="inscriptionType" type="xs:string" />\r
+    <xs:element name="inscriptionContent" type="xs:string" />\r
+    <xs:element name="inscriber" type="xs:string" />\r
+    <xs:element name="inscriptionDate" type="xs:string" />\r
+    <xs:element name="inscriptionInterpretation" type="xs:string" />\r
+    <xs:element name="inscriptionLanguage" type="xs:string" />\r
+    <xs:element name="inscriptionMethod" type="xs:string" />\r
+    <xs:element name="inscriptionPosition" type="xs:string" />\r
+    <xs:element name="inscriptionScript" type="xs:string" />\r
+    <xs:element name="inscriptionTranslation" type="xs:string" />\r
+    <xs:element name="inscriptionTransliteration" type="xs:string" />\r
+    <xs:element name="inscriptionType" type="xs:string" />\r
                 \r
 \r
                        <!-- Object description Inscription description information -->\r
-                           <xs:element name="inscriptionDescription" type="xs:string" />\r
-                <xs:element name="inscriptionDescriptionInscriber" type="xs:string" />\r
-                <xs:element name="inscriptionDescriptionDate" type="xs:string" />\r
-                <xs:element name="inscriptionDescriptionInterpretation" type="xs:string" />\r
-                <xs:element name="inscriptionDescriptionMethod" type="xs:string" />\r
-                <xs:element name="inscriptionDescriptionPosition" type="xs:string" />\r
-                <xs:element name="inscriptionDescriptionType" type="xs:string" />\r
+    <xs:element name="inscriptionDescription" type="xs:string" />\r
+    <xs:element name="inscriptionDescriptionInscriber" type="xs:string" />\r
+    <xs:element name="inscriptionDescriptionDate" type="xs:string" />\r
+    <xs:element name="inscriptionDescriptionInterpretation" type="xs:string" />\r
+    <xs:element name="inscriptionDescriptionMethod" type="xs:string" />\r
+    <xs:element name="inscriptionDescriptionPosition" type="xs:string" />\r
+    <xs:element name="inscriptionDescriptionType" type="xs:string" />\r
 \r
                        <!-- Object description Material information -->\r
-                               <xs:element name="material" type="xs:string" />\r
-                               <xs:element name="materialComponent" type="xs:string" />\r
-                               <xs:element name="materialComponentNote" type="xs:string" />\r
-                               <xs:element name="materialName" type="xs:string" />\r
-                               <xs:element name="materialSource" type="xs:string" />\r
+    <xs:element name="material" type="xs:string" />\r
+    <xs:element name="materialComponent" type="xs:string" />\r
+    <xs:element name="materialComponentNote" type="xs:string" />\r
+    <xs:element name="materialName" type="xs:string" />\r
+    <xs:element name="materialSource" type="xs:string" />\r
 \r
                        <!-- Misc Object description information -->\r
-                               <xs:element name="objectStatus" type="xs:string" />\r
-                               <xs:element name="phase" type="xs:string" />\r
-                               <xs:element name="physicalDescription" type="xs:string" />\r
-                               <xs:element name="sex" type="xs:string" />\r
-                               <xs:element name="style" type="xs:string" />\r
-                               <xs:element name="technicalAttribute" type="xs:string" />\r
-                               <xs:element name="technicalAttributeMeasurement" type="xs:string" />\r
-                               <xs:element name="technicalAttributeMeasurementUnit" type="xs:string" />\r
-                               <xs:element name="objectComponentName" type="xs:string" />\r
-                               <xs:element name="objectComponentInformation" type="xs:string" />\r
+    <xs:element name="objectStatus" type="xs:string" />\r
+    <xs:element name="phase" type="xs:string" />\r
+    <xs:element name="physicalDescription" type="xs:string" />\r
+    <xs:element name="sex" type="xs:string" />\r
+    <xs:element name="style" type="xs:string" />\r
+    <xs:element name="technicalAttribute" type="xs:string" />\r
+    <xs:element name="technicalAttributeMeasurement" type="xs:string" />\r
+    <xs:element name="technicalAttributeMeasurementUnit" type="xs:string" />\r
+    <xs:element name="objectComponentName" type="xs:string" />\r
+    <xs:element name="objectComponentInformation" type="xs:string" />\r
                                \r
                        <!-- Object description Date information -->\r
-                               <xs:element name="dateAssociation" type="xs:string" />\r
-                               <xs:element name="dateEarliestSingle" type="xs:string" />\r
-                               <xs:element name="dateEarliestSingleCertainty" type="xs:string" />\r
-                               <xs:element name="dateEarlierstSingleQualifier" type="xs:string" />\r
-                               <xs:element name="dateLatest" type="xs:string" />\r
-                               <xs:element name="dateLatestCertainty" type="xs:string" />\r
-                               <xs:element name="dateLatestQualifier" type="xs:string" />\r
-                               <xs:element name="datePeriod" type="xs:string" />\r
-                               <xs:element name="dateText" type="xs:string" />\r
+    <xs:element name="dateAssociation" type="xs:string" />\r
+    <xs:element name="dateEarliestSingle" type="xs:string" />\r
+    <xs:element name="dateEarliestSingleCertainty" type="xs:string" />\r
+    <xs:element name="dateEarlierstSingleQualifier" type="xs:string" />\r
+    <xs:element name="dateLatest" type="xs:string" />\r
+    <xs:element name="dateLatestCertainty" type="xs:string" />\r
+    <xs:element name="dateLatestQualifier" type="xs:string" />\r
+    <xs:element name="datePeriod" type="xs:string" />\r
+    <xs:element name="dateText" type="xs:string" />\r
     \r
 </xs:schema>\r
index dc6b6c6ce057ec0a60552a27619ee9e3ea2270fa..2c05547e59efa2b8de42de6d57a7e576fba59172 100644 (file)
@@ -30,7 +30,7 @@ import org.collectionspace.services.client.CollectionObjectClient;
 import org.collectionspace.services.collectionobject.CollectionobjectsCommon;
 import org.collectionspace.services.collectionobject.domain.naturalhistory.CollectionObjectNaturalhistory;
 import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
-
+import org.collectionspace.services.collectionobject.OtherNumberList;
 import org.jboss.resteasy.client.ClientResponse;
 
 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
@@ -52,12 +52,11 @@ import org.slf4j.LoggerFactory;
 public class CollectionObjectServiceTest extends AbstractServiceTest {
 
     private final Logger logger =
-        LoggerFactory.getLogger(CollectionObjectServiceTest.class);
-
+            LoggerFactory.getLogger(CollectionObjectServiceTest.class);
     // Instance variables specific to this test.
     private CollectionObjectClient client = new CollectionObjectClient();
     private String knownResourceId = null;
-    
+
     /*
      * This method is called only by the parent class, AbstractServiceTest
      */
@@ -66,13 +65,12 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
         return client.getServicePathComponent();
     }
 
-     // ---------------------------------------------------------------
+    // ---------------------------------------------------------------
     // CRUD tests : CREATE tests
     // ---------------------------------------------------------------
-
     // Success outcomes
     @Override
-    @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class)
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class)
     public void create(String testName) throws Exception {
 
         // Perform setup, such as initializing the type of service request
@@ -83,7 +81,7 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
         // Submit the request to the service and store the response.
         String identifier = createIdentifier();
         MultipartOutput multipart =
-            createCollectionObjectInstance(client.getCommonPartName(), identifier);
+                createCollectionObjectInstance(client.getCommonPartName(), identifier);
         ClientResponse<Response> res = client.create(multipart);
         int statusCode = res.getStatus();
 
@@ -93,7 +91,7 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
         // Specifically:
         // Does it fall within the set of valid status codes?
         // Does it exactly match the expected status code?
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             logger.debug(testName + ": status = " + statusCode);
         }
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
@@ -103,123 +101,125 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
         // Store the ID returned from this create operation
         // for additional tests below.
         knownResourceId = extractId(res);
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             logger.debug(testName + ": knownResourceId=" + knownResourceId);
         }
     }
 
-       /* (non-Javadoc)
-        * @see org.collectionspace.services.client.test.ServiceTest#createList()
-        */
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.client.test.ServiceTest#createList()
+     */
     @Override
-    @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
-        dependsOnMethods = {"create"})
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
+    dependsOnMethods = {"create"})
     public void createList(String testName) throws Exception {
-        for(int i = 0; i < 3; i++){
+        for (int i = 0; i < 3; i++) {
             create(testName);
         }
     }
 
     // Failure outcomes
-
     // Placeholders until the three tests below can be uncommented.
     // See Issue CSPACE-401.
     @Override
-    public void createWithEmptyEntityBody(String testName) throws Exception {}
+    public void createWithEmptyEntityBody(String testName) throws Exception {
+    }
+
     @Override
-    public void createWithMalformedXml(String testName) throws Exception {}
+    public void createWithMalformedXml(String testName) throws Exception {
+    }
+
     @Override
-    public void createWithWrongXmlSchema(String testName) throws Exception {}
+    public void createWithWrongXmlSchema(String testName) throws Exception {
+    }
 
 
-/*
+    /*
     @Override
     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
-        dependsOnMethods = {"create", "testSubmitRequest"})
+    dependsOnMethods = {"create", "testSubmitRequest"})
     public void createWithEmptyEntityBody(String testName) throwsException {
     
-        // Perform setup.
-        setupCreateWithEmptyEntityBody(testName);
-
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getServiceRootURL();
-        String mediaType = MediaType.APPLICATION_XML;
-        final String entity = "";
-        int statusCode = submitRequest(method, url, mediaType, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        if(logger.isDebugEnabled()){
-            logger.debug(testName + ": url=" + url +
-                " status=" + statusCode);
-        }
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupCreateWithEmptyEntityBody(testName);
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getServiceRootURL();
+    String mediaType = MediaType.APPLICATION_XML;
+    final String entity = "";
+    int statusCode = submitRequest(method, url, mediaType, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    if(logger.isDebugEnabled()){
+    logger.debug(testName + ": url=" + url +
+    " status=" + statusCode);
+    }
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     @Override
     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
-        dependsOnMethods = {"create", "testSubmitRequest"})
+    dependsOnMethods = {"create", "testSubmitRequest"})
     public void createWithMalformedXml(String testName) throws Exception {
     
-        // Perform setup.
-        setupCreateWithMalformedXml(testName);
-
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getServiceRootURL();
-        String mediaType = MediaType.APPLICATION_XML;
-        final String entity = MALFORMED_XML_DATA; // Constant from base class.
-        int statusCode = submitRequest(method, url, mediaType, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        if(logger.isDebugEnabled()){
-            logger.debug(testName + ": url=" + url +
-                " status=" + statusCode);
-        }
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupCreateWithMalformedXml(testName);
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getServiceRootURL();
+    String mediaType = MediaType.APPLICATION_XML;
+    final String entity = MALFORMED_XML_DATA; // Constant from base class.
+    int statusCode = submitRequest(method, url, mediaType, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    if(logger.isDebugEnabled()){
+    logger.debug(testName + ": url=" + url +
+    " status=" + statusCode);
+    }
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     @Override
     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
-        dependsOnMethods = {"create", "testSubmitRequest"})
+    dependsOnMethods = {"create", "testSubmitRequest"})
     public void createWithWrongXmlSchema(String testName) throws Exception {
     
-        // Perform setup.
-        setupCreateWithWrongXmlSchema(testName);
-     
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getServiceRootURL();
-        String mediaType = MediaType.APPLICATION_XML;
-        final String entity = WRONG_XML_SCHEMA_DATA;
-        int statusCode = submitRequest(method, url, mediaType, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        if(logger.isDebugEnabled()){
-            logger.debug(testName + ": url=" + url +
-                " status=" + statusCode);
-        }
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupCreateWithWrongXmlSchema(testName);
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getServiceRootURL();
+    String mediaType = MediaType.APPLICATION_XML;
+    final String entity = WRONG_XML_SCHEMA_DATA;
+    int statusCode = submitRequest(method, url, mediaType, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    if(logger.isDebugEnabled()){
+    logger.debug(testName + ": url=" + url +
+    " status=" + statusCode);
     }
-*/
-
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    }
+     */
     // ---------------------------------------------------------------
     // CRUD tests : READ tests
     // ---------------------------------------------------------------
-
     // Success outcomes
     @Override
-    @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
-        dependsOnMethods = {"create"})
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
+    dependsOnMethods = {"create"})
     public void read(String testName) throws Exception {
 
         // Perform setup.
@@ -231,25 +231,24 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
 
         // Check the status code of the response: does it match
         // the expected response(s)?
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             logger.debug(testName + ": status = " + statusCode);
         }
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
-        
+
         MultipartInput input = (MultipartInput) res.getEntity();
         CollectionobjectsCommon collectionObject =
-            (CollectionobjectsCommon) extractPart(input,
-            client.getCommonPartName(), CollectionobjectsCommon.class);
+                (CollectionobjectsCommon) extractPart(input,
+                client.getCommonPartName(), CollectionobjectsCommon.class);
         Assert.assertNotNull(collectionObject);
     }
-    
-    // Failure outcomes
 
+    // Failure outcomes
     @Override
-    @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
-        dependsOnMethods = {"read"})
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
+    dependsOnMethods = {"read"})
     public void readNonExistent(String testName) throws Exception {
 
         // Perform setup.
@@ -261,7 +260,7 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
 
         // Check the status code of the response: does it match
         // the expected response(s)?
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             logger.debug(testName + ": status = " + statusCode);
         }
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
@@ -274,8 +273,8 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
     // ---------------------------------------------------------------
     // Success outcomes
     @Override
-    @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
-        dependsOnMethods = {"createList", "read"})
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
+    dependsOnMethods = {"createList", "read"})
     public void readList(String testName) throws Exception {
 
         // Perform setup.
@@ -288,7 +287,7 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
 
         // Check the status code of the response: does it match
         // the expected response(s)?
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             logger.debug(testName + ": status = " + statusCode);
         }
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
@@ -299,16 +298,16 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
         boolean iterateThroughList = false;
         if (iterateThroughList && logger.isDebugEnabled()) {
             List<CollectionobjectsCommonList.CollectionObjectListItem> items =
-                list.getCollectionObjectListItem();
+                    list.getCollectionObjectListItem();
             int i = 0;
 
-            for(CollectionobjectsCommonList.CollectionObjectListItem item : items){
+            for (CollectionobjectsCommonList.CollectionObjectListItem item : items) {
                 logger.debug(testName + ": list-item[" + i + "] csid=" +
-                    item.getCsid());
+                        item.getCsid());
                 logger.debug(testName + ": list-item[" + i + "] objectNumber=" +
-                    item.getObjectNumber());
+                        item.getObjectNumber());
                 logger.debug(testName + ": list-item[" + i + "] URI=" +
-                    item.getUri());
+                        item.getUri());
                 i++;
 
             }
@@ -317,14 +316,13 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
 
     // Failure outcomes
     // None at present.
-
     // ---------------------------------------------------------------
     // CRUD tests : UPDATE tests
     // ---------------------------------------------------------------
     // Success outcomes
     @Override
-    @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
-        dependsOnMethods = {"read"})
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
+    dependsOnMethods = {"read"})
     public void update(String testName) throws Exception {
 
         // Perform setup.
@@ -332,26 +330,26 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
 
         ClientResponse<MultipartInput> res =
                 client.read(knownResourceId);
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             logger.debug(testName + ": read status = " + res.getStatus());
         }
         Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
 
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             logger.debug("got object to update with ID: " + knownResourceId);
         }
         MultipartInput input = (MultipartInput) res.getEntity();
         CollectionobjectsCommon collectionObject =
-            (CollectionobjectsCommon) extractPart(input,
+                (CollectionobjectsCommon) extractPart(input,
                 client.getCommonPartName(), CollectionobjectsCommon.class);
         Assert.assertNotNull(collectionObject);
 
         // Update the content of this resource.
         collectionObject.setObjectNumber("updated-" + collectionObject.getObjectNumber());
         collectionObject.setObjectName("updated-" + collectionObject.getObjectName());
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             verbose("updated object", collectionObject,
-                CollectionobjectsCommon.class);
+                    CollectionobjectsCommon.class);
         }
         // Submit the request to the service and store the response.
         MultipartOutput output = new MultipartOutput();
@@ -361,7 +359,7 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
         res = client.update(knownResourceId, output);
         int statusCode = res.getStatus();
         // Check the status code of the response: does it match the expected response(s)?
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             logger.debug(testName + ": status = " + statusCode);
         }
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
@@ -372,7 +370,7 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
         input = (MultipartInput) res.getEntity();
         CollectionobjectsCommon updatedCollectionObject =
                 (CollectionobjectsCommon) extractPart(input,
-                        client.getCommonPartName(), CollectionobjectsCommon.class);
+                client.getCommonPartName(), CollectionobjectsCommon.class);
         Assert.assertNotNull(updatedCollectionObject);
 
         Assert.assertEquals(updatedCollectionObject.getObjectName(),
@@ -380,101 +378,104 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
                 "Data in updated object did not match submitted data.");
 
     }
-    
-    // Failure outcomes
 
+    // Failure outcomes
     // Placeholders until the three tests below can be uncommented.
     // See Issue CSPACE-401.
     @Override
-    public void updateWithEmptyEntityBody(String testName) throws Exception {}
+    public void updateWithEmptyEntityBody(String testName) throws Exception {
+    }
+
     @Override
-    public void updateWithMalformedXml(String testName) throws Exception {}
+    public void updateWithMalformedXml(String testName) throws Exception {
+    }
+
     @Override
-    public void updateWithWrongXmlSchema(String testName) throws Exception {}
+    public void updateWithWrongXmlSchema(String testName) throws Exception {
+    }
 
-/*
+    /*
     @Override
     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
-        dependsOnMethods = {"create", "update", "testSubmitRequest"})
+    dependsOnMethods = {"create", "update", "testSubmitRequest"})
     public void updateWithEmptyEntityBody(String testName) throws Exception {
     
-        // Perform setup.
-        setupUpdateWithEmptyEntityBody(testName);
-
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getResourceURL(knownResourceId);
-        String mediaType = MediaType.APPLICATION_XML;
-        final String entity = "";
-        int statusCode = submitRequest(method, url, mediaType, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        if(logger.isDebugEnabled()){
-            logger.debug(testName + ": url=" + url +
-                " status=" + statusCode);
-        }
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupUpdateWithEmptyEntityBody(testName);
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getResourceURL(knownResourceId);
+    String mediaType = MediaType.APPLICATION_XML;
+    final String entity = "";
+    int statusCode = submitRequest(method, url, mediaType, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    if(logger.isDebugEnabled()){
+    logger.debug(testName + ": url=" + url +
+    " status=" + statusCode);
+    }
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     @Override
     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
-        dependsOnMethods = {"create", "update", "testSubmitRequest"})
+    dependsOnMethods = {"create", "update", "testSubmitRequest"})
     public void updateWithMalformedXml() throws Exception {
 
-        // Perform setup.
-        setupUpdateWithMalformedXml(testName);
-
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getResourceURL(knownResourceId);
-        final String entity = MALFORMED_XML_DATA;
-        String mediaType = MediaType.APPLICATION_XML;
-        int statusCode = submitRequest(method, url, mediaType, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        if(logger.isDebugEnabled()){
-            logger.debug(testName + ": url=" + url +
-                " status=" + statusCode);
-        }
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupUpdateWithMalformedXml(testName);
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getResourceURL(knownResourceId);
+    final String entity = MALFORMED_XML_DATA;
+    String mediaType = MediaType.APPLICATION_XML;
+    int statusCode = submitRequest(method, url, mediaType, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    if(logger.isDebugEnabled()){
+    logger.debug(testName + ": url=" + url +
+    " status=" + statusCode);
+    }
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
     }
 
     @Override
     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
-        dependsOnMethods = {"create", "update", "testSubmitRequest"})
+    dependsOnMethods = {"create", "update", "testSubmitRequest"})
     public void updateWithWrongXmlSchema(String testName) throws Exception {
     
-        // Perform setup.
-        setupUpdateWithWrongXmlSchema(String testName);
-        
-        // Submit the request to the service and store the response.
-        String method = REQUEST_TYPE.httpMethodName();
-        String url = getResourceURL(knownResourceId);
-        String mediaType = MediaType.APPLICATION_XML;
-        final String entity = WRONG_XML_SCHEMA_DATA;
-        int statusCode = submitRequest(method, url, mediaType, entity);
-        
-        // Check the status code of the response: does it match
-        // the expected response(s)?
-        if(logger.isDebugEnabled()){
-            logger.debug(testName + ": url=" + url +
-                " status=" + statusCode);
-        }
-        Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
-            invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
-        Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    // Perform setup.
+    setupUpdateWithWrongXmlSchema(String testName);
+
+    // Submit the request to the service and store the response.
+    String method = REQUEST_TYPE.httpMethodName();
+    String url = getResourceURL(knownResourceId);
+    String mediaType = MediaType.APPLICATION_XML;
+    final String entity = WRONG_XML_SCHEMA_DATA;
+    int statusCode = submitRequest(method, url, mediaType, entity);
+
+    // Check the status code of the response: does it match
+    // the expected response(s)?
+    if(logger.isDebugEnabled()){
+    logger.debug(testName + ": url=" + url +
+    " status=" + statusCode);
     }
-*/
-
+    Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+    invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+    Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+    }
+     */
     @Override
-    @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
-        dependsOnMethods = {"update", "testSubmitRequest"})
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
+    dependsOnMethods = {"update", "testSubmitRequest"})
     public void updateNonExistent(String testName) throws Exception {
 
         // Perform setup.
@@ -485,15 +486,15 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
         // Note: The ID used in this 'create' call may be arbitrary.
         // The only relevant ID may be the one used in updateCollectionObject(), below.
         MultipartOutput multipart =
-            createCollectionObjectInstance(client.getCommonPartName(),
+                createCollectionObjectInstance(client.getCommonPartName(),
                 NON_EXISTENT_ID);
         ClientResponse<MultipartInput> res =
-            client.update(NON_EXISTENT_ID, multipart);
+                client.update(NON_EXISTENT_ID, multipart);
         int statusCode = res.getStatus();
 
         // Check the status code of the response: does it match
         // the expected response(s)?
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             logger.debug(testName + ": status = " + statusCode);
         }
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
@@ -506,8 +507,8 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
     // ---------------------------------------------------------------
     // Success outcomes
     @Override
-    @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
-        dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
+    dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
     public void delete(String testName) throws Exception {
 
         // Perform setup.
@@ -519,7 +520,7 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
 
         // Check the status code of the response: does it match
         // the expected response(s)?
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             logger.debug(testName + ": status = " + statusCode);
         }
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
@@ -529,8 +530,8 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
 
     // Failure outcomes
     @Override
-    @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
-        dependsOnMethods = {"delete"})
+    @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTest.class,
+    dependsOnMethods = {"delete"})
     public void deleteNonExistent(String testName) throws Exception {
 
         // Perform setup.
@@ -542,7 +543,7 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
 
         // Check the status code of the response: does it match
         // the expected response(s)?
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             logger.debug(testName + ": status = " + statusCode);
         }
         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
@@ -570,29 +571,32 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
 
         // Check the status code of the response: does it match
         // the expected response(s)?
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             logger.debug("testSubmitRequest: url=" + url +
-                " status=" + statusCode);
+                    " status=" + statusCode);
         }
         Assert.assertEquals(statusCode, EXPECTED_STATUS);
 
-    }          
+    }
 
     // ---------------------------------------------------------------
     // Utility methods used by tests above
     // ---------------------------------------------------------------
-
     private MultipartOutput createCollectionObjectInstance(String commonPartName,
-        String identifier) {
+            String identifier) {
         return createCollectionObjectInstance(commonPartName,
-            "objectNumber-" + identifier,
-            "objectName-" + identifier);
+                "objectNumber-" + identifier,
+                "objectName-" + identifier);
     }
 
     private MultipartOutput createCollectionObjectInstance(String commonPartName,
-        String objectNumber, String objectName) {
+            String objectNumber, String objectName) {
         CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
-
+        OtherNumberList onList = new OtherNumberList();
+        List<String> ons = onList.getOtherNumber();
+        ons.add("urn:org.collectionspace.id:24082390");
+        ons.add("urn:org.walkerart.id:123");
+        collectionObject.setOtherNumbers(onList);
         collectionObject.setObjectNumber(objectNumber);
         collectionObject.setObjectName(objectName);
         collectionObject.setAge(""); //test for null string
@@ -601,12 +605,12 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
                 "Puerto Rico. ca. 8&quot; high, 6&quot; wide, projects 10&quot; (with horns).");
         MultipartOutput multipart = new MultipartOutput();
         OutputPart commonPart = multipart.addPart(collectionObject,
-            MediaType.APPLICATION_XML_TYPE);
+                MediaType.APPLICATION_XML_TYPE);
         commonPart.getHeaders().add("label", commonPartName);
 
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             verbose("to be created, collectionobject common ",
-               collectionObject, CollectionobjectsCommon.class);
+                    collectionObject, CollectionobjectsCommon.class);
         }
 
         CollectionObjectNaturalhistory conh = new CollectionObjectNaturalhistory();
@@ -616,9 +620,9 @@ public class CollectionObjectServiceTest extends AbstractServiceTest {
         OutputPart nhPart = multipart.addPart(conh, MediaType.APPLICATION_XML_TYPE);
         nhPart.getHeaders().add("label", getNHPartName());
 
-        if(logger.isDebugEnabled()){
+        if (logger.isDebugEnabled()) {
             verbose("to be created, collectionobject nhistory",
-                conh, CollectionObjectNaturalhistory.class);
+                    conh, CollectionObjectNaturalhistory.class);
         }
         return multipart;
 
index 4aca87598860cc525b9c9ad2eccd53771e2b210c..0ad19e79a075f52aa62e815169c309326ddb7c5f 100644 (file)
@@ -33,7 +33,7 @@
                 
                 <!-- Object identification information -->
                 <xs:element name="objectNumber" type="xs:string"/>
-                <xs:element name="otherNumber" type="xs:string"/>
+                <xs:element name="otherNumbers" type="otherNumberList"/>
                 <xs:element name="otherNumberType" type="xs:string"/>
                 <xs:element name="briefDescription" type="xs:string"/>
                 <xs:element name="comments" type="xs:string"/>
                 
 
                        <!-- Object description Inscription description information -->
-                           <xs:element name="inscriptionDescription" type="xs:string" />
+                <xs:element name="inscriptionDescription" type="xs:string" />
                 <xs:element name="inscriptionDescriptionInscriber" type="xs:string" />
                 <xs:element name="inscriptionDescriptionDate" type="xs:string" />
                 <xs:element name="inscriptionDescriptionInterpretation" type="xs:string" />
                 <xs:element name="inscriptionDescriptionType" type="xs:string" />
 
                        <!-- Object description Material information -->
-                               <xs:element name="material" type="xs:string" />
-                               <xs:element name="materialComponent" type="xs:string" />
-                               <xs:element name="materialComponentNote" type="xs:string" />
-                               <xs:element name="materialName" type="xs:string" />
-                               <xs:element name="materialSource" type="xs:string" />
+                <xs:element name="material" type="xs:string" />
+                <xs:element name="materialComponent" type="xs:string" />
+                <xs:element name="materialComponentNote" type="xs:string" />
+                <xs:element name="materialName" type="xs:string" />
+                <xs:element name="materialSource" type="xs:string" />
 
                        <!-- Misc Object description information -->
-                               <xs:element name="objectStatus" type="xs:string" />
-                               <xs:element name="phase" type="xs:string" />
-                               <xs:element name="physicalDescription" type="xs:string" />
-                               <xs:element name="sex" type="xs:string" />
-                               <xs:element name="style" type="xs:string" />
-                               <xs:element name="technicalAttribute" type="xs:string" />
-                               <xs:element name="technicalAttributeMeasurement" type="xs:string" />
-                               <xs:element name="technicalAttributeMeasurementUnit" type="xs:string" />
-                               <xs:element name="objectComponentName" type="xs:string" />
-                               <xs:element name="objectComponentInformation" type="xs:string" />
+                <xs:element name="objectStatus" type="xs:string" />
+                <xs:element name="phase" type="xs:string" />
+                <xs:element name="physicalDescription" type="xs:string" />
+                <xs:element name="sex" type="xs:string" />
+                <xs:element name="style" type="xs:string" />
+                <xs:element name="technicalAttribute" type="xs:string" />
+                <xs:element name="technicalAttributeMeasurement" type="xs:string" />
+                <xs:element name="technicalAttributeMeasurementUnit" type="xs:string" />
+                <xs:element name="objectComponentName" type="xs:string" />
+                <xs:element name="objectComponentInformation" type="xs:string" />
                                
                        <!-- Object description Date information -->
-                               <xs:element name="dateAssociation" type="xs:string" />
-                               <xs:element name="dateEarliestSingle" type="xs:string" />
-                               <xs:element name="dateEarliestSingleCertainty" type="xs:string" />
-                               <xs:element name="dateEarlierstSingleQualifier" type="xs:string" />
-                               <xs:element name="dateLatest" type="xs:string" />
-                               <xs:element name="dateLatestCertainty" type="xs:string" />
-                               <xs:element name="dateLatestQualifier" type="xs:string" />
-                               <xs:element name="datePeriod" type="xs:string" />
-                               <xs:element name="dateText" type="xs:string" />
+                <xs:element name="dateAssociation" type="xs:string" />
+                <xs:element name="dateEarliestSingle" type="xs:string" />
+                <xs:element name="dateEarliestSingleCertainty" type="xs:string" />
+                <xs:element name="dateEarlierstSingleQualifier" type="xs:string" />
+                <xs:element name="dateLatest" type="xs:string" />
+                <xs:element name="dateLatestCertainty" type="xs:string" />
+                <xs:element name="dateLatestQualifier" type="xs:string" />
+                <xs:element name="datePeriod" type="xs:string" />
+                <xs:element name="dateText" type="xs:string" />
                 
             </xs:sequence>
         </xs:complexType>
     </xs:element>
+
+    <xs:complexType name="otherNumberList">
+        <xs:sequence>
+            <xs:element name="otherNumber" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
     
     <!-- collection objects as in nuxeo repository -->
     <xs:element name="collectionobjects-common-list">
index a38670b358d254daf21a7fa13aaf0231ade8878c..0bfdc9c172de11fa4af49c859d738f0f14f31c74 100644 (file)
@@ -25,8 +25,10 @@ package org.collectionspace.services.common.repository;
 
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.StringTokenizer;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.transform.OutputKeys;
@@ -51,6 +53,14 @@ import org.w3c.dom.Text;
  */
 public class DocumentUtils {
 
+    private static String NAME_VALUE_SEPARATOR = "|";
+
+    private static class NameValue {
+
+        String name;
+        String value;
+    };
+
     /**
      * parseProperties given payload to create XML document. this
      * method also closes given stream after parsing.
@@ -60,7 +70,7 @@ public class DocumentUtils {
      */
     public static Document parseDocument(InputStream payload)
             throws Exception {
-        try{
+        try {
             // Create a builder factory
             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
             factory.setValidating(false);//TODO take validating value from meta
@@ -68,8 +78,8 @@ public class DocumentUtils {
             // Create the builder and parse the file
             return factory.newDocumentBuilder().parse(payload);
 
-        }finally{
-            if(payload != null){
+        } finally {
+            if (payload != null) {
                 payload.close();
             }
 
@@ -87,29 +97,88 @@ public class DocumentUtils {
         HashMap<String, Object> objectProps = new HashMap<String, Object>();
         // Get a list of all elements in the document
         Node root = document.getFirstChild();
-        NodeList children = root.getChildNodes();
-        for(int i = 0; i < children.getLength(); i++){
-            Node node = (Node) children.item(i);
-            if(node.getNodeType() == Node.ELEMENT_NODE){
-                Node cnode = node.getFirstChild();
-                if(cnode == null){
-                    //if element is present but no value, set to ""
-                    //FIXME what about non-string types?
-                    objectProps.put(node.getNodeName(), "");
-                }else{
-                    if(cnode.getNodeType() != Node.TEXT_NODE){
-                        continue;
-                    }
-                    Node textNode = (Text) cnode;
-                    //FIXME what about other native xml types?
-                    objectProps.put(node.getNodeName(),
-                            textNode.getNodeValue());
+        NodeList rootChildren = root.getChildNodes();
+        for (int i = 0; i < rootChildren.getLength(); i++) {
+            Node node = rootChildren.item(i);
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                NodeList childNodes = node.getChildNodes();
+                if (childNodes.getLength() > 1) {
+                    //must be multi value element
+                    String[] vals = getMultiValues(node);
+                    objectProps.put(node.getNodeName(), vals);
+                } else if (childNodes.getLength() == 1) {
+                    objectProps.put(node.getNodeName(), getTextNodeValue(node));
                 }
             }
         }
         return objectProps;
     }
 
+    /**
+     * getMultiValues retrieve multi-value element values
+     * @param node
+     * @return
+     */
+    private static String[] getMultiValues(Node node) {
+        ArrayList<String> vals = new ArrayList<String>();
+        NodeList children = node.getChildNodes();
+        for (int i = 0; i < children.getLength(); i++) {
+            Node cnode = children.item(i);
+            vals.add(qualify(cnode.getNodeName(), getTextNodeValue(cnode)));
+        }
+        return vals.toArray(new String[0]);
+    }
+
+    /**
+     * getTextNodeValue retrieves text node value
+     * @param cnode
+     * @return
+     */
+    private static String getTextNodeValue(Node cnode) {
+        String value = "";
+        Node ccnode = cnode.getFirstChild();
+        if (ccnode != null && ccnode.getNodeType() == Node.TEXT_NODE) {
+            value = ccnode.getNodeValue();
+        }
+        return value;
+    }
+
+    /**
+     * isQualified check if the given value is already qualified with given property name
+     * e.g.  otherNumber|urn:org.collectionspace.id:24082390 is qualified with otherNumber
+     * but urn:org.walkerart.id:123 is not qualified
+     * @param name of the property, e.g. otherNumber
+     * @param value of the property e.g. otherNumber
+     * @return
+     */
+    private static boolean isQualified(String name, String value) {
+        StringTokenizer stz = new StringTokenizer(value, NAME_VALUE_SEPARATOR);
+        int tokens = stz.countTokens();
+        if (tokens == 2) {
+            String n = stz.nextToken();
+            return name.equals(n);
+        }
+        return false;
+    }
+
+    /**
+     * qualify qualifies given property value with given property name, e.g.
+     * name=otherNumber and value=urn:org.collectionspace.id:24082390 would be
+     * qualified as otherNumber|urn:org.collectionspace.id:24082390. however,
+     * name=otherNumber and value=otherNumber|urn:org.collectionspace.id:24082390
+     * would be ignored as the given value is already qualified once.
+     * @param name
+     * @param value
+     * @return
+     */
+    private static String qualify(String name, String value) {
+        if (isQualified(name, value)) {
+            return value;
+        }
+        return name + NAME_VALUE_SEPARATOR + value;
+
+    }
+
     /**
      * buildDocument builds org.w3c.dom.Document from given properties using
      * given metadata for a part
@@ -124,7 +193,7 @@ public class DocumentUtils {
             throws Exception {
         ObjectPartContentType partContentMeta = partMeta.getContent();
         XmlContentType xc = partContentMeta.getXmlContent();
-        if(xc == null){
+        if (xc == null) {
             return null;
         }
 
@@ -146,20 +215,62 @@ public class DocumentUtils {
         root.setAttribute("xmlns:" + ns, xc.getNamespaceURI());
         document.appendChild(root);
 
-        for(String prop : objectProps.keySet()){
+        for (String prop : objectProps.keySet()) {
             Object value = objectProps.get(prop);
-            if(value != null){
+            if (value != null) {
                 //no need to qualify each element name as namespace is already added
                 Element e = document.createElement(prop);
                 root.appendChild(e);
-                String strValue = objectProps.get(prop).toString();
-                Text tNode = document.createTextNode(strValue);
-                e.appendChild(tNode);
+                if (value instanceof ArrayList) {
+                    //multi-value element
+                    insertMultiValues(document, e, (ArrayList) value);
+                } else {
+                    String strValue = objectProps.get(prop).toString();
+                    insertTextNode(document, e, strValue);
+                }
             }
         }
         return document;
     }
 
+    private static void insertMultiValues(Document document, Element e, ArrayList vals) {
+        String parentName = e.getNodeName();
+        for (Object o : vals) {
+            String val = (String) o; //force cast
+            NameValue nv = unqualify(val);
+            Element c = document.createElement(nv.name);
+            e.appendChild(c);
+            insertTextNode(document, c, nv.value);
+        }
+    }
+
+    private static void insertTextNode(Document document, Element e, String strValue) {
+        Text tNode = document.createTextNode(strValue);
+        e.appendChild(tNode);
+    }
+
+    /**
+     * unqualify given value. if the given input value is not qualified, throw exception
+     * input of otherNumber|urn:org.collectionspace.id:24082390 would be unqualified
+     * as name=otherNumber and value=urn:org.collectionspace.id:24082390
+     * @param input
+     * @return name and value
+     * @exception IllegalStateException
+     */
+    private static NameValue unqualify(String input) {
+        NameValue nv = new NameValue();
+        StringTokenizer stz = new StringTokenizer(input, NAME_VALUE_SEPARATOR);
+        int tokens = stz.countTokens();
+        if (tokens == 2) {
+            nv.name = stz.nextToken();
+            nv.value = stz.nextToken();
+        } else {
+            throw new IllegalStateException("Found multi valued element " + input +
+                    " without qualification");
+        }
+        return nv;
+    }
+
     /**
      * writeDocument streams out given document to given output stream
      * @param document