Commit 00f7916d authored by Katia Saurfelt's avatar Katia Saurfelt
Browse files

feat: add DataObjectGroup on all [Binary|Physical]DataObject descendents of DataObjectPackage.

Use <rng:zeroOrMore/rng:choice> grouping all [Binary|Physical]DataObjects to avoid the problem
if [Binary|Physical]DataObject order (closes #35)

--HG--
branch : seda21
parent 3f22e0b6b094
Pipeline #95377 failed with stages
in 1 minute and 11 seconds
......@@ -447,7 +447,7 @@ class SEDA2ExportAdapter(EntityAdapter):
class SEDA2RelaxNGExport(RNGMixin, SEDA2ExportAdapter):
"""Abstract Adapter to build a Relax NG representation of a SEDA profile, using SEDA 2.1
specification."""
specification."""
__regid__ = "SEDA-2.1.rng"
__abstract__ = True
......@@ -503,7 +503,7 @@ class SEDA2RelaxNGExport(RNGMixin, SEDA2ExportAdapter):
def postprocess_dataobjectsreference(self, root, namespaces):
"""transform DataObjectReferenceId into DataObjectGroupReferenceId
if wrap_dataobjects
if wrap_dataobjects
"""
return
......@@ -752,23 +752,23 @@ class SEDA22RelaxNGExport(SEDA2RelaxNGExport):
'rng:optional/rng:element[@name="DataObjectPackage"]',
namespaces=namespaces,
)
if dops:
assert len(dops) == 1
dop = dops[0]
# insert DataObjectGroup to all descendent
# [Binary|Physical]DataObjects of DataObjectPackage will recieve a
nodes = dop.xpath(
'rng:element[@name="BinaryDataObject" or @name="PhysicalDataObject"]',
namespaces=namespaces,
)
opt_nodes = dop.xpath(
'rng:optional[rng:element[@name="BinaryDataObject" or @name="PhysicalDataObject"]]',
namespaces=namespaces,
)
if nodes or opt_nodes:
# insert after definition of dop's id attribute
for node in chain(nodes, opt_nodes):
zeroormore = self.element("rng:zeroOrMore")
choice = self.element("rng:choice", zeroormore)
dop[0].addnext(zeroormore)
'./descendant::rng:element[@name="BinaryDataObject" or @name="PhysicalDataObject"]',
namespaces=namespaces)
if nodes:
zeroormore = self.element("rng:zeroOrMore")
choice = self.element("rng:choice", zeroormore)
dop[0].addnext(zeroormore)
for node in nodes:
parent = node.getparent()
if parent != dop:
parent.getparent().remove(parent)
# insert DataObjectGroup with id from [Physical|Binary]DataObject if found
group = self.element(
"rng:element", choice, attributes={"name": "DataObjectGroup"}
......@@ -786,7 +786,7 @@ class SEDA22RelaxNGExport(SEDA2RelaxNGExport):
def postprocess_dataobjectsreference(self, root, namespaces):
"""transform DataObjectReferenceId into DataObjectGroupReferenceId
if wrap_dataobjects
if wrap_dataobjects
"""
# DataObjectReferenceId into DataObjectGroupReferenceId
reference_nodes = root.xpath(
......@@ -796,9 +796,11 @@ class SEDA22RelaxNGExport(SEDA2RelaxNGExport):
)
for reference_node in reference_nodes:
reference_node.attrib["name"] = "DataObjectGroupReferenceId"
node_id = reference_node.xpath('@a:defaultValue[1]', namespaces=namespaces)
node_id = reference_node.xpath("@a:defaultValue[1]", namespaces=namespaces)
# change defaultValue from BinaryDataObject xml:id to DataObjectGroup xml:id
reference_node.attrib[f"{{{namespaces['a']}}}defaultValue"] = f"g{node_id[0]}"
reference_node.attrib[
f"{{{namespaces['a']}}}defaultValue"
] = f"g{node_id[0]}"
class SEDA21RelaxNGExport(SEDA2RelaxNGExport):
......@@ -824,19 +826,17 @@ class SEDA21RelaxNGExport(SEDA2RelaxNGExport):
assert len(dops) == 1
dop = dops[0]
nodes = dop.xpath(
'rng:element[@name="BinaryDataObject" or @name="PhysicalDataObject"]',
namespaces=namespaces,
)
opt_nodes = dop.xpath(
'rng:optional[rng:element[@name="BinaryDataObject" or @name="PhysicalDataObject"]]',
namespaces=namespaces,
)
if nodes or opt_nodes:
group = self.element("rng:group")
# insert after definition of dop's id attribute
dop[0].addnext(group)
for node in chain(nodes, opt_nodes):
group.append(node)
'./descendant::rng:element[@name="BinaryDataObject" or @name="PhysicalDataObject"]',
namespaces=namespaces)
if nodes:
zeroormore = self.element("rng:zeroOrMore")
choice = self.element("rng:choice", zeroormore)
dop[0].addnext(zeroormore)
for node in nodes:
parent = node.getparent()
if parent != dop:
parent.getparent().remove(parent)
choice.append(node)
class XAttr(
......
......@@ -510,24 +510,33 @@ class SEDA2RNGExportTC(RelaxNGTestMixin, CubicWebTC):
dop = self.get_element(profile, "DataObjectPackage")
self.assertEqual(len(self.xpath(dop, "./rng:group/*")), 3)
def test_object_data_object_group(self):
def test_object_data_object_with_group(self):
with self.admin_access.cnx() as cnx:
transfer = cnx.create_entity(
"SEDAArchiveTransfer", title=u"test profile", wrap_dataobjects=True
)
bdo = cnx.create_entity(
cnx.create_entity(
"SEDABinaryDataObject",
user_cardinality="1",
user_annotation=u"I am number one",
seda_binary_data_object=transfer,
)
cnx.create_entity(
"SEDABinaryDataObject",
"SEDAPhysicalDataObject",
user_cardinality="1..n",
user_annotation=u"I am number two",
seda_physical_data_object=transfer,
)
cnx.create_entity(
"SEDABinaryDataObject",
user_cardinality="0..1",
user_annotation=u"I am number one",
seda_binary_data_object=transfer,
)
cnx.create_entity(
"SEDAPhysicalDataObject",
user_annotation=u"I am number three",
user_cardinality="0..n",
user_annotation=u"I am number two",
seda_physical_data_object=transfer,
)
......@@ -551,19 +560,46 @@ class SEDA2RNGExportTC(RelaxNGTestMixin, CubicWebTC):
'/rng:element[@name="PhysicalDataObject"]',
)
),
1,
2,
)
# setting some cardinality to 1 will remove rng:optional parent of the DataObjectPackage
# and BinaryDataObject nodes
bdo.cw_set(user_cardinality=u"1")
def test_object_data_object_without_group(self):
with self.admin_access.cnx() as cnx:
transfer = cnx.create_entity(
"SEDAArchiveTransfer", title=u"test profile", wrap_dataobjects=False
)
cnx.create_entity(
"SEDABinaryDataObject",
user_cardinality="1",
user_annotation=u"I am number one",
seda_binary_data_object=transfer,
)
cnx.create_entity(
"SEDAPhysicalDataObject",
user_cardinality="1..n",
user_annotation=u"I am number two",
seda_physical_data_object=transfer,
)
cnx.create_entity(
"SEDABinaryDataObject",
user_cardinality="0..1",
user_annotation=u"I am number one",
seda_binary_data_object=transfer,
)
cnx.create_entity(
"SEDAPhysicalDataObject",
user_cardinality="0..n",
user_annotation=u"I am number two",
seda_physical_data_object=transfer,
)
profile = self.profile_etree(transfer)
dop = self.get_element(profile, "DataObjectPackage")
self.assertEqual(
len(
self.xpath(
dop,
'./rng:zeroOrMore/rng:choice/rng:element[@name="DataObjectGroup"]'
'/rng:element[@name="BinaryDataObject"]',
'./rng:zeroOrMore/rng:choice/rng:element[@name="BinaryDataObject"]',
)
),
2,
......@@ -572,11 +608,10 @@ class SEDA2RNGExportTC(RelaxNGTestMixin, CubicWebTC):
len(
self.xpath(
dop,
'./rng:zeroOrMore/rng:choice/rng:element[@name="DataObjectGroup"]'
'/rng:element[@name="PhysicalDataObject"]',
'./rng:zeroOrMore/rng:choice/rng:element[@name="PhysicalDataObject"]',
)
),
1,
2,
)
def test_transfer_annotation(self):
......
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