author Sylvain Thénault <>
Tue, 05 Dec 2017 13:47:54 +0100
changeset 2896 ce08a5c6e100
parent 2616 45cae2f412d1
child 2898 8bd8b3533dec
permissions -rw-r--r--
[schema] Add a new 'ordering' attribute on some etype + hook to set it autonomatically in order to being able to order children elements of an entity.

# copyright 2016-2017 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact --
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 of the License, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <>.
"""cubicweb-seda application package

Data Exchange Standard for Archival

from cubicweb_compound import skip_rtypes_set, structure_def, CompositeGraph

# control of compound graph by adding etype / rtype to the corresponding set below
GRAPH_SKIP_RTYPES = set(['container', 'clone_of'])

def seda_profile_container_def(schema):
    """Define container for SEDAArchiveTransfer, as a list of (etype, parent_rdefs)."""
    return structure_def(schema, 'SEDAArchiveTransfer',
                         skipetypes=GRAPH_SKIP_ETYPES, skiprtypes=GRAPH_SKIP_RTYPES).items()

def _iter_external_rdefs(eschema, skip_rtypes):
    """Return an iterator on (rdef, role) of external relations from entity schema (i.e.
    non-composite relations).
    for rschema, targets, role in eschema.relation_definitions():
        if rschema in skip_rtypes:
        for target_etype in targets:
            rdef = eschema.rdef(rschema, role, target_etype)
            if rdef.composite:
            yield rdef, role

def iter_all_rdefs(schema, container_etype):
    """Return an iterator on (rdef, role) of all relations of the compound graph starting from the
    given entity type, both internal (composite) and external (non-composite).
    graph = CompositeGraph(schema, skipetypes=GRAPH_SKIP_ETYPES, skiprtypes=GRAPH_SKIP_RTYPES)
    skip_external_rtypes = skip_rtypes_set(GRAPH_SKIP_RTYPES)
    stack = [container_etype]
    visited = set(stack)
    while stack:
        etype = stack.pop()
        for (rtype, role), targets in graph.child_relations(etype):
            rschema = schema.rschema(rtype)
            for target in targets:
                if role == 'subject':
                    rdef = rschema.rdefs[(etype, target)]
                    rdef = rschema.rdefs[(target, etype)]
                yield rdef, role

                if target not in visited:
        for rdef, role in _iter_external_rdefs(schema[etype], skip_external_rtypes):
            yield rdef, role

# list of entity types that may be used multiple times at a same level, and
# through which relation
    ('SEDAArchiveUnit', 'seda_archive_unit'),
    ('SEDABinaryDataObject', 'seda_binary_data_object'),
    ('SEDAPhysicalDataObject', 'seda_physical_data_object'),
    ('SEDADataObjectReference', 'seda_data_object_reference'),
    ('SEDARelatedTransferReference', 'seda_related_transfer_reference'),
    ('SEDAWriter', 'seda_writer_from'),
    ('SEDAAddressee', 'seda_addressee_from'),
    ('SEDARecipient', 'seda_recipient_from'),
    ('SEDASpatial', 'seda_spatial'),
    ('SEDATemporal', 'seda_temporal '),
    ('SEDAJuridictional', 'seda_juridictional'),
    ('SEDAKeyword', 'seda_keyword'),
    ('SEDATag', 'seda_tag'),
    ('SEDAIsVersionOf', 'seda_is_version_of'),
    ('SEDAReplaces', 'seda_replaces'),
    ('SEDARequires', 'seda_requires'),
    ('SEDAIsPartOf', 'seda_is_part_of'),
    ('SEDAReferences', 'seda_references'),
    ('SEDAEvent', 'seda_event'),
    ('SEDACustodialHistoryItem', 'seda_custodial_history_item'),
    ('SEDARelationship', 'seda_relationship'),