[PATCH 2 of 5 seda] [entities] Extract code to get closest management rule from profile generation

Sylvain Thenault sylvain.thenault at logilab.fr
Fri Mar 17 10:45:10 CET 2017


# HG changeset patch
# User Sylvain Thénault <sylvain.thenault at logilab.fr>
# Date 1489737517 -3600
#      Fri Mar 17 08:58:37 2017 +0100
# Node ID da6b373bb952a31b906eae3ec11f0b31ff041f9b
# Parent  44a96295dbb6bbe1e1e9e79a53088823a8560322
[entities] Extract code to get closest management rule from profile generation

and add it as a method of archive unit entities.

Related to extranet #14593198

diff --git a/cubicweb_seda/entities/custom.py b/cubicweb_seda/entities/custom.py
--- a/cubicweb_seda/entities/custom.py
+++ b/cubicweb_seda/entities/custom.py
@@ -12,20 +12,33 @@
 # details.
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with this program. If not, see <http://www.gnu.org/licenses/>.
 
+from ..xsd2yams import RULE_TYPES
 from . import generated
 
 
 def _extract_title(annotation):
     """Return the first line in the annotation to use as a title"""
     annotation = annotation.strip()
     assert annotation
     return annotation.splitlines()[0]
 
 
+def _climb_rule_holders(transfer_or_archive_unit):
+    """Starting from a transfer or archive unit entity, yield entity that may be linked to
+    management rule until the root (transfer) is reached.
+    """
+    while transfer_or_archive_unit is not None:
+        if transfer_or_archive_unit.cw_etype == 'SEDAArchiveTransfer':
+            yield transfer_or_archive_unit
+        else:
+            yield transfer_or_archive_unit.first_level_choice.content_sequence
+        transfer_or_archive_unit = transfer_or_archive_unit.cw_adapt_to('ITreeBase').parent()
+
+
 class SEDAArchiveTransfer(generated.SEDAArchiveTransfer):
 
     def dc_title(self):
         return self.title
 
@@ -75,10 +88,21 @@ class SEDAArchiveUnit(generated.SEDAArch
         """Return the choice element of an archive unit (SEDAAltArchiveUnitArchiveUnitRefId),
         holding either a reference or descriptive content
         """
         return self.related('seda_alt_archive_unit_archive_unit_ref_id', 'subject').one()
 
+    def inherited_rule(self, rule_type):
+        """Return the rule entity of the given type, defined on this unit or in its nearest parent
+        possible defining it, or None if no matching rule has been found.
+        """
+        assert rule_type in RULE_TYPES
+        rtype = 'reverse_seda_{}_rule'.format(rule_type)
+        for rule_holder in _climb_rule_holders(self):
+            if getattr(rule_holder, rtype):
+                return getattr(rule_holder, rtype)[0]
+        return None
+
 
 class SEDABinaryDataObject(generated.SEDABinaryDataObject):
 
     def dc_title(self):
         return _extract_title(self.user_annotation)
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
@@ -752,22 +752,10 @@ class SEDA2RelaxNGExport(RNGMixin, SEDA2
         for tag in tags:
             parent = self.element(tag, parent)
         return parent
 
 
-def climb_rule_holders(transfer_or_archive_unit):
-    """Starting from a transfer or archive unit entity, yield entity that may be linked to management
-    rule until the root (transfer) is reached.
-    """
-    while transfer_or_archive_unit is not None:
-        if transfer_or_archive_unit.cw_etype == 'SEDAArchiveTransfer':
-            yield transfer_or_archive_unit
-        else:
-            yield transfer_or_archive_unit.first_level_choice.content_sequence
-        transfer_or_archive_unit = transfer_or_archive_unit.cw_adapt_to('ITreeBase').parent()
-
-
 def _safe_cardinality(entity):
     """Return entity's cardinality if some entity is given, else None."""
     if entity is None:
         return None
     return entity.user_cardinality
@@ -922,15 +910,15 @@ class SEDA1XSDExport(SEDA2XSDExport):
                             xsd_attributes=[XAttr('languageID', 'xsd:language')])
         content_entity = self.archive_unit_content(archive_unit)
         self.xsd_transferring_agency_archive_identifier(archive_node, content_entity,
                                                         'TransferringAgencyArchiveIdentifier')
         self.xsd_content_description(archive_node, content_entity)
-        appraisal_rule_entity = self.archive_unit_appraisal_rule(archive_unit)
+        appraisal_rule_entity = archive_unit.inherited_rule('appraisal')
         if appraisal_rule_entity:
             self.xsd_appraisal_rule(archive_node, appraisal_rule_entity)
         # not optional in seda 1
-        access_rule_entity = self.archive_unit_access_rule(archive_unit)
+        access_rule_entity = archive_unit.inherited_rule('access')
         self.xsd_access_rule(archive_node, access_rule_entity)
         self.xsd_children(archive_node, archive_unit)
 
     archive_object_tag_name = 'ArchiveObject'
 
@@ -951,14 +939,14 @@ class SEDA1XSDExport(SEDA2XSDExport):
                 or content_entity.start_date
                 or content_entity.end_date
                 or content_entity.description
                 or content_entity.keywords):
             self.xsd_content_description(ao_node, content_entity)
