Skip to content

Commit

Permalink
Follow keep instruction for back-matter resources (usnistgov#1378)
Browse files Browse the repository at this point in the history
If a back-matter resource has a keep instruction, the spec
requirement "req-backmatter-keep" says not to replace the
resource unless a later one also has a keep instruction.
  • Loading branch information
galtm authored and aj-stein-nist committed Jan 10, 2023
1 parent bd33bf7 commit 930fdac
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 3 deletions.
14 changes: 11 additions & 3 deletions src/utils/util/resolver-pipeline/oscal-profile-resolve-merge.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,18 @@
<back-matter>
<!-- Using combination logic on back matter elements. -->
<xsl:for-each-group select="back-matter/* | selection/back-matter/*" group-by="(@opr:id,@uuid,generate-id())[1]">
<xsl:variable name="last" as="element(resource)" select="current-group()[last()]"/>
<!-- The final phase needs the ability to keep unreferenced
back matter items based on keep instructions, so the merge
phase must preserve these items. -->
<xsl:variable name="keepers" as="element(resource)*"
select="current-group()[child::prop[@name='keep' and @value='always']]"/>
<xsl:call-template name="combine-elements">
<!-- Take last one in group because of spec
requirement id="req-backmatter-dupe". -->
<xsl:with-param name="who" select="current-group()[last()]" as="element(resource)"/>
<!-- Take last one in group because of spec requirement
id="req-backmatter-dupe". -->
<!-- Take last item with keep instruction, because
of spec requirement id="req-backmatter-keep". -->
<xsl:with-param name="who" select="$keepers[last()] | $last" as="element(resource)+"/>
</xsl:call-template>
</xsl:for-each-group>
</back-matter>
Expand Down
121 changes: 121 additions & 0 deletions src/utils/util/resolver-pipeline/testing/3_merged/merge.xspec
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,127 @@
</back-matter>
</x:expect>
</x:scenario>
<x:scenario label="Testing keep instructions: Three resources with same uuid, where">
<x:scenario label="1st has keep instruction and others do not">
<x:context>
<catalog>
<selection uuid="xyz-tiny_catalog">
<control id="x1"><title>Control X1</title></control>
<back-matter>
<resource uuid="0050231f-4fd0-43d6-8fa0-431367cd83e2">
<title>Ref BBB, first</title>
<prop name="keep" value="always"/>
</resource>
</back-matter>
</selection>
<selection uuid="xyz-tiny_catalog2">
<control id="x2"><title>Control X2</title></control>
<back-matter>
<resource uuid="0050231f-4fd0-43d6-8fa0-431367cd83e2">
<title>Ref BBB, second</title>
</resource>
</back-matter>
</selection>
<back-matter>
<resource uuid="0050231f-4fd0-43d6-8fa0-431367cd83e2">
<title>Ref BBB, third</title>
</resource>
</back-matter>
</catalog>
</x:context>
<x:call template="combine-back-matter"/>
<x:expect label="back-matter with 1st and 3rd items. 2nd item was superseded by 3rd item.">
<back-matter>
<resource uuid="0050231f-4fd0-43d6-8fa0-431367cd83e2">
<title>Ref BBB, first</title>
<prop name="keep" value="always"/>
</resource>
<resource uuid="0050231f-4fd0-43d6-8fa0-431367cd83e2">
<title>Ref BBB, third</title>
</resource>
</back-matter>
</x:expect>
</x:scenario>
<x:scenario label="1st and 3rd have keep instruction and 2nd does not">
<x:context>
<catalog>
<selection uuid="xyz-tiny_catalog">
<control id="x1"><title>Control X1</title></control>
<back-matter>
<resource uuid="0050231f-4fd0-43d6-8fa0-431367cd83e2">
<title>Ref BBB, first</title>
<prop name="keep" value="always"/>
</resource>
</back-matter>
</selection>
<selection uuid="xyz-tiny_catalog2">
<control id="x2"><title>Control X2</title></control>
<back-matter>
<resource uuid="0050231f-4fd0-43d6-8fa0-431367cd83e2">
<title>Ref BBB, second</title>
</resource>
</back-matter>
</selection>
<back-matter>
<resource uuid="0050231f-4fd0-43d6-8fa0-431367cd83e2">
<title>Ref BBB, third</title>
<prop name="keep" value="always"/>
</resource>
</back-matter>
</catalog>
</x:context>
<x:call template="combine-back-matter"/>
<x:expect label="back-matter with last item only.">
<back-matter>
<resource uuid="0050231f-4fd0-43d6-8fa0-431367cd83e2">
<title>Ref BBB, third</title>
<prop name="keep" value="always"/>
</resource>
</back-matter>
</x:expect>
</x:scenario>
<x:scenario label="1st and 2nd have keep instruction and 3rd does not">
<x:context>
<catalog>
<selection uuid="xyz-tiny_catalog">
<control id="x1"><title>Control X1</title></control>
<back-matter>
<resource uuid="0050231f-4fd0-43d6-8fa0-431367cd83e2">
<title>Ref BBB, first</title>
<prop name="keep" value="always"/>
</resource>
</back-matter>
</selection>
<selection uuid="xyz-tiny_catalog2">
<control id="x2"><title>Control X2</title></control>
<back-matter>
<resource uuid="0050231f-4fd0-43d6-8fa0-431367cd83e2">
<title>Ref BBB, second</title>
<prop name="keep" value="always"/>
</resource>
</back-matter>
</selection>
<back-matter>
<resource uuid="0050231f-4fd0-43d6-8fa0-431367cd83e2">
<title>Ref BBB, third</title>
</resource>
</back-matter>
</catalog>
</x:context>
<x:call template="combine-back-matter"/>
<x:expect label="back-matter with 2nd and 3rd items. 1st item was superseded by 2nd item.">
<back-matter>
<resource uuid="0050231f-4fd0-43d6-8fa0-431367cd83e2">
<title>Ref BBB, second</title>
<prop name="keep" value="always"/>
</resource>
<resource uuid="0050231f-4fd0-43d6-8fa0-431367cd83e2">
<title>Ref BBB, third</title>
</resource>
</back-matter>
</x:expect>
</x:scenario>
</x:scenario>
<x:scenario label="No back matter in input context">
<x:context>
<catalog>
Expand Down

0 comments on commit 930fdac

Please sign in to comment.