[PATCH] Make generation of xml:id attribute configurable through an adapter

Philippe Pepiot philippe.pepiot at logilab.fr
Tue Jun 26 09:52:59 CEST 2018


On 25/06/2018, Denis Laxalde wrote:
> # HG changeset patch
> # User Denis Laxalde <denis.laxalde at logilab.fr>
> # Date 1529415726 -7200
> #      Tue Jun 19 15:42:06 2018 +0200
> # Node ID a89f3018c9e3f92d4e9f58515a5a7c43753aa31f
> # Parent  97b06a36d10468e7f69dddfae864961c138dc53d
> # EXP-Topic CONSEJIRA-510
> Make generation of xml:id attribute configurable through an adapter
> 
> The idea is to have the generation of xml:id attribute configurable
> based on entity context. So we create an entity adapter IXmlId that
> default to the current implementation. This will be extended in
> cubicweb-saem_ref where we'd want to use the ARK identifier to produce
> this xml:id attribute.
> 
> diff --git a/cubicweb_seda/entities/__init__.py b/cubicweb_seda/entities/__init__.py
> --- a/cubicweb_seda/entities/__init__.py
> +++ b/cubicweb_seda/entities/__init__.py
> @@ -20,6 +20,7 @@ import json
>  from logilab.common.registry import objectify_predicate
>  
>  from cubicweb.predicates import is_instance
> +from cubicweb.view import EntityAdapter
>  from cubicweb_compound.entities import IContainer, IContained, IClonableAdapter
>  
>  from .. import seda_profile_container_def
> @@ -202,6 +203,17 @@ class SEDAArchiveUnitIClonableAdapter(SE
>                  clones[data_object].cw_set(**{rtype: transfer})
>  
>  
> +class XmlIdAdapter(EntityAdapter):
> +    """Adapter for entity to be inserted in XML document and for which an
> +    xml:id attribute needs to be generated.
> +    """
> +    __regid__ = 'IXmlId'
> +    __select__ = is_instance('Any')
> +
> +    def id(self):
> +        return u'id{}'.format(self.entity.eid)
> +
> +
>  def registration_callback(vreg):
>      vreg.register_all(globals().values(), __name__)
>      vreg.register(IContainer.build_class('SEDAArchiveTransfer'))
> 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
> @@ -100,9 +100,9 @@ def _concept_value(concept, language):
>      return concept.label()
>  
>  
> -def eid2xmlid(eid):
> +def eid2xmlid(entity):
>      """Return a value usable as ID/IDREF for the given eid."""
> -    return 'id' + text_type(eid)
> +    return entity.cw_adapt_to('IXmlId').id()
>  
>  
>  def serialize(value, build_url):
> @@ -115,7 +115,7 @@ def serialize(value, build_url):
>          if value.cw_etype == 'Concept':
>              return _concept_value(value, 'seda-2')
>          if _internal_reference(value):
> -            return eid2xmlid(value.eid)
> +            return value.cw_adapt_to('IXmlId').id()

I think this should be eid2xmlid(value) for consistency ?

>          return None  # intermediary entity
>      if isinstance(value, bool):
>          return 'true' if value else 'false'
> @@ -785,7 +785,7 @@ class SEDA1XSDExport(SEDA2ExportAdapter)
>              cardinality=archive_unit.user_cardinality,
>              documentation=archive_unit.user_annotation,
>              xsd_attributes=[XAttr('Id', 'xsd:ID')],
> -            extra_attributes={'xml:id': eid2xmlid(archive_unit.eid)},
> +            extra_attributes={'xml:id': eid2xmlid(archive_unit)},
>          )
>          transfer = archive_unit.cw_adapt_to('ITreeBase').parent()
>          self.xsd_archival_agreement(archive_node, transfer)
> @@ -814,7 +814,7 @@ class SEDA1XSDExport(SEDA2ExportAdapter)
>              cardinality=archive_unit.user_cardinality,
>              documentation=archive_unit.user_annotation,
>              xsd_attributes=[XAttr('Id', 'xsd:ID')],
> -            extra_attributes={'xml:id': eid2xmlid(archive_unit.eid)},
> +            extra_attributes={'xml:id': eid2xmlid(archive_unit)},
>          )
>          content_entity = self.archive_unit_content(archive_unit)
>          self.element_schema(ao_node, 'Name', 'udt:TextType',
> @@ -841,7 +841,7 @@ class SEDA1XSDExport(SEDA2ExportAdapter)
>              cardinality=data_object.user_cardinality,
>              documentation=data_object.user_annotation,
>              xsd_attributes=[XAttr('Id', 'xsd:ID')],
> -            extra_attributes={'xml:id': eid2xmlid(data_object.eid)},
> +            extra_attributes={'xml:id': eid2xmlid(data_object)},
>          )
>  
>          self.xsd_system_id(document_node, data_object)
> @@ -1088,7 +1088,7 @@ class SEDA1XSDExport(SEDA2ExportAdapter)
>                      xsd_attributes=[XAttr('when', 'udt:DateType',
>                                            cardinality=when_card),
>                                      XAttr('languageID', 'xsd:language')],
> -                    extra_attributes={'xml:id': eid2xmlid(item.eid)},
> +                    extra_attributes={'xml:id': eid2xmlid(item)},
>                  )
>  
>      def xsd_originating_agency(self, parent, content):
> @@ -1117,7 +1117,7 @@ class SEDA1XSDExport(SEDA2ExportAdapter)
>              cardinality=keyword.user_cardinality,
>              documentation=keyword.user_annotation,
>              xsd_attributes=[XAttr('Id', 'xsd:ID')],
> -            extra_attributes={'xml:id': eid2xmlid(keyword.eid)},
> +            extra_attributes={'xml:id': eid2xmlid(keyword)},
>          )
>          content = keyword.keyword_content
>          url = None
> @@ -1218,7 +1218,7 @@ class SEDA02XSDExport(SEDA1XSDExport):
>              cardinality=archive_unit.user_cardinality,
>              documentation=archive_unit.user_annotation,
>              xsd_attributes=[XAttr('Id', 'xsd:ID')],
> -            extra_attributes={'xml:id': eid2xmlid(archive_unit.eid)},
> +            extra_attributes={'xml:id': eid2xmlid(archive_unit)},
>          )
>          transfer = archive_unit.cw_adapt_to('ITreeBase').parent()
>          self.xsd_archival_agreement(archive_node, transfer)
> @@ -1259,7 +1259,7 @@ class SEDA02XSDExport(SEDA1XSDExport):
>              parent, 'Document',
>              cardinality=data_object.user_cardinality,
>              documentation=data_object.user_annotation,
> -            extra_attributes={'xml:id': eid2xmlid(data_object.eid)},
> +            extra_attributes={'xml:id': eid2xmlid(data_object)},
>              xsd_attributes=[XAttr('Id', 'xsd:ID')],
>          )
>          self.xsd_attachment(document_node, data_object)
> @@ -1294,7 +1294,7 @@ class SEDA02XSDExport(SEDA1XSDExport):
>                  cardinality=item.user_cardinality,
>                  documentation=item.user_annotation,
>                  xsd_attributes=[XAttr('languageID', 'xsd:language')],
> -                extra_attributes={'xml:id': eid2xmlid(item.eid)},
> +                extra_attributes={'xml:id': eid2xmlid(item)},
>              )
>  
>      def xsd_integrity(self, parent, data_object):
> @@ -1306,7 +1306,7 @@ class SEDA02XSDExport(SEDA1XSDExport):
>                                                    fixed_value=_concept_value(
>                                                        algorithm, self.concepts_language))])
>          self.element_schema(integrity, 'UnitIdentifier', 'qdt:ArchivesIDType',
> -                            default_value=eid2xmlid(data_object.eid))
> +                            default_value=eid2xmlid(data_object))
>  
>      system_id_tag_name = 'Identification'
>      # in SEDA 0.2, ArchiveObject tag name is 'Contains' (as for Archive)
> @@ -1411,7 +1411,7 @@ def _path_target_values(entity, path):
>  def _simple_path_target_values(entity, rtype, role, target_etype):
>      if target_etype in BASE_TYPES:
>          if rtype == 'id':
> -            return [(None, eid2xmlid(entity.eid))]
> +            return [(None, eid2xmlid(entity))]
>          return [(None, getattr(entity, rtype, None))]
>      targets = entity.related(rtype, role, entities=True)
>      rschema = entity._cw.vreg.schema.rschema
> 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
> @@ -673,6 +673,7 @@ class SEDAExportFuncTCMixIn(object):
>              cnx.commit()
>          self.transfer_eid = transfer.eid
>          self.bdo_eid = bdo.eid
> +        self.bdo_xmlid = bdo.cw_adapt_to('IXmlId').id()
>          self.au_eid = unit.eid
>  
>      def test_profile1(self):
> @@ -698,8 +699,7 @@ class SEDARNGExportFuncTC(SEDAExportFunc
>          for attrdef in self.xpath(root, '//xs:attribute[@xml:id]'):
>              self.assertEqual(attrdef[0]['type'], 'ID')
>          # ensure they are properly referenced using 'default' attribute
> -        xmlid = pg.eid2xmlid(self.bdo_eid)
> -        references = self.xpath(root, '//rng:element[@a:defaultValue="{}"]'.format(xmlid))
> +        references = self.xpath(root, '//rng:element[@a:defaultValue="{}"]'.format(self.bdo_xmlid))
>          self.assertEqual(len(references), 1)
>          self.assertEqual(references[0].attrib['name'], 'DataObjectReferenceId')
>          for reference_id in self.xpath(root, '//rng:element[@name="DataObjectReferenceId"]'):
> 



More information about the saem-devel mailing list