Commit b36c28bc authored by Sylvain Thénault's avatar Sylvain Thénault
Browse files

[profile gen] Support for custodial history in SEDA 1.0 / 0.2 export

with additional rules so that SEDA 0.2 is disabled when there are more than one
item in the history or if SEDAWhen is linked to an item, because in SEDA 0.2
custodial history is saved as texte, making those meaning less (well, even the
notion of 'history item' actually...).

Related to #16269136
parent 6a3ed40a9656
......@@ -127,6 +127,10 @@ class SEDAContent(generated.SEDAContent):
def keywords(self):
return self.reverse_seda_keyword
@property
def custodial_history_items(self):
return self.reverse_seda_custodial_history_item
@property
def type(self):
return self.reverse_seda_type_from[0] if self.reverse_seda_type_from else None
......@@ -325,3 +329,10 @@ class SEDAOriginatingAgency(generated.SEDAOriginatingAgency):
@property
def agency(self):
return self.seda_originating_agency_to[0] if self.seda_originating_agency_to else None
class SEDACustodialHistoryItem(generated.SEDACustodialHistoryItem):
@property
def when(self):
return self.reverse_seda_when[0] if self.reverse_seda_when else None
......@@ -38,7 +38,6 @@ RULES = {
'seda_seq_alt_archive_unit_archive_unit_ref_id_management',
'seda_access_rule',
])),
'rule_without_rule': Rule(
set(['SEDA 1.0', 'SEDA 0.2', 'simplified']),
_("Some management rule has no inner rule, one is required."),
......@@ -85,6 +84,21 @@ RULES = {
set([
'seda_ref_non_rule_id_from',
])),
'seda02_custodial_history_items': Rule(
set(['SEDA 0.2']),
_("Custodial history is text with SEDA 0.2, hence only one item element is considered."),
'seda_history_tab',
set([
'seda_custodial_history_item',
])),
'seda02_custodial_history_when': Rule(
set(['SEDA 0.2']),
_("Custodial history is text with SEDA 0.2, hence date information isn't considered."),
'seda_history_tab',
set([
'seda_when',
])),
}
......@@ -128,6 +142,12 @@ class ISEDACompatAnalyzer(EntityAdapter):
"""Yield (rule identifier, problematic entity) describing a problem that prevents the given
profile to be compatible with some format.
"""
for check_method in (self._check_management_rules,
self._check_custodial_history_rules):
for problem in check_method():
yield problem
def _check_management_rules(self):
profile = self.entity
# First level archive unit needs an access rule (SEDA 1)
if not profile.reverse_seda_access_rule:
......@@ -161,6 +181,25 @@ class ISEDACompatAnalyzer(EntityAdapter):
{'c': profile.eid}).entities():
yield 'rule_ref_non_rule_id', _parent(rule)
def _check_custodial_history_rules(self):
profile = self.entity
# Check for more than one custodial history items (SEDA 0.2)
for content in self._cw.execute(
'Any CONT GROUPBY CONT WHERE X seda_custodial_history_item CONT,'
'X container C, C eid %(c)s HAVING COUNT(X) > 1',
{'c': profile.eid}).entities():
parent = _parent(content) if profile.simplified_profile else content
yield 'seda02_custodial_history_items', parent
# Check for SEDAwhen usage (SEDA 0.2)
for content in self._cw.execute(
'DISTINCT Any CONT WHERE X seda_custodial_history_item CONT,'
'W seda_when X, X container C, C eid %(c)s',
{'c': profile.eid}).entities():
parent = _parent(content) if profile.simplified_profile else content
yield 'seda02_custodial_history_when', parent
# XXX more than one items ->
def _parent(entity):
"""Return the first encountered parent which is an ArchiveUnit"""
......
......@@ -1087,6 +1087,7 @@ class SEDA1XSDExport(SEDA2XSDExport):
self.xsd_language(cd_node, content)
self.xsd_content_dates(cd_node, content)
self.xsd_description(cd_node, content)
self.xsd_custodial_history(cd_node, content)
self.xsd_keywords(cd_node, content)
self.xsd_originating_agency(cd_node, content)
......@@ -1125,6 +1126,19 @@ class SEDA1XSDExport(SEDA2XSDExport):
for keyword in content.keywords:
self.xsd_keyword(parent, keyword)
def xsd_custodial_history(self, parent, content):
if content.custodial_history_items:
ch_node = self.element_schema(parent, 'CustodialHistory',
cardinality='0..1')
for item in content.custodial_history_items:
when_card = item.when.user_cardinality if item.when else None
self.element_schema(ch_node, 'CustodialHistoryItem', 'qdt:CustodialHistoryItemType',
cardinality=item.user_cardinality,
documentation=item.user_annotation,
xsd_attributes=[XAttr('when', 'udt:DateType',
cardinality=when_card),
XAttr('languageID', 'xsd:language')])
def xsd_originating_agency(self, parent, content):
if content.originating_agency:
self.xsd_agency(parent, 'OriginatingAgency', content.originating_agency)
......@@ -1286,12 +1300,21 @@ class SEDA02XSDExport(SEDA1XSDExport):
cd_node = self.element_schema(parent, 'ContentDescription',
documentation=content.user_annotation,
xsd_attributes=[XAttr('Id', 'xsd:ID')])
self.xsd_custodial_history(cd_node, content)
self.xsd_language(cd_node, content)
self.xsd_content_dates(cd_node, content)
self.xsd_description(cd_node, content)
self.xsd_originating_agency(cd_node, content)
self.xsd_keywords(cd_node, content)
def xsd_custodial_history(self, parent, content):
if content.custodial_history_items:
item = content.custodial_history_items[0]
self.element_schema(parent, 'CustodialHistory', 'udt:TextType',
cardinality=item.user_cardinality,
documentation=item.user_annotation,
xsd_attributes=[XAttr('languageID', 'xsd:language')])
# in SEDA 0.2, ArchiveObject tag name is 'Contains' (as for Archive)
archive_object_tag_name = 'Contains'
# in SEDA 0.2, AccessRestrictionRule tag name is 'AccessRestriction'
......
......@@ -52,6 +52,11 @@
<rng:data type="string"/>
</rng:element>
<rng:element name="ContentDescription">
<rng:optional>
<rng:element name="CustodialHistory">
<rng:data type="string"/>
</rng:element>
</rng:optional>
<rng:element name="Language">
<rng:attribute name="listVersionID">
<rng:value type="token">edition 2009</rng:value>
......
......@@ -105,6 +105,15 @@
<xsd:element name="ContentDescription">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" name="CustodialHistory">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="udt:TextType">
<xsd:attribute name="languageID" type="xsd:language" use="prohibited"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="Language">
<xsd:complexType>
<xsd:simpleContent>
......
......@@ -82,6 +82,20 @@
<rng:data type="string"/>
</rng:element>
</rng:optional>
<rng:optional>
<rng:element name="CustodialHistory">
<rng:optional>
<rng:element name="CustodialHistoryItem">
<rng:optional>
<rng:attribute name="when">
<rng:data type="string"/>
</rng:attribute>
</rng:optional>
<rng:data type="string"/>
</rng:element>
</rng:optional>
</rng:element>
</rng:optional>
<rng:zeroOrMore>
<rng:element name="Keyword">
<rng:element name="KeywordContent">
......
......@@ -125,6 +125,22 @@
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
<xsd:element minOccurs="0" name="CustodialHistory">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" name="CustodialHistoryItem">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="qdt:CustodialHistoryItemType">
<xsd:attribute name="when" type="udt:DateType" use="optional"/>
<xsd:attribute name="languageID" type="xsd:language" use="prohibited"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="Keyword">
<xsd:complexType>
<xsd:sequence>
......
......@@ -22,7 +22,7 @@ from testutils import create_archive_unit
class CompatAnalyzerTC(CubicWebTC):
def test_base(self):
def test_rules(self):
with self.admin_access.repo_cnx() as cnx:
create = cnx.create_entity
......@@ -78,6 +78,42 @@ class CompatAnalyzerTC(CubicWebTC):
self.assertDiagnostic(doctor, ['SEDA 2.0'],
'rule_ref_non_rule_id')
def test_custodial_hsitory(self):
with self.admin_access.repo_cnx() as cnx:
create = cnx.create_entity
transfer = create('SEDAArchiveTransfer', title=u'diagnosis testing')
unit, unit_alt, unit_alt_seq = create_archive_unit(transfer)
access_rule = create('SEDAAccessRule',
seda_access_rule=unit_alt_seq)
access_rule_seq = create('SEDASeqAccessRuleRule',
reverse_seda_seq_access_rule_rule=access_rule)
create('SEDAStartDate',
user_cardinality=u'1',
seda_start_date=access_rule_seq)
content = create('SEDAContent', seda_content=unit_alt_seq)
create('SEDATitle', seda_title=content)
history_item = create('SEDACustodialHistoryItem', seda_custodial_history_item=content)
doctor = transfer.cw_adapt_to('ISEDACompatAnalyzer')
cnx.commit()
self.assertDiagnostic(doctor, ['SEDA 2.0', 'SEDA 1.0', 'SEDA 0.2', 'simplified'])
history_item2 = create('SEDACustodialHistoryItem', seda_custodial_history_item=content)
content.cw_clear_all_caches()
cnx.commit()
self.assertDiagnostic(doctor, ['SEDA 2.0', 'SEDA 1.0', 'simplified'],
'seda02_custodial_history_items')
history_item2.cw_delete()
create('SEDAwhen', seda_when=history_item)
content.cw_clear_all_caches()
history_item.cw_clear_all_caches()
cnx.commit()
self.assertDiagnostic(doctor, ['SEDA 2.0', 'SEDA 1.0', 'simplified'],
'seda02_custodial_history_when')
def assertDiagnostic(self, doctor, expected_formats, *expected_rule_ids):
doctor.entity.cw_clear_all_caches()
rule_ids = set(rule_id for rule_id, entity in doctor.failing_rules())
......
......@@ -735,6 +735,9 @@ class OldSEDAExportMixin(object):
create('SEDAType', seda_type_from=content,
seda_type_to=concepts['CDO'])
create('SEDACustodialHistoryItem', seda_custodial_history_item=content,
reverse_seda_when=create('SEDAwhen'))
# Add sub archive unit
_, _, subunit_alt_seq = create_archive_unit(unit_alt_seq, id=u'au2',
user_cardinality=u'1..n')
......
......@@ -143,7 +143,7 @@ class ArchiveUnitTabbedPrimaryView(tabs.TabbedPrimaryView):
_('seda_management_tab'),
_('seda_au_content_tab'),
_('seda_au_indexation_tab'),
_('seda_au_history_tab'),
_('seda_history_tab'),
_('seda_au_archive_units_tab'),
_('seda_au_data_objects_refs_tab'),
]
......@@ -327,7 +327,7 @@ class SimplifiedArchiveUnitHistoryTab(tabs.TabsMixin, EntityView):
"""Display content's custodial history about an archive unit of a simplified profile.
"""
__regid__ = 'seda_au_history_tab'
__regid__ = 'seda_history_tab'
__select__ = ArchiveUnitContentTab.__select__ & simplified_profile()
def entity_call(self, entity):
......@@ -340,7 +340,7 @@ class SimplifiedArchiveUnitContentHistoryView(content.ContentHistoryTab):
__select__ = content.ContentHistoryTab.__select__ & simplified_profile()
tabid = 'seda_au_history_tab'
tabid = 'seda_history_tab'
def url_params(self, entity):
params = super(SimplifiedArchiveUnitContentHistoryView, self).url_params(entity)
......
......@@ -124,7 +124,7 @@ class ContentTabbedPrimaryView(tabs.TabbedPrimaryView):
_('seda_content_indexation_tab'),
_('seda_content_relation_tab'),
_('seda_content_event_tab'),
_('seda_content_history_tab'),
_('seda_history_tab'),
]
......@@ -286,7 +286,7 @@ class ContentEventTab(viewlib.SubObjectsTab):
class ContentHistoryTab(viewlib.SubObjectsTab):
"""Display custodial history information about an archive unit content."""
__regid__ = 'seda_content_history_tab'
__regid__ = 'seda_history_tab'
__select__ = is_instance('SEDAContent')
rtype_role_targets = [('seda_custodial_history_item', 'object', None)]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment