]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-864: Added a native Nuxeo "repeatable" information group to the CollectionObje...
authorRichard Millet <richard.millet@berkeley.edu>
Thu, 27 May 2010 06:04:04 +0000 (06:04 +0000)
committerRichard Millet <richard.millet@berkeley.edu>
Thu, 27 May 2010 06:04:04 +0000 (06:04 +0000)
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/document/AbstractDocumentHandlerImpl.java
services/common/src/main/java/org/collectionspace/services/common/document/AbstractMultipartDocumentHandlerImpl.java
services/common/src/main/java/org/collectionspace/services/common/document/DocumentUtils.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteSubItemDocumentModelHandlerImpl.java

index 096ab50c4fbc48a41beb8ee34f626df4d88523f4..a57f265552f057ab6fb898882a98f18ed8d772f2 100644 (file)
     $LastChangedDate$\r
 -->\r
 \r
-<xs:schema \r
-    xmlns:xs="http://www.w3.org/2001/XMLSchema"\r
+\r
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"\r
     xmlns:ns="http://collectionspace.org/collectionobject/"\r
     xmlns="http://collectionspace.org/collectionobject/"\r
-    targetNamespace="http://collectionspace.org/collectionobject/"\r
-    version="0.1">\r
+    targetNamespace="http://collectionspace.org/collectionobject/" version="0.1">\r
+\r
+    <xs:complexType name="otherNumberList">\r
+        <xs:sequence>\r
+            <xs:element name="otherNumber" type="ns:otherNumber" minOccurs="0"\r
+                maxOccurs="unbounded"/>\r
+        </xs:sequence>\r
+    </xs:complexType>\r
+\r
+    <xs:complexType name="otherNumber">\r
+        <xs:sequence>\r
+            <xs:element name="numberValue" type="xs:string"/>\r
+            <xs:element name="numberType" type="xs:string"/>\r
+        </xs:sequence>\r
+    </xs:complexType>\r
 \r
     <!-- Object identification information -->\r
     <xs:element name="objectNumber" type="xs:string"/>\r
+    <xs:element name="otherNumberList" type="ns:otherNumberList"/>\r
+\r
+    <!-- Remove these two elements when the App/UI layer is using the new repeatable 'otherNumbers' field -->\r
     <xs:element name="otherNumber" type="xs:string"/>\r
     <xs:element name="otherNumberType" type="xs:string"/>\r
+\r
     <xs:element name="briefDescription" type="xs:string"/>\r
     <xs:element name="comments" type="xs:string"/>\r
     <xs:element name="distinguishingFeatures" type="xs:string"/>\r
@@ -36,7 +53,8 @@
     <xs:element name="responsibleDepartments">\r
         <xs:complexType>\r
             <xs:sequence>\r
-                <xs:element name="responsibleDepartment" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>\r
+                <xs:element name="responsibleDepartment" type="xs:string"\r
+                    minOccurs="0" maxOccurs="unbounded"/>\r
             </xs:sequence>\r
         </xs:complexType>\r
     </xs:element>\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
+\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="contentScript" 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="contentScript" 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
-                \r
-    <xs:element name="editionNumber" type="xs:string" />\r
-    <xs:element name="form" 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
 \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
-                \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
     <!-- 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
-                               \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="dateEarliestSingleQualifier" 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: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="dateEarliestSingleQualifier" 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 7ed609f177866c053c40cc62fbba290efb774801..a77ed26d5c5c84d9581f5b95dd78bf38e44c4b78 100644 (file)
@@ -34,6 +34,9 @@ import org.collectionspace.services.collectionobject.CollectionobjectsCommon;
 import org.collectionspace.services.collectionobject.domain.naturalhistory.CollectionobjectsNaturalhistory;
 import org.collectionspace.services.collectionobject.CollectionobjectsCommonList;
 import org.collectionspace.services.collectionobject.ResponsibleDepartmentList;
+import org.collectionspace.services.collectionobject.OtherNumber;
+import org.collectionspace.services.collectionobject.OtherNumberList;
+
 import org.collectionspace.services.jaxb.AbstractCommonList;
 
 import org.jboss.resteasy.client.ClientResponse;
@@ -998,20 +1001,42 @@ public class CollectionObjectServiceTest extends AbstractServiceTestImpl {
     private MultipartOutput createCollectionObjectInstance(String commonPartName,
             String objectNumber, String objectName) {
         CollectionobjectsCommon collectionObject = new CollectionobjectsCommon();
+        
         ResponsibleDepartmentList deptList = new ResponsibleDepartmentList();
         List<String> depts = deptList.getResponsibleDepartment();
         // @TODO Use properly formatted refNames for representative departments
         // in this example test record. The following are mere placeholders.
         depts.add("urn:org.collectionspace.services.department:Registrar");
-        if (multivalue) {
+        if (multivalue == true) {
             depts.add("urn:org.walkerart.department:Fine Art");
         }
+        //
+        // FIXME: REM - Can someone please document why we are toggling this
+        // value?  Thanks.
+        //
         multivalue = !multivalue;
+
+        OtherNumberList otherNumList = new OtherNumberList();
+        List<OtherNumber> otherNumbers = otherNumList.getOtherNumber();
+        
+        OtherNumber otherNumber1 = new OtherNumber();        
+        otherNumber1.setNumberValue("101");
+        otherNumber1.setNumberType("integer");
+        otherNumbers.add(otherNumber1);
+        
+        OtherNumber otherNumber2 = new OtherNumber();
+        otherNumber2.setNumberValue("101.502.23.456");
+        otherNumber2.setNumberType("ipaddress");
+        otherNumbers.add(otherNumber2);        
+        
         //FIXME: Title does not need to be set.
         collectionObject.setTitle("atitle");
         collectionObject.setResponsibleDepartments(deptList);
         collectionObject.setObjectNumber(objectNumber);
+        
+        collectionObject.setOtherNumberList(otherNumList);
         collectionObject.setOtherNumber("urn:org.walkerart.id:123");
+        
         collectionObject.setObjectName(objectName);
         collectionObject.setAge(""); //test for null string
         collectionObject.setBriefDescription("Papier mache bird cow mask with horns, "
index 20fbbaed84ae674f0a2687578bd246707398984e..3c4b69a8cfb7fc775f8decc79667cdbe380f9e28 100644 (file)
   xmlns="http://collectionspace.org/services/collectionobject"
   targetNamespace="http://collectionspace.org/services/collectionobject"
   version="0.1">
-            
+
+    <xs:complexType name="otherNumberList">
+        <xs:sequence>
+            <xs:element name="otherNumber" type="ns:otherNumber" minOccurs="0" maxOccurs="unbounded" />
+        </xs:sequence>
+    </xs:complexType>
+    
+    <xs:complexType name="otherNumber">
+        <xs:sequence>
+            <xs:element name="numberValue" type="xs:string"/>
+            <xs:element name="numberType" type="xs:string"/>
+        </xs:sequence>
+    </xs:complexType>
+    
 <!--
     Avoid XmlRootElement nightmare:
     See http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html
                 
                 <!-- Object identification information -->
                 <xs:element name="objectNumber" type="xs:string"/>
+                <xs:element name="otherNumberList" type="ns:otherNumberList" />
+                
+                <!-- Remove these two elements when the App/UI layer is using the new repeatable 'otherNumbers' field -->
                 <xs:element name="otherNumber" type="xs:string"/>
                 <xs:element name="otherNumberType" type="xs:string"/>
+
                 <xs:element name="briefDescription" type="xs:string"/>
                 <xs:element name="comments" type="xs:string"/>
                 <xs:element name="distinguishingFeatures" type="xs:string"/>
index 9582978bd7215ec902434005b707649f13838e1c..44041b891f19c56bd2009de1f8d97a43191f359e 100644 (file)
@@ -38,23 +38,44 @@ import org.slf4j.LoggerFactory;
  *
  * $LastChangedRevision: $
  * $LastChangedDate: $
+ * @param <T> 
+ * @param <TL> 
+ * @param <WT> 
+ * @param <WTL> 
  */
 public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
         implements DocumentHandler<T, TL, WT, WTL> {
 
+    /** The logger. */
     private final Logger logger = LoggerFactory.getLogger(AbstractDocumentHandlerImpl.class);
+    
+    /** The properties. */
     private Map<String, Object> properties = new HashMap<String, Object>();
+    
+    /** The doc filter. */
     private DocumentFilter docFilter = null;
+    
+    /** The service context. */
     private ServiceContext serviceContext;
 
+    /**
+     * Instantiates a new abstract document handler impl.
+     */
     public AbstractDocumentHandlerImpl() {
+       // Empty constructor
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#getServiceContext()
+     */
     @Override
     public ServiceContext getServiceContext() {
         return serviceContext;
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#setServiceContext(org.collectionspace.services.common.context.ServiceContext)
+     */
     @Override
     public void setServiceContext(ServiceContext ctx) {
         serviceContext = ctx;
@@ -80,7 +101,10 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
 //     DocumentFilter docFilter = this.createDocumentFilter(ctx);
 //     this.setDocumentFilter(docFilter);
 //    }
-    @Override
+    /* (non-Javadoc)
+ * @see org.collectionspace.services.common.document.DocumentHandler#createDocumentFilter()
+ */
+@Override
     public abstract DocumentFilter createDocumentFilter();
 
     /**
@@ -99,6 +123,9 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
         this.docFilter = docFilter;
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#prepare(org.collectionspace.services.common.document.DocumentHandler.Action)
+     */
     @Override
     final public void prepare(Action action) throws Exception {
         switch (action) {
@@ -127,26 +154,44 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
         }
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#prepareCreate()
+     */
     @Override
     public void prepareCreate() throws Exception {
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#prepareUpdate()
+     */
     @Override
     public void prepareUpdate() throws Exception {
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#prepareGet()
+     */
     @Override
     public void prepareGet() throws Exception {
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#prepareGetAll()
+     */
     @Override
     public void prepareGetAll() throws Exception {
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#prepareDelete()
+     */
     @Override
     public void prepareDelete() throws Exception {
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#handle(org.collectionspace.services.common.document.DocumentHandler.Action, org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     final public void handle(Action action, DocumentWrapper<?> wrapDoc) throws Exception {
         switch (action) {
@@ -173,23 +218,41 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
         }
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#handleCreate(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public abstract void handleCreate(DocumentWrapper<WT> wrapDoc) throws Exception;
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#handleUpdate(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public abstract void handleUpdate(DocumentWrapper<WT> wrapDoc) throws Exception;
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#handleGet(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public abstract void handleGet(DocumentWrapper<WT> wrapDoc) throws Exception;
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#handleGetAll(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public abstract void handleGetAll(DocumentWrapper<WTL> wrapDoc) throws Exception;
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#handleDelete(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public void handleDelete(DocumentWrapper<WT> wrapDoc) throws Exception {
         
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#complete(org.collectionspace.services.common.document.DocumentHandler.Action, org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     final public void complete(Action action, DocumentWrapper<?> wrapDoc) throws Exception {
         switch (action) {
@@ -215,59 +278,104 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
         }
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#completeCreate(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public void completeCreate(DocumentWrapper<WT> wrapDoc) throws Exception {
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#completeUpdate(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public void completeUpdate(DocumentWrapper<WT> wrapDoc) throws Exception {
         //no specific action needed
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#completeGet(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public void completeGet(DocumentWrapper<WT> wrapDoc) throws Exception {
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#completeGetAll(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public void completeGetAll(DocumentWrapper<WTL> wrapDoc) throws Exception {
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#completeDelete(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public void completeDelete(DocumentWrapper<WT> wrapDoc) throws Exception {
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#extractCommonPart(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public abstract T extractCommonPart(DocumentWrapper<WT> wrapDoc)
             throws Exception;
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#fillCommonPart(java.lang.Object, org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public abstract void fillCommonPart(T obj, DocumentWrapper<WT> wrapDoc)
             throws Exception;
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#extractCommonPartList(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public abstract TL extractCommonPartList(DocumentWrapper<WTL> wrapDoc)
             throws Exception;
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#fillCommonPartList(java.lang.Object, org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     final public void fillCommonPartList(TL obj, DocumentWrapper<WTL> wrapDoc) throws Exception {
         throw new UnsupportedOperationException("bulk create/update not yet supported");
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#getCommonPart()
+     */
     @Override
     public abstract T getCommonPart();
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#setCommonPart(java.lang.Object)
+     */
     @Override
     public abstract void setCommonPart(T obj);
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#getCommonPartList()
+     */
     @Override
     public abstract TL getCommonPartList();
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#setCommonPartList(java.lang.Object)
+     */
     @Override
     public abstract void setCommonPartList(TL obj);
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#getQProperty(java.lang.String)
+     */
     @Override
     public abstract String getQProperty(String prop);
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#getUnQProperty(java.lang.String)
+     */
     @Override
     public String getUnQProperty(String qProp) {
         StringTokenizer tkz = new StringTokenizer(qProp, ":");
@@ -281,11 +389,20 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
         return tkz.nextToken();
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.DocumentHandler#getServiceContextPath()
+     */
     @Override
     public String getServiceContextPath() {
         return "/" + getServiceContext().getServiceName().toLowerCase() + "/";
     }
 
+    /**
+     * Validate.
+     *
+     * @param action the action
+     * @throws Exception the exception
+     */
     private void validate(Action action) throws Exception {
         List<ValidatorHandler> valHandlers = serviceContext.getValidatorHandlers();
         for (ValidatorHandler handler : valHandlers) {
index 360b429de09f0a7ddfb35696a91cb458328a3b84..847055dbf575c6bca64fa4daff469215ab08fde7 100644 (file)
@@ -33,6 +33,10 @@ import org.slf4j.LoggerFactory;
  *
  * $LastChangedRevision: $
  * $LastChangedDate: $
+ * @param <T> 
+ * @param <TL> 
+ * @param <WT> 
+ * @param <WTL> 
  */
 public abstract class AbstractMultipartDocumentHandlerImpl<T, TL, WT, WTL>
         extends AbstractDocumentHandlerImpl<T, TL, WT, WTL>
@@ -41,8 +45,12 @@ public abstract class AbstractMultipartDocumentHandlerImpl<T, TL, WT, WTL>
     private final Logger logger = LoggerFactory.getLogger(AbstractMultipartDocumentHandlerImpl.class);
 
     public AbstractMultipartDocumentHandlerImpl() {
+       //Empty constructor
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.AbstractDocumentHandlerImpl#handleCreate(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public abstract void handleCreate(DocumentWrapper<WT> wrapDoc) throws Exception;
 
index d4bf210e278c93389ea55f92aec2e281bdbc2d9c..b3639dc4449f29fdd198c32c4cc11c6f25ecba59 100644 (file)
@@ -46,6 +46,7 @@ import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.TransformerConfigurationException; 
 import javax.xml.transform.TransformerException; 
 
+import org.collectionspace.services.common.ServiceMain;
 import org.collectionspace.services.common.service.ObjectPartContentType;
 import org.collectionspace.services.common.service.ObjectPartType;
 import org.collectionspace.services.common.service.XmlContentType;
@@ -66,7 +67,6 @@ import org.w3c.dom.Text;
  * $LastChangedDate: $
  */
 public class DocumentUtils {
-
     /** The Constant logger. */
     private static final Logger logger =
         LoggerFactory.getLogger(DocumentUtils.class);
@@ -77,8 +77,7 @@ public class DocumentUtils {
     /**
      * The Class NameValue.
      */
-    private static class NameValue {
-       
+    private static class NameValue {           
            /**
             * Instantiates a new name value.
             */
@@ -115,6 +114,7 @@ public class DocumentUtils {
                        
                String s = new String(buff);
                logger.debug(s);
+               System.out.println(s);
                //
                // Essentially, reset the stream and return it in its original state
                //
@@ -128,11 +128,21 @@ public class DocumentUtils {
      * parseProperties given payload to create XML document. this
      * method also closes given stream after parsing.
      * @param payload stream
+     * @param partMeta 
      * @return parsed Document
      * @throws Exception
      */
-    public static Document parseDocument(InputStream payload)
+    public static Document parseDocument(InputStream payload, ObjectPartType partMeta)
             throws Exception {
+       final String FILE_SEPARATOR = System.getProperty("file.separator");
+       final String XML_SCHEMA_EXTENSION = ".xsd";
+       final String SCHEMAS_DIR = "schemas";
+       final String JAXP_SCHEMA_SOURCE =
+            "http://java.sun.com/xml/jaxp/properties/schemaSource";
+       final String JAXP_SCHEMA_LANGUAGE =
+            "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
+        final String W3C_XML_SCHEMA =
+            "http://www.w3.org/2001/XMLSchema";        
        Document result = null;
        
        if (logger.isDebugEnabled() == true) {
@@ -141,19 +151,60 @@ public class DocumentUtils {
                }
        }
        
+       //
+       // Look for an XML Schema (.xsd) file for the incoming part payload
+       //
+       String serverRoot = ServiceMain.getInstance().getServerRootDir();
+       String schemasDir = serverRoot + FILE_SEPARATOR + 
+               SCHEMAS_DIR + FILE_SEPARATOR;
+       
+       //
+       // Send a warning to the log file if the XML Schema file is missing
+       //
+       String schemaName = schemasDir + partMeta.getLabel() + XML_SCHEMA_EXTENSION;
+       File schemaFile = null;
+       try {
+               schemaFile = new File(schemaName);
+       } catch (Exception e) {
+               if (logger.isDebugEnabled() == true) {
+                       logger.warn("Missing schema file: " + schemaName);
+               }
+       }
+       
         try {
             // Create a builder factory
             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-            factory.setValidating(false);//TODO take validating value from meta
+//            factory.setNamespaceAware(true);
+            factory.setValidating(true);
+            try {
+               factory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
+               if (schemaFile != null) {
+                       factory.setAttribute(JAXP_SCHEMA_SOURCE, schemaFile);
+               }
+            } catch (IllegalArgumentException x) {
+                logger.warn("Error: JAXP DocumentBuilderFactory attribute not recognized: "
+                        + JAXP_SCHEMA_LANGUAGE);
+                logger.warn("Check to see if parser conforms to JAXP 1.2 spec.");
+                throw x;
+            }
 
+            //
+            // Lexical Control Settings that focus on content
+            //
+            factory.setCoalescing(true);
+            factory.setExpandEntityReferences(true);
+            factory.setIgnoringComments(true);
+            factory.setIgnoringElementContentWhitespace(true);            
+            
             // Create the builder and parse the file
             result = factory.newDocumentBuilder().parse(payload);
+            result.normalizeDocument();
             
             // Write it to the log so we can see what we've created.
             if (logger.isDebugEnabled() == true) {
+               logger.debug(xmlToString(result));
                System.out.println(xmlToString(result));
             }
-
         } finally {
             if (payload != null) {
                 payload.close();
@@ -169,11 +220,11 @@ public class DocumentUtils {
      * @return map key=property name, value=property value
      * @throws Exception
      */
-    public static Map<String, Object> parseProperties(Document document)
+    public static Map<String, Object> parseProperties(Node document)
             throws Exception {
         HashMap<String, Object> objectProps = new HashMap<String, Object>();
         // Get a list of all elements in the document
-        Node root = document.getFirstChild();
+        Node root = document;//.getFirstChild();
         NodeList rootChildren = root.getChildNodes();
         for (int i = 0; i < rootChildren.getLength(); i++) {
             Node node = rootChildren.item(i);
@@ -204,29 +255,78 @@ public class DocumentUtils {
     }
 
     /**
-     * getMultiValues retrieve multi-value element values
+     * getMultiStringValues 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) {
+    private static String[] getMultiStringValues(Node node) {
         ArrayList<String> vals = new ArrayList<String>();
         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
+            //assumption: backend does not support more than 2 levels 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]);
     }
+    
+    /**
+     * Removes all the immediate child text nodes.
+     *
+     * @param parent the parent
+     * @return the element
+     */
+    private static Node removeTextNodes(Node parent) {
+       Node result = parent;
+       
+       NodeList nodeList = parent.getChildNodes();
+       int nodeListSize = nodeList.getLength();
+       for (int i = 0; i < nodeListSize; i++) {
+               Node child = nodeList.item(i);
+               if (child != null && child.getNodeType() == Node.TEXT_NODE) {
+                       parent.removeChild(child);
+               }
+       }
+       
+       return result;
+    }
+
+    /**
+     * getMultiValues retrieve multi-value element values
+     * assumption: backend does not support more than 1 level deep hierarchy
+     * @param node
+     * @return
+     */
+    private static Object getMultiValues(Node node) throws Exception {
+       Object result = null;           
+       
+        Node child = removeTextNodes(node).getFirstChild();
+        Node grandChild = child.getFirstChild();
+        
+        if (grandChild != null) {
+               if (grandChild.getNodeType() == Node.TEXT_NODE) {
+                       result = getMultiStringValues(node);
+               } else {
+                   ArrayList<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
+                   NodeList nodeChildren = node.getChildNodes();
+                   for (int i = 0; i < nodeChildren.getLength(); i++) {
+                       Node nodeChild = nodeChildren.item(i);
+                       Map<String, Object> hashMap = parseProperties(nodeChild);
+                       values.add(hashMap);
+                   }
+                   result = values;
+               }
+        }
+        
+        return result;
+    }
 
     /**
      * getTextNodeValue retrieves text node value
@@ -314,22 +414,36 @@ public class DocumentUtils {
         root.setAttribute("xmlns:" + ns, xc.getNamespaceURI());
         document.appendChild(root);
 
+        buildDocument(document, root, objectProps);
+        
+        return document;
+    }
+    
+    /**
+     * Builds the document.
+     *
+     * @param document the document
+     * @param e the e
+     * @param objectProps the object props
+     * @throws Exception the exception
+     */
+    public static void buildDocument(Document document, Element e,
+            Map<String, Object> objectProps) throws Exception {
         for (String prop : objectProps.keySet()) {
             Object value = objectProps.get(prop);
             if (value != null) {
                 //no need to qualify each element name as namespace is already added
-                Element e = document.createElement(prop);
-                root.appendChild(e);
+                Element newElement = document.createElement(prop);
+                e.appendChild(newElement);
                 if (value instanceof ArrayList<?>) {
                     //multi-value element
-                    insertMultiValues(document, e, (ArrayList<String>) value);
+                    insertMultiValues(document, newElement, (ArrayList<String>) value);
                 } else {
                     String strValue = objectProps.get(prop).toString();
-                    insertTextNode(document, e, strValue);
+                    insertTextNode(document, newElement, strValue);
                 }
             }
         }
-        return document;
     }
 
     /**
@@ -339,17 +453,63 @@ public class DocumentUtils {
      * @param e the e
      * @param vals the vals
      */
-    private static void insertMultiValues(Document document, Element e, ArrayList<String> vals) {
+    private static void insertMultiStringValues(Document document, Element e, ArrayList<String> vals) {
         String parentName = e.getNodeName();
         
-        for (Object o : vals) {
-            String val = (String) o; //force cast
+        for (String o : vals) {
+            String val = o;
             NameValue nv = unqualify(val);
             Element c = document.createElement(nv.name);
             e.appendChild(c);
             insertTextNode(document, c, nv.value);
         }
     }
+    
+    /**
+     * Insert multi hash map values.
+     *
+     * @param document the document
+     * @param e the e
+     * @param vals the vals
+     * @throws Exception the exception
+     */
+    private static void insertMultiHashMapValues(Document document, Element e, ArrayList<Map<String, Object>> vals)
+               throws Exception {
+        String parentName = e.getNodeName();
+        String childName = null;
+        if (parentName.endsWith("List") == true) {
+               int parentNameLen = parentName.length();
+               childName = parentName.substring(0, parentNameLen - "List".length());
+        } else {
+               throw new Exception("Unknown node type from a Nuxeo document type.");
+        }
+                
+        for (Map<String, Object> map : vals) {
+            Element newNode = document.createElement(childName);
+            e.appendChild(newNode);
+            buildDocument(document, newNode, map);
+        }
+    }
+
+    /**
+     * Insert multi values.
+     *
+     * @param document the document
+     * @param e the e
+     * @param vals the vals
+     * @throws Exception the exception
+     */
+    private static void insertMultiValues(Document document, Element e, ArrayList<?> vals)
+               throws Exception {
+       if (vals != null && vals.size() > 0) {
+               Object firstElement = vals.get(0);
+               if (firstElement instanceof String) {
+                       insertMultiStringValues(document, e, (ArrayList<String>)vals);
+               } else if (firstElement instanceof Map<?, ?>) {
+                       insertMultiHashMapValues(document, e, (ArrayList<Map<String, Object>>)vals);
+               }
+       }
+    }
 
     /**
      * Insert text node.
@@ -433,7 +593,7 @@ public class DocumentUtils {
     /**
      * getXmlDocoument retrieve w3c.Document from given file
      * @param fileName
-     * @return
+     * @return Document
      * @throws Exception
      */
     public static Document getXmlDocument(String fileName) throws Exception {
index 05ded5bb0bad6e80d9085cc6b3aa686c54c63e20..8d2aafc50239fec677a116b509f38ed53f556502 100644 (file)
@@ -66,10 +66,14 @@ import org.w3c.dom.Document;
 public abstract class RemoteDocumentModelHandlerImpl<T, TL>
         extends DocumentModelHandler<T, TL> {
 
+    /** The logger. */
     private final Logger logger = LoggerFactory.getLogger(RemoteDocumentModelHandlerImpl.class);
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.common.document.AbstractDocumentHandlerImpl#setServiceContext(org.collectionspace.services.common.context.ServiceContext)
+     */
     @Override
-    public void setServiceContext(ServiceContext ctx) {
+    public void setServiceContext(ServiceContext ctx) {  //FIXME: Apply proper generics to ServiceContext<MultipartInput, MultipartOutput>
         if(ctx instanceof MultipartServiceContext){
             super.setServiceContext(ctx);
         }else{
@@ -78,6 +82,9 @@ public abstract class RemoteDocumentModelHandlerImpl<T, TL>
         }
     }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#completeUpdate(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public void completeUpdate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
         DocumentModel docModel = wrapDoc.getWrappedObject();
@@ -94,17 +101,24 @@ public abstract class RemoteDocumentModelHandlerImpl<T, TL>
         }
     }
 
-    protected void addOutputPart(Map<String, Object> unQObjectProperties, String schema, ObjectPartType partMeta)
+    /**
+     * Adds the output part.
+     *
+     * @param unQObjectProperties the un q object properties
+     * @param schema the schema
+     * @param partMeta the part meta
+     * @throws Exception the exception
+     */
+    private void addOutputPart(Map<String, Object> unQObjectProperties, String schema, ObjectPartType partMeta)
                throws Exception {
                Document doc = DocumentUtils.buildDocument(partMeta, schema,
                                unQObjectProperties);
-               if (logger.isDebugEnabled()) {
-                       DocumentUtils.writeDocument(doc, System.out);
+               if (logger.isDebugEnabled() == true) {                  
+                       logger.debug(DocumentUtils.xmlToString(doc));
                }
                MultipartServiceContext ctx = (MultipartServiceContext) getServiceContext();
                ctx.addOutputPart(schema, doc, partMeta.getContent().getContentType());
-    }
-    
+    }    
     
     /**
      * Extract paging info.
@@ -133,6 +147,9 @@ public abstract class RemoteDocumentModelHandlerImpl<T, TL>
     }
     
     
+       /* (non-Javadoc)
+        * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#extractAllParts(org.collectionspace.services.common.document.DocumentWrapper)
+        */
        @Override
        public void extractAllParts(DocumentWrapper<DocumentModel> wrapDoc)
                        throws Exception {
@@ -150,6 +167,9 @@ public abstract class RemoteDocumentModelHandlerImpl<T, TL>
                }
        }
 
+    /* (non-Javadoc)
+     * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#fillAllParts(org.collectionspace.services.common.document.DocumentWrapper)
+     */
     @Override
     public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
 
@@ -202,10 +222,10 @@ public abstract class RemoteDocumentModelHandlerImpl<T, TL>
         //check if this is an xml part
         if(part.getMediaType().equals(MediaType.APPLICATION_XML_TYPE)){
             if(payload != null){
-                Document document = DocumentUtils.parseDocument(payload);
+                Document document = DocumentUtils.parseDocument(payload, partMeta);
                 //TODO: callback to handler if registered to validate the
                 //document
-                Map<String, Object> objectProps = DocumentUtils.parseProperties(document);
+                Map<String, Object> objectProps = DocumentUtils.parseProperties(document.getFirstChild());
                 docModel.setProperties(partMeta.getLabel(), objectProps);
             }
         }
index f5adcea72afde26e93a6d6a931177ac505c747a1..4685928db4b2bfa7e6985ae74130d79cba8d0ab1 100644 (file)
@@ -25,20 +25,14 @@ package org.collectionspace.services.nuxeo.client.java;
 \r
 import java.io.InputStream;\r
 import java.util.HashMap;\r
-import java.util.List;\r
 import java.util.Map;\r
-import java.util.Set;\r
-import java.util.Map.Entry;\r
 \r
-import javax.ws.rs.core.MediaType;\r
-\r
-import org.collectionspace.services.common.context.MultipartServiceContext;\r
 import org.collectionspace.services.common.document.DocumentUtils;\r
-import org.collectionspace.services.common.document.DocumentWrapper;\r
 import org.collectionspace.services.common.service.ObjectPartType;\r
+\r
 import org.jboss.resteasy.plugins.providers.multipart.InputPart;\r
+import javax.ws.rs.core.MediaType;\r
 import org.nuxeo.ecm.core.api.DocumentModel;\r
-import org.nuxeo.ecm.core.api.DocumentModelList;\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 import org.w3c.dom.Document;\r
@@ -80,10 +74,10 @@ public abstract class RemoteSubItemDocumentModelHandlerImpl<T, TL> extends
         // and then check that here, so skip other parts.\r
         if(part.getMediaType().equals(MediaType.APPLICATION_XML_TYPE)){\r
             if(payload != null){\r
-                Document document = DocumentUtils.parseDocument(payload);\r
+                Document document = DocumentUtils.parseDocument(payload, partMeta);\r
                 //TODO: callback to handler if registered to validate the\r
                 //document\r
-                Map<String, Object> objectProps = DocumentUtils.parseProperties(document);\r
+                Map<String, Object> objectProps = DocumentUtils.parseProperties(document.getFirstChild());\r
                 // Now pull out the subitem props and set them into the Subitem schema\r
                 Map<String, Object> subitemProps = null;\r
                 for(String key:fields){\r