[PATCH seda V2] [profile gen] Ensure data-objects are exported before sub-units in SEDA 0.2

Sylvain Thenault sylvain.thenault at logilab.fr
Tue Aug 29 18:20:36 CEST 2017


 cubicweb_seda/entities/profile_generation.py |   8 ++-
 test/data/seda_02_export.rng                 |  60 ++++++++++++------------
 test/data/seda_02_export.xsd                 |  66 ++++++++++++++--------------
 test/test_profile_generation.py              |  27 +++++++++++
 4 files changed, 97 insertions(+), 64 deletions(-)


# HG changeset patch
# User Sylvain Thénault <sylvain.thenault at logilab.fr>
# Date 1504017381 -7200
#      Tue Aug 29 16:36:21 2017 +0200
# Node ID 68c5f87f8677d2e0b218928a437e8efab30933a8
# Parent  274dcd2aafbfcb7a6cd864e039e6cf4b4918fb17
# Available At https://hg.logilab.org/review/cubes/seda
#              hg pull https://hg.logilab.org/review/cubes/seda -r 68c5f87f8677
[profile gen] Ensure data-objects are exported before sub-units in SEDA 0.2

else this won't be conform to the SEDA 0.2schema. But notice this is the
opposite in SEDA 1.0. In this case, test cases were fine but the problem was
actually the same: data-objects and sub-units order was random, and it's not
anymore.

As we are here, add eid so we get a total ordering, which is an expected
property so that exported profiles are consistent during time. This should be
enough until we want to control ordering from the UI.

Closes extranet #33070904

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
@@ -812,15 +812,19 @@ class SEDA1XSDExport(SEDA2ExportAdapter)
         self.xsd_attachment(document_node, data_object)
         self.xsd_date_created(document_node, data_object)
         self.xsd_integrity(document_node, data_object)
         self.xsd_document_type(document_node, data_object)
 
+    # in SEDA 1 sub-archive units are exposed before data objects
+    last_children_type = 'SEDABinaryDataObject'
+
     def xsd_children(self, parent, entity):
         """Iter on archive/archive object children, which may be either
         archive objects or documents, and append XSD elements for them to the given parent node.
         """
-        for au_or_bdo in entity.cw_adapt_to('ITreeBase').iterchildren():
+        for au_or_bdo in sorted(entity.cw_adapt_to('ITreeBase').iterchildren(),
+                                key=lambda x: (x.cw_etype == self.last_children_type, x.eid)):
             if au_or_bdo.cw_etype == 'SEDABinaryDataObject':
                 self.xsd_document(parent, au_or_bdo)
             else:
                 assert au_or_bdo.cw_etype == 'SEDAArchiveUnit'
                 self.xsd_archive_object(parent, au_or_bdo)
@@ -1239,10 +1243,12 @@ class SEDA02XSDExport(SEDA1XSDExport):
     # in SEDA 0.2, keyword tag name is 'ContentDescriptive', not 'Keyword' and keyword content type
     # is TextType and there is no 'role' attribute
     kw_tag_name = 'ContentDescriptive'
     kw_content_tag_type = 'udt:TextType'
     kw_content_tag_attributes = [XAttr('languageID', 'xsd:language')]
