[profile gen] Move generic functions to the top of the file, dropping xsd_ prefix when it's not specific to XSD export
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 06 Jul 2016 18:17:26 +0200
changeset 1339 70bf9bb74735
parent 1338 162b0e22ccbd
child 1340 a6fd38685740
[profile gen] Move generic functions to the top of the file, dropping xsd_ prefix when it's not specific to XSD export
entities/profile_generation.py
--- a/entities/profile_generation.py	Wed Jul 06 18:12:11 2016 +0200
+++ b/entities/profile_generation.py	Wed Jul 06 18:17:26 2016 +0200
@@ -51,6 +51,79 @@
     return '{{{0}}}'.format(namespaces[prefix]) + name
 
 
+def content_types(content_type):
+    """Return an ordered tuple of content types from pyxst `textual_content_type` that may be None, a
+    set or a string value.
+    """
+    if content_type:
+        if isinstance(content_type, set):
+            content_types = sorted(content_type)
+        else:
+            content_types = (content_type,)
+    else:
+        content_types = ()
+    return content_types
+
+
+def serialize(value):
+    """Return typed `value` as an XSD string."""
+    if value is None:
+        return None
+    if hasattr(value, 'eid'):
+        if value.cw_etype == 'ConceptScheme':
+            return value.absolute_url()
+        if value.cw_etype == 'Concept':
+            try:
+                return value.labels['seda-2']
+            except KeyError:
+                return value.labels['en']
+        if hasattr(value, 'id'):
+            # value is something in the profile which has a id (e.g. archive unit, data object)
+            return value.id
+        return None  # intermediary entity
+    if isinstance(value, bool):
+        return 'true' if value else 'false'
+    assert isinstance(value, basestring), repr(value)
+    return unicode(value)
+
+
+def element_minmax_cardinality(occ, card_entity):
+    """Return (minimum, maximum) cardinality for the given pyxst Occurence. Cardinality may be
+    overriden by the data model's user_cardinality value.
+    """
+    cardinality = getattr(card_entity, 'user_cardinality', None)
+    if cardinality is None:
+        minimum = occ.minimum
+        maximum = occ.maximum
+    else:
+        assert cardinality in ('0..1', '0..n', '1', '1..n')
+        if cardinality[0] == '0':
+            minimum = 0
+        else:
+            minimum = 1
+        if cardinality[-1] == 'n':
+            maximum = graph_nodes.INFINITY
+        else:
+            maximum = 1
+    return minimum, maximum
+
+
+def attribute_minimum_cardinality(occ, card_entity):
+    """Return 0 or 1 for the given pyxst attribute's Occurence. Cardinality may be overriden by
+    the data model's user_cardinality value.
+    """
+    cardinality = getattr(card_entity, 'user_cardinality', None)
+    if cardinality is None:
+        minimum = occ.minimum
+    else:
+        # XXX assert cardinality in ('0..1', '1'), cardinality
+        if cardinality[0] == '0':
+            minimum = 0
+        else:
+            minimum = 1
+    return minimum
+
+
 class SEDA2ExportAdapter(EntityAdapter):
     """Abstract base class for export of SEDA profile"""
     __abstract__ = True
@@ -248,7 +321,7 @@
         content_type = self.xsd_content_type(xselement.textual_content_type)
         attrs['type'] = content_type
         target_element = self.element('xsd:attribute', parent, attrs)
-        value = xsd_serialize(target_value)
+        value = serialize(target_value)
         if value is not None:
             if xselement.local_name == 'id':
                 target_element.attrib[self.qname('seda:profid')] = value
@@ -312,7 +385,7 @@
                     attrs['name'] = attrname
                     attrs['type'] = self.xsd_content_type(occ.target.textual_content_type)
                     attr = self.element('xsd:attribute', attributes=attrs, parent=extension_element)
-        fixed_value = xsd_serialize(value)
+        fixed_value = serialize(value)
         if fixed_value is not None:
             attr = 'default' if hasattr(value, 'id') else 'fixed'
             target_element.attrib[attr] = fixed_value
@@ -465,7 +538,7 @@
             return self.element('rng:optional', profile_element)
 
     def _rng_attribute(self, xselement, parent_element, value=None):
-        xstypes = xsd_content_types(xselement.textual_content_type)
+        xstypes = content_types(xselement.textual_content_type)
         if len(xstypes) > 1:
             parent_element = self.element('rng:choice', parent_element)
         for xstype in xstypes:
@@ -492,7 +565,7 @@
 
     def element_xmlattribute(self, occ, profile_element, target_value, to_process, card_entity):
         parent_element = self._rng_attribute_parent(occ, card_entity, profile_element)
