[PATCH saem_ref v2] [seda] Handle all target types for seda_archive_unit relation in archive unit ARK attribution

Denis Laxalde denis.laxalde at logilab.fr
Tue May 15 10:59:54 CEST 2018


# HG changeset patch
# User Denis Laxalde <denis.laxalde at logilab.fr>
# Date 1526308617 -7200
#      Mon May 14 16:36:57 2018 +0200
# Node ID 2f47a5deb560ea6c14c0e2e8ad47815ea99afa85
# Parent  03cc50b258bb113a5352a406da447772bc091c2d
# Available At http://hg.logilab.org/review/cubes/saem_ref
#              hg pull http://hg.logilab.org/review/cubes/saem_ref -r 2f47a5deb560
# EXP-Topic CONSEJIRA-491
[seda] Handle all target types for seda_archive_unit relation in archive unit ARK attribution

Relation seda_archive_unit may have SEDAArchiveTransfer and
SEDASeqAltArchiveUnitArchiveUnitRefIdManagement entity types as object.
Previously, we only handled the first case which occurs when a
SEDAArchiveUnit is related directly to a SEDAArchiveTransfer. However,
when relating a SEDAArchiveUnit to another SEDAArchiveUnit our previous
assumption (that the target of seda_archive_unit relation has an
"ark_naa" relation) breaks, thus making it impossible to insert such a
relation.

We thus check the entity type of target of this relation in ARK locator
and generator for SEDAArchiveUnit. In case a
SEDASeqAltArchiveUnitArchiveUnitRefIdManagement entity type is obtained,
we use the "container" relation to obtain the archive transfer and its
ARK NAA. There might be a "business" way to obtain this information but,
given the complexity of the data model, I could not find it.

The consequence of this *fix* is that ARK identifiers of nested
SEDAArchiveUnit are now always qualified with respect to their parent.
This does not change if the parent is a SEDAArchiveTransfer but this
changes if it is another SEDAArchiveUnit since, previously, the nested
entity would simply have had an unqualified ARK: hopefully, it makes
sense from a business perspective...

CONSEJIRA-491.

diff --git a/cubicweb_saem_ref/entities/__init__.py b/cubicweb_saem_ref/entities/__init__.py
--- a/cubicweb_saem_ref/entities/__init__.py
+++ b/cubicweb_saem_ref/entities/__init__.py
@@ -102,6 +102,19 @@ class OUARKIdentifierGenerator(Qualified
         return self._cw.entity_from_eid(authority)
 
 
+def archive_unit_parent(parent):
+    assert parent.cw_etype in (
+        'SEDAArchiveTransfer',
+        'SEDASeqAltArchiveUnitArchiveUnitRefIdManagement',
+    ), '{} should be target of seda_archive_unit relation'.format(parent)
+    if parent.cw_etype == 'SEDASeqAltArchiveUnitArchiveUnitRefIdManagement':
+        # XXX We use the "container" relation since there appears to be no
+        # other way to get back the SEDAArchiveTransfer entity in case
+        # this is not the target.
+        parent = parent.container[0]
+    return parent
+
+
 class SEDAArchiveUnitARKIdentifierGenerator(QualifiedARKIdentifierGenerator):
     __select__ = (
         QualifiedARKIdentifierGenerator.__select__
@@ -110,10 +123,10 @@ class SEDAArchiveUnitARKIdentifierGenera
 
     @property
     def parent_entity(self):
-        transfer = self.cw_extra_kwargs['seda_archive_unit']
-        if hasattr(transfer, 'eid'):
-            return transfer
-        return self._cw.entity_from_eid(transfer)
+        target = self.cw_extra_kwargs['seda_archive_unit']
+        if not hasattr(target, 'eid'):
+            target = self._cw.entity_from_eid(target)
+        return archive_unit_parent(target)
 
 
 class ArkNAALocator(EntityAdapter):
@@ -182,14 +195,17 @@ class SEDAArchiveUnitArkNAALocator(ArkNA
     __select__ = is_instance('SEDAArchiveUnit')
 
     def naa_what(self):
+        edited = getattr(self.entity, 'cw_edited', {})
         # entity is usually not yet created, since ark has to be generated before entity creation
-        if 'seda_archive_unit' in getattr(self.entity, 'cw_edited', {}):
-            transfer = self._cw.entity_from_eid(self.entity.cw_edited['seda_archive_unit'])
-        elif self.entity.seda_archive_unit:
-            transfer = self.entity.seda_archive_unit[0]
+        if 'seda_archive_unit' in edited or self.entity.seda_archive_unit:
+            if 'seda_archive_unit' in edited:
+                target = self._cw.entity_from_eid(edited['seda_archive_unit'])
+            else:
+                target = self.entity.seda_archive_unit[0]
+            target = archive_unit_parent(target)
+            return target.cw_adapt_to(self.__regid__).naa_what()
         else:
             return direct_naa_what(self.entity)
-        return transfer.cw_adapt_to(self.__regid__).naa_what()
 
 
 class ExternalUri(AnyEntity):
diff --git a/test/test_seda.py b/test/test_seda.py
--- a/test/test_seda.py
+++ b/test/test_seda.py
@@ -149,6 +149,7 @@ class CloneImportTC(CubicWebTC):
                                                                          user_annotation=u'plop')
             self.transfer_eid = transfer.eid
             self.unit_eid = unit.eid
+            self.unit_alt_seq_eid = unit_alt_seq.eid
             cnx.commit()
 
     def test_import_one_entity(self):
@@ -170,6 +171,22 @@ class CloneImportTC(CubicWebTC):
             # archive transfer's ARK.
             self.assertTrue(imported_unit.ark.startswith(ark), imported_unit)
 
+    def test_create_nested_archive_unit(self):
+        with self.admin_access.cnx() as cnx:
+            unit_alt_seq = cnx.entity_from_eid(self.unit_alt_seq_eid)
+            unit, _, _ = testutils.create_archive_unit(
+                unit_alt_seq, cnx=cnx,
+                ark_naa=None,
+                user_cardinality=u'1',
+                user_annotation=u'nested')
+            cnx.commit()
+            self.assertTrue(unit.ark)
+            self.assertFalse(unit.ark_naa)
+            parent = cnx.entity_from_eid(self.unit_eid)
+            # Nested archive unit has a qualified ARK from its parent archive
+            # unit.
+            self.assertTrue(unit.ark.startswith(parent.ark), unit.ark)
+
 
 if __name__ == '__main__':
     unittest.main()



More information about the saem-devel mailing list