+    # in SEDA 0.2 data objects are exposed before sub-archive units
+    last_children_type = 'SEDAArchiveUnit'
 
 
 class OldSEDARNGExportMixin(RNGMixin):
 
     def element_schema(self, parent, name, xsd_type=None,
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
@@ -370,10 +370,40 @@
             </rng:element>
             <rng:element name="StartDate">
               <rng:data type="string"/>
             </rng:element>
           </rng:element>
+          <rng:zeroOrMore>
+            <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">
+                  <rng:data type="ID"/>
+                </rng:attribute>
+              </rng:optional>
+              <rng:element name="Attachment">
+                <rng:attribute name="format">
+                  <rng:value type="string">fmt/123</rng:value>
+                </rng:attribute>
+                <rng:attribute name="encodingCode">
+                  <rng:value type="string">6</rng:value>
+                </rng:attribute>
+                <rng:attribute name="filename">
+                  <rng:value type="string">this_is_the_filename.pdf</rng:value>
+                </rng:attribute>
+                <rng:data type="string"/>
+              </rng:element>
+              <rng:element name="Type">
+                <rng:attribute name="listVersionID">
+                  <rng:value type="token">edition 2009</rng:value>
+                </rng:attribute>
+                <rng:value type="string">CDO</rng:value>
+              </rng:element>
+            </rng:element>
+          </rng:zeroOrMore>
           <rng:oneOrMore>
             <rng:element name="Contains">
               <rng:element name="DescriptionLevel">
                 <rng:attribute name="listVersionID">
                   <rng:value type="token">edition 2009</rng:value>
@@ -505,40 +535,10 @@
                   <rng:data type="string"/>
                 </rng:element>
               </rng:element>
             </rng:element>
           </rng:oneOrMore>
-          <rng:zeroOrMore>
-            <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">
-                  <rng:data type="ID"/>
-                </rng:attribute>
-              </rng:optional>
-              <rng:element name="Attachment">
-                <rng:attribute name="format">
-                  <rng:value type="string">fmt/123</rng:value>
-                </rng:attribute>
-                <rng:attribute name="encodingCode">
-                  <rng:value type="string">6</rng:value>
-                </rng:attribute>
-                <rng:attribute name="filename">
-                  <rng:value type="string">this_is_the_filename.pdf</rng:value>
-                </rng:attribute>
-                <rng:data type="string"/>
-              </rng:element>
-              <rng:element name="Type">
-                <rng:attribute name="listVersionID">
-                  <rng:value type="token">edition 2009</rng:value>
-                </rng:attribute>
-                <rng:value type="string">CDO</rng:value>
-              </rng:element>
-            </rng:element>
-          </rng:zeroOrMore>
         </rng:element>
       </rng:oneOrMore>
     </rng:element>
   </rng:start>
 </rng:grammar>
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
@@ -272,10 +272,43 @@
                     <xsd:element name="StartDate" type="udt:DateType"/>
                   </xsd:sequence>
                   <xsd:attribute name="Id" type="xsd:ID" use="optional"/>
                 </xsd:complexType>
               </xsd:element>
+              <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>
+                    <xsd:element name="Attachment">
+                      <xsd:complexType>
+                        <xsd:simpleContent>
+                          <xsd:extension base="qdt:ArchivesBinaryObjectType">
+                            <xsd:attribute fixed="fmt/123" name="format" type="clmDAFFileTypeCode:FileTypeCodeType" use="required"/>
+                            <xsd:attribute fixed="6" name="encodingCode" type="clm60133:CharacterSetEncodingCodeContentType" use="required"/>
+                            <xsd:attribute name="mimeCode" type="clmIANAMIMEMediaType:MIMEMediaTypeContentType" use="prohibited"/>
+                            <xsd:attribute fixed="this_is_the_filename.pdf" name="filename" type="xsd:string" use="required"/>
+                            <xsd:attribute name="characterSetCode" type="clmIANACharacterSetCode:CharacterSetCodeContentType" use="prohibited"/>
+                            <xsd:attribute name="uri" type="xsd:anyURI" use="prohibited"/>
+                          </xsd:extension>
+                        </xsd:simpleContent>
+                      </xsd:complexType>
+                    </xsd:element>
+                    <xsd:element fixed="CDO" name="Type">
+                      <xsd:complexType>
+                        <xsd:simpleContent>
+                          <xsd:extension base="qdt:CodeDocumentType">
+                            <xsd:attribute fixed="edition 2009" name="listVersionID" type="xsd:token" use="required"/>
+                          </xsd:extension>
+                        </xsd:simpleContent>
+                      </xsd:complexType>
+                    </xsd:element>
+                  </xsd:sequence>
+                  <xsd:attribute name="Id" type="xsd:ID" use="optional"/>
+                </xsd:complexType>
+              </xsd:element>
               <xsd:element maxOccurs="unbounded" name="Contains">
                 <xsd:annotation>
                   <xsd:documentation>archive unit title</xsd:documentation>
                 </xsd:annotation>
                 <xsd:complexType>
@@ -408,43 +441,10 @@
                     </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" seda:profid="id%(bdo-eid)s">
-                <xsd:annotation>
-                  <xsd:documentation>data object title</xsd:documentation>
-                </xsd:annotation>
-                <xsd:complexType>
-                  <xsd:sequence>
-                    <xsd:element name="Attachment">
-                      <xsd:complexType>
-                        <xsd:simpleContent>
-                          <xsd:extension base="qdt:ArchivesBinaryObjectType">
-                            <xsd:attribute fixed="fmt/123" name="format" type="clmDAFFileTypeCode:FileTypeCodeType" use="required"/>
-                            <xsd:attribute fixed="6" name="encodingCode" type="clm60133:CharacterSetEncodingCodeContentType" use="required"/>
-                            <xsd:attribute name="mimeCode" type="clmIANAMIMEMediaType:MIMEMediaTypeContentType" use="prohibited"/>
-                            <xsd:attribute fixed="this_is_the_filename.pdf" name="filename" type="xsd:string" use="required"/>
-                            <xsd:attribute name="characterSetCode" type="clmIANACharacterSetCode:CharacterSetCodeContentType" use="prohibited"/>
-                            <xsd:attribute name="uri" type="xsd:anyURI" use="prohibited"/>
-                          </xsd:extension>
-                        </xsd:simpleContent>
-                      </xsd:complexType>
-                    </xsd:element>
-                    <xsd:element fixed="CDO" name="Type">
-                      <xsd:complexType>
-                        <xsd:simpleContent>
-                          <xsd:extension base="qdt:CodeDocumentType">
-                            <xsd:attribute fixed="edition 2009" name="listVersionID" type="xsd:token" use="required"/>
-                          </xsd:extension>
-                        </xsd:simpleContent>
-                      </xsd:complexType>
-                    </xsd:element>
-                  </xsd:sequence>
-                  <xsd:attribute name="Id" type="xsd:ID" use="optional"/>
-                </xsd:complexType>
-              </xsd:element>
             </xsd:sequence>
             <xsd:attribute name="Id" type="xsd:ID" use="optional"/>
           </xsd:complexType>
         </xsd:element>
       </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
@@ -915,10 +915,37 @@ class OldSEDARNGExportTC(RelaxNGTestMixi
             cnx.commit()
 
             root = self.profile_etree(transfer, 'SEDA-0.2.rng')
         self.check_xsd_profile(root, self.datapath('seda_02_bordereau_ref.xml'))
 
+    def test_children_order(self):
+        with self.admin_access.cnx() as cnx:
+            create = cnx.create_entity
+
+            transfer = create('SEDAArchiveTransfer', title=u'test profile',
+                              simplified_profile=True)
+            unit, unit_alt, unit_alt_seq = testutils.create_archive_unit(transfer)
+            subunit, subunit_alt, subunit_alt_seq = testutils.create_archive_unit(
+                unit_alt_seq)
+            bdo = testutils.create_data_object(transfer)
+            create('SEDADataObjectReference',
+                   seda_data_object_reference=unit_alt_seq,
+                   seda_data_object_reference_id=bdo)
+            cnx.commit()
+
+            # ensure Document appears before Contains in SEDA 0.2
+            adapter = transfer.cw_adapt_to('SEDA-0.2.xsd')
+            root = etree.Element('test-root')
+            adapter.xsd_children(root, unit)
+            self.assertEqual([node.attrib['name'] for node in root], ['Document', 'Contains'])
+
+            # ensure Document appears after ArchiveObject in SEDA 1
+            adapter = transfer.cw_adapt_to('SEDA-1.0.xsd')
+            root = etree.Element('test-root')
+            adapter.xsd_children(root, unit)
+            self.assertEqual([node.attrib['name'] for node in root], ['ArchiveObject', 'Document'])
+
 
 class SEDAExportUnitTest(unittest.TestCase):
 
     def test_concepts_languages(self):
         self.assertEqual(pg.SEDA1XSDExport.concepts_language, 'seda-1')


More information about the saem-devel mailing list