[profile gen] Support for digest algorithm in SEDA 0.2 export
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 09 Mar 2017 16:28:55 +0100
changeset 2474 d331fbee620a
parent 2473 6c5b63064379
child 2476 9e7a025cd039
[profile gen] Support for digest algorithm in SEDA 0.2 export This is a bit tough since in SEDA 0.2, Integrity element are defined as children of the root transfer node, hence we have to reuse the kind of reference trick we have in SEDA 0.2 export: document export a seda:profid attribute whose value is the referenced by default value on the UnitIdentifier element associated to the digest (and algorithm) definition. Related to #16687452
cubicweb_seda/entities/profile_generation.py
test/data/seda_02_export.rng
test/data/seda_02_export.xsd
test/test_profile_generation.py
--- a/cubicweb_seda/entities/profile_generation.py	Thu Mar 09 16:26:34 2017 +0100
+++ b/cubicweb_seda/entities/profile_generation.py	Thu Mar 09 16:28:55 2017 +0100
@@ -1306,11 +1306,22 @@
     namespaces[None] = 'fr:gouv:ae:archive:draft:standard_echange_v0.2'
     namespaces['qdt'] = 'fr:gouv:ae:archive:draft:standard_echange_v0.2:QualifiedDataType:1'
     namespaces['udt'] = 'urn:un:unece:uncefact:data:standard:UnqualifiedDataType:6'
+    namespaces['seda'] = 'fr:gouv:culture:archivesdefrance:seda:v2.0'
 
     root_attributes = SEDA1XSDExport.root_attributes.copy()
     root_attributes['targetNamespace'] = 'fr:gouv:ae:archive:draft:standard_echange_v0.2'
     root_attributes['version'] = '1.1'
 
+    def xsd_transfer(self, parent, archive_transfer):
+        """Append XSD elements for the archive transfer to the given parent node."""
+        transfer_node = self.xsd_transfer_base(parent, archive_transfer)
+
+        for data_object in archive_transfer.binary_data_objects:
+            self.xsd_integrity(transfer_node, data_object)
+
+        for archive_unit in archive_transfer.archive_units:
+            self.xsd_archive(transfer_node, archive_unit)
+
     def xsd_archive(self, parent, archive_unit):
         """Append XSD elements for an archive to the given parent node."""
         archive_node = self.element_schema(parent, 'Contains',
@@ -1358,9 +1369,11 @@
 
     def xsd_document(self, parent, data_object):
         """Append XSD elements for the document to the given parent node."""
+        xmlid = eid2xmlid(data_object.eid)
         document_node = self.element_schema(parent, 'Document',
                                             cardinality=data_object.user_cardinality,
                                             documentation=data_object.user_annotation,
+                                            extra_attributes={'seda:profid': xmlid},
                                             xsd_attributes=[XAttr('Id', 'xsd:ID')])
 
         self.xsd_attachment(document_node, data_object)
@@ -1387,6 +1400,17 @@
                                 documentation=item.user_annotation,
                                 xsd_attributes=[XAttr('languageID', 'xsd:language')])
 
+    def xsd_integrity(self, parent, data_object):
+        integrity = self.element_schema(parent, 'Integrity', cardinality='0..1')
+        algorithm = data_object.seda_algorithm[0] if data_object.seda_algorithm else None
+        self.element_schema(integrity, 'Contains', 'qdt:ArchivesHashcodeBinaryObjectType',
+                            xsd_attributes=[XAttr('algorithme', 'xsd:string',
+                                                  cardinality='1',
+                                                  fixed_value=_concept_value(
+                                                      algorithm, self.concepts_language))])
+        self.element_schema(integrity, 'UnitIdentifier', 'qdt:ArchivesIDType',
+                            default_value=eid2xmlid(data_object.eid))
+
     system_id_tag_name = 'Identification'
     # in SEDA 0.2, ArchiveObject tag name is 'Contains' (as for Archive)
     archive_object_tag_name = 'Contains'
@@ -1461,6 +1485,8 @@
 
     namespaces = SEDA1XSDExport.namespaces.copy()
     namespaces['rng'] = 'http://relaxng.org/ns/structure/1.0'
+    namespaces['a'] = 'http://relaxng.org/ns/compatibility/annotations/1.0'
+    namespaces['seda'] = 'fr:gouv:culture:archivesdefrance:seda:v2.0'
     root_attributes = {
         'ns': 'fr:gouv:ae:archive:draft:standard_echange_v0.2',
         'datatypeLibrary': 'http://www.w3.org/2001/XMLSchema-datatypes',
--- a/test/data/seda_02_export.rng	Thu Mar 09 16:26:34 2017 +0100
+++ b/test/data/seda_02_export.rng	Thu Mar 09 16:28:55 2017 +0100
@@ -1,11 +1,13 @@
 <?xml version='1.0' encoding='utf-8' standalone='no'?>
 <rng:grammar
+    xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
     xmlns:clmDAFFileTypeCode="urn:un:unece:uncefact:codelist:draft:DAF:fileTypeCode:2009-08-18"
     xmlns:clmIANACharacterSetCode="urn:un:unece:uncefact:codelist:standard:IANA:CharacterSetCode:2007-05-14"
     xmlns:clmIANAMIMEMediaType="urn:un:unece:uncefact:codelist:standard:IANA:MIMEMediaType:2008-11-12"
     xmlns:clm60133="urn:un:unece:uncefact:codelist:standard:6:0133:40106"
     xmlns:qdt="fr:gouv:culture:archivesdefrance:seda:v1.0:QualifiedDataType:1"
     xmlns:rng="http://relaxng.org/ns/structure/1.0"
+    xmlns:seda="fr:gouv:culture:archivesdefrance:seda:v2.0"
     xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:10"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     xmlns="fr:gouv:culture:archivesdefrance:seda:v1.0"
@@ -145,6 +147,19 @@
           </rng:element>
         </rng:optional>
       </rng:element>
+      <rng:optional>
+        <rng:element name="Integrity">
+          <rng:element name="Contains">
+            <rng:attribute name="algorithme">
+              <rng:value type="string">md5</rng:value>
+            </rng:attribute>
+            <rng:data type="string"/>
+          </rng:element>
+          <rng:element name="UnitIdentifier" a:defaultValue="id6120">
+            <rng:data type="string"/>
+          </rng:element>
+        </rng:element>
+      </rng:optional>
       <rng:oneOrMore>
         <rng:element name="Contains">
           <xsd:annotation>
@@ -493,7 +508,7 @@
             </rng:element>
           </rng:oneOrMore>
           <rng:zeroOrMore>
-            <rng:element name="Document">
+            <rng:element name="Document" seda:profid="id%(bdo-eid)s">
               <xsd:annotation>
                 <xsd:documentation>data object title</xsd:documentation>
               </xsd:annotation>
--- a/test/data/seda_02_export.xsd	Thu Mar 09 16:26:34 2017 +0100
+++ b/test/data/seda_02_export.xsd	Thu Mar 09 16:28:55 2017 +0100
@@ -7,6 +7,7 @@
     xmlns:clm60133="urn:un:unece:uncefact:codelist:standard:6:0133:40106"
     xmlns:qdt="fr:gouv:culture:archivesdefrance:seda:v1.0:QualifiedDataType:1"
     xmlns:rng="http://relaxng.org/ns/structure/1.0"
+    xmlns:seda="fr:gouv:culture:archivesdefrance:seda:v2.0"
     xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:10"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     xmlns="fr:gouv:culture:archivesdefrance:seda:v1.0"
@@ -86,6 +87,22 @@
             </xsd:sequence>
           </xsd:complexType>
         </xsd:element>
+        <xsd:element minOccurs="0" name="Integrity">
+          <xsd:complexType>
+            <xsd:sequence>
+              <xsd:element name="Contains">
+                <xsd:complexType>
+                  <xsd:simpleContent>
+                    <xsd:extension base="qdt:ArchivesHashcodeBinaryObjectType">
+                      <xsd:attribute fixed="md5" name="algorithme" type="xsd:string" use="required"/>
+                    </xsd:extension>
+                  </xsd:simpleContent>
+                </xsd:complexType>
+              </xsd:element>
+              <xsd:element default="id%(bdo-eid)s" name="UnitIdentifier" type="qdt:ArchivesIDType"/>
+            </xsd:sequence>
+          </xsd:complexType>
+        </xsd:element>
         <xsd:element maxOccurs="unbounded" name="Contains">
           <xsd:annotation>
             <xsd:documentation>archive unit title</xsd:documentation>
@@ -393,7 +410,7 @@
                   <xsd:attribute name="Id" type="xsd:ID" use="optional"/>
                 </xsd:complexType>
               </xsd:element>
-              <xsd:element maxOccurs="unbounded" minOccurs="0" name="Document">
+              <xsd:element maxOccurs="unbounded" minOccurs="0" name="Document" seda:profid="id%(bdo-eid)s">
                 <xsd:annotation>
                   <xsd:documentation>data object title</xsd:documentation>
                 </xsd:annotation>
--- a/test/test_profile_generation.py	Thu Mar 09 16:26:34 2017 +0100
+++ b/test/test_profile_generation.py	Thu Mar 09 16:28:55 2017 +0100
@@ -828,6 +828,7 @@
             cnx.commit()
 
         self.transfer_eid = transfer.eid
+        self.bdo_eid = bdo.eid
         self.file_concept_eid = concepts['file'].eid
         self.agent_eid = agent.eid
 
@@ -855,7 +856,8 @@
             self.assertXmlValid(root)
             with open(self.datapath(expected_file)) as expected:
                 self.assertXmlEqual(expected.read()
-                                    % {'concept-uri': binary_type(file_concept.cwuri),
+                                    % {'bdo-eid': binary_type(self.bdo_eid),
+                                       'concept-uri': binary_type(file_concept.cwuri),
                                        'scheme-uri': binary_type(file_concept.scheme.cwuri),
                                        'agent-id': binary_type(agent.eid),
                                        'agent-name': binary_type(agent.dc_title())},