[PATCH 5 of 5 seda] [profile gen] Support for digest algorithm in SEDA 0.2 export

Sylvain Thenault sylvain.thenault at logilab.fr
Thu Mar 9 17:13:52 CET 2017


# HG changeset patch
# User Sylvain Thénault <sylvain.thenault at logilab.fr>
# Date 1489073335 -3600
#      Thu Mar 09 16:28:55 2017 +0100
# Node ID d331fbee620a18b66b60f7cc518c395cb5e53342
# Parent  6c5b6306437922460ddc337b805854000941c244
[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

diff --git a/cubicweb_seda/entities/profile_generation.py b/cubicweb_seda/entities/profile_generation.py
--- a/cubicweb_seda/entities/profile_generation.py
+++ b/cubicweb_seda/entities/profile_generation.py
@@ -1304,15 +1304,26 @@ class SEDA02XSDExport(SEDA1XSDExport):
 
     namespaces = SEDA1XSDExport.namespaces.copy()
     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',
                                            cardinality=archive_unit.user_cardinality,
                                            documentation=archive_unit.user_annotation,
@@ -1356,13 +1367,15 @@ class SEDA02XSDExport(SEDA1XSDExport):
         # elements)
         ao_node.insert(0, ao_node[-1])
 
     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)
         self.xsd_date_created(document_node, data_object)
         self.xsd_system_id(document_node, data_object)
@@ -1385,10 +1398,21 @@ class SEDA02XSDExport(SEDA1XSDExport):
             self.element_schema(parent, 'CustodialHistory', 'udt:TextType',
                                 cardinality=item.user_cardinality,
                                 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'
     # in SEDA 0.2, AccessRestrictionRule tag name is 'AccessRestriction'
     access_restriction_tag_name = 'AccessRestriction'
@@ -1459,10 +1483,12 @@ class SEDA02RNGExport(OldSEDARNGExportMi
     """
     __regid__ = 'SEDA-0.2.rng'
 
     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',
     }
 
diff --git a/test/data/seda_02_export.rng b/test/data/seda_02_export.rng
--- a/test/data/seda_02_export.rng
+++ b/test/data/seda_02_export.rng
@@ -1,13 +1,15 @@
 <?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"
     datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
     ns="fr:gouv:ae:archive:draft:standard_echange_v0.2">
@@ -143,10 +145,23 @@
           <rng:element name="Name">
             <rng:data type="string"/>
           </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>
             <xsd:documentation>archive unit title</xsd:documentation>
           </xsd:annotation>
@@ -491,11 +506,11 @@
                 </rng:element>
               </rng:element>
             </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>
               <rng:optional>
                 <rng:attribute name="Id">
diff --git a/test/data/seda_02_export.xsd b/test/data/seda_02_export.xsd
--- a/test/data/seda_02_export.xsd
+++ b/test/data/seda_02_export.xsd
@@ -5,10 +5,11 @@
     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"
     attributeFormDefault="unqualified"
     elementFormDefault="qualified"
@@ -84,10 +85,26 @@
               </xsd:element>
               <xsd:element minOccurs="0" name="Name" type="udt:TextType"/>
             </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>
           </xsd:annotation>
           <xsd:complexType>
@@ -391,11 +408,11 @@
                     </xsd:element>
                   </xsd:sequence>
                   <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>
                 <xsd:complexType>
                   <xsd:sequence>
diff --git a/test/test_profile_generation.py b/test/test_profile_generation.py
--- a/test/test_profile_generation.py
+++ b/test/test_profile_generation.py
@@ -826,10 +826,11 @@ class OldSEDAExportMixin(object):
                                                                    user_cardinality=u'1..n')
 
             cnx.commit()
 
         self.transfer_eid = transfer.eid
+        self.bdo_eid = bdo.eid
         self.file_concept_eid = concepts['file'].eid
         self.agent_eid = agent.eid
 
     def _test_profile(self, adapter_id, expected_file):
         with self.admin_access.client_cnx() as cnx:
@@ -853,11 +854,12 @@ class OldSEDAExportMixin(object):
 
             root = etree.fromstring(generated_xsd)
             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())},
                                     generated_xsd)
             return adapter, root


More information about the saem-devel mailing list