-        self._rng_attribute(occ.target, parent_element, xsd_serialize(target_value))
+        self._rng_attribute(occ.target, parent_element, serialize(target_value))
 
     def element_xmlelement(self, occ, profile_element, target_value, to_process, card_entity):  # noqa
         parent_element = self._rng_element_parent(occ, card_entity, profile_element)
@@ -507,13 +580,13 @@
             self.fill_element(xselement, profile_element, target_value, card_entity)
         else:
             target_element = self.element('rng:element', parent_element, attrs)
-            content_types = xsd_content_types(xselement.textual_content_type)
-            if content_types:
-                if len(content_types) == 1:
+            xstypes = content_types(xselement.textual_content_type)
+            if xstypes:
+                if len(xstypes) == 1:
                     parent_element = target_element
                 else:
                     parent_element = self.element('rng:choice', target_element)
-                for xstype in content_types:
+                for xstype in xstypes:
                     self.fill_element(xselement, parent_element, target_value, card_entity,
                                       xstype=xstype, copy_attributes=True)
             else:
@@ -551,7 +624,7 @@
                 if attrname in ('id', 'href') or attrname.startswith(('list', 'scheme')):
                     parent_element = self._rng_attribute_parent(occ, card_entity, profile_element)
                     self._rng_attribute(occ.target, parent_element)
-        fixed_value = xsd_serialize(value)
+        fixed_value = serialize(value)
         if fixed_value is not None:
             if hasattr(value, 'id'):
                 profile_element.attrib[self.qname('a:defaultValue')] = fixed_value
@@ -594,42 +667,6 @@
         return parent
 
 
-def xsd_content_types(content_type):
-    """Return XSD content types from pyxst `textual_content_type` that may be None, a set or a
-    string value.
-    """
-    if content_type:
-        if isinstance(content_type, set):
-            content_types = sorted(content_type)
-        else:
-            content_types = (content_type,)
-    else:
-        content_types = ()
-    return content_types
-
-
-def xsd_serialize(value):
-    """Return XSD value as a string depending on the type of the given `value`."""
-    if value is None:
-        return None
-    if hasattr(value, 'eid'):
-        if value.cw_etype == 'ConceptScheme':
-            return value.absolute_url()
-        if value.cw_etype == 'Concept':
-            try:
-                return value.labels['seda-2']
-            except KeyError:
-                return value.labels['en']
-        if hasattr(value, 'id'):
-            # value is something in the profile which has a id (e.g. archive unit, data object)
-            return value.id
-        return None  # intermediary entity
-    if isinstance(value, bool):
-        return 'true' if value else 'false'
-    assert isinstance(value, basestring), repr(value)
-    return unicode(value)
-
-
 def xsd_element_cardinality(occ, card_entity):
     """Return XSD element cardinality for the given pyxst Occurence. Cardinality may be overriden by
     the data model's user_cardinality value.
@@ -643,27 +680,6 @@
     return attribs
 
 
-def element_minmax_cardinality(occ, card_entity):
-    """Return (minimum, maximum) cardinality for the given pyxst Occurence. Cardinality may be
-    overriden by the data model's user_cardinality value.
-    """
-    cardinality = getattr(card_entity, 'user_cardinality', None)
-    if cardinality is None:
-        minimum = occ.minimum
-        maximum = occ.maximum
-    else:
-        assert cardinality in ('0..1', '0..n', '1', '1..n')
-        if cardinality[0] == '0':
-            minimum = 0
-        else:
-            minimum = 1
-        if cardinality[-1] == 'n':
-            maximum = graph_nodes.INFINITY
-        else:
-            maximum = 1
-    return minimum, maximum
-
-
 def xsd_attribute_cardinality(occ, card_entity):
     """Return XSD attribute cardinality for the given pyxst Occurence. Cardinality may be overriden by
     the data model's user_cardinality value.
@@ -674,22 +690,6 @@
         return {'use': 'optional'}
 
 
-def attribute_minimum_cardinality(occ, card_entity):
-    """Return 0 or 1 for the given pyxst attribute's Occurence. Cardinality may be overriden by
-    the data model's user_cardinality value.
-    """
-    cardinality = getattr(card_entity, 'user_cardinality', None)
-    if cardinality is None:
-        minimum = occ.minimum
-    else:
-        # XXX assert cardinality in ('0..1', '1'), cardinality
-        if cardinality[0] == '0':
-            minimum = 0
-        else:
-            minimum = 1
-    return minimum
-
-
 def xsd_cleanup_etree(element):
     """Cleanup given XSD element tree.