-        appraisal_rule_entity = self.archive_unit_appraisal_rule(archive_unit)
+        appraisal_rule_entity = archive_unit.inherited_rule('appraisal')
         if appraisal_rule_entity:
             self.xsd_appraisal_rule(ao_node, appraisal_rule_entity)
-        access_rule_entity = self.archive_unit_access_rule(archive_unit)
+        access_rule_entity = archive_unit.inherited_rule('access')
         if access_rule_entity:
             self.xsd_access_rule(ao_node, access_rule_entity)
         self.xsd_children(ao_node, archive_unit)
 
         return ao_node
@@ -1258,26 +1246,14 @@ class SEDA1XSDExport(SEDA2XSDExport):
         #     # schemeID XXX move to saem
         #     attributes[0]['fixed'] = scheme.ark
         #     attributes[0]['use'] = 'required'
         return attributes
 
-    def archive_unit_access_rule(self, archive_unit):
-        for rule_holder in climb_rule_holders(archive_unit):
-            if rule_holder.reverse_seda_access_rule:
-                return rule_holder.reverse_seda_access_rule[0]
-        return None
-
     def archive_unit_name(self, archive_unit):
         seq = archive_unit.first_level_choice.content_sequence
         return seq.title
 
-    def archive_unit_appraisal_rule(self, archive_unit):
-        for rule_holder in climb_rule_holders(archive_unit):
-            if rule_holder.reverse_seda_appraisal_rule:
-                return rule_holder.reverse_seda_appraisal_rule[0]
-        return None
-
     def agency_name(self, agency):
         return agency.agency.dc_title() if agency and agency.agency else None
 
     def agency_id(self, agency):
         return text_type(agency.agency.eid) if agency and agency.agency else None
@@ -1344,15 +1320,15 @@ class SEDA02XSDExport(SEDA1XSDExport):
                             xsd_attributes=[XAttr('languageID', 'xsd:language')])
         self.xsd_transferring_agency_archive_identifier(archive_node, content_entity,
                                                         'TransferringAgencyArchiveIdentifier')
         self.xsd_content_description(archive_node, content_entity)
 
-        appraisal_rule_entity = self.archive_unit_appraisal_rule(archive_unit)
+        appraisal_rule_entity = archive_unit.inherited_rule('appraisal')
         if appraisal_rule_entity:
             self.xsd_appraisal_rule(archive_node, appraisal_rule_entity)
         # in SEDA 0.2, access restriction is not mandatory
-        access_rule_entity = self.archive_unit_access_rule(archive_unit)
+        access_rule_entity = archive_unit.inherited_rule('access')
         if access_rule_entity:
             self.xsd_access_rule(archive_node, access_rule_entity)
         self.xsd_children(archive_node, archive_unit)
         return archive_node
 


More information about the saem-devel mailing list