Skip to content

Commit

Permalink
Pipeline configuration adjustment for converter-generator runtimes (#144
Browse files Browse the repository at this point in the history
)

* Now displaying constraints in documentation at point of definition; WIP on constraint path matching logic
* Updating convertor generator and other pipelines to latest XSLT sequence.
  • Loading branch information
wendellpiez authored May 27, 2021
1 parent 0dd6a34 commit f48177c
Show file tree
Hide file tree
Showing 10 changed files with 279 additions and 392 deletions.
135 changes: 93 additions & 42 deletions toolchains/xslt-M4/compose/make-model-map.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
exclude-result-prefixes="#all"
version="3.0">

<xsl:output indent="true"/>
<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="/METASCHEMA">
Expand All @@ -19,38 +20,47 @@
</map>
</xsl:template>

<xsl:key name="global-assemblies" match="METASCHEMA/define-assembly" use="@name"/>
<xsl:key name="global-fields" match="METASCHEMA/define-field" use="@name"/>
<xsl:key name="global-flags" match="METASCHEMA/define-flag" use="@name"/>
<xsl:key name="global-assemblies" match="METASCHEMA/define-assembly" use="@_key-name"/>
<xsl:key name="global-fields" match="METASCHEMA/define-field" use="@_key-name"/>
<xsl:key name="global-flags" match="METASCHEMA/define-flag" use="@_key-name"/>

<xsl:template match="define-assembly | define-field" mode="build">
<xsl:param name="minOccurs" select="(@min-occurs,'0')[1]"/>
<xsl:param name="maxOccurs" select="(@max-occurs,'1')[1]"/>
<xsl:param name="using-name" select="()"/>
<xsl:param name="group-name" select="group-as/@name"/>
<xsl:param name="group-json" select="group-as/@in-json"/>
<xsl:param name="group-xml" select="group-as/@in-xml"/>
<xsl:param name="in-xml" select="()"/>
<xsl:param name="visited" select="()" tunnel="true"/>
<xsl:param name="with-remarks" select="()"/>
<xsl:variable name="type" select="replace(local-name(),'^define\-','')"/>
<xsl:param name="reference" select="."/>

<!-- properties can be given on the reference or on the definition itself, and a reference
can overload its definition -->
<xsl:variable name="minOccurs" select="($reference/@min-occurs,@min-occurs,'0')[1]"/>
<xsl:variable name="maxOccurs" select="($reference/@max-occurs,@max-occurs,'1')[1]"/>
<xsl:variable name="type" select="$reference => local-name() => replace('^define-','')"/>
<xsl:variable name="using-name" select="$reference/@_using-name"/>
<xsl:variable name="group-name" select="($reference/group-as/@name,group-as/@name)[1]"/>
<xsl:variable name="group-json" select="($reference/group-as/@in-json,group-as/@in-json)[1]"/>
<xsl:variable name="group-xml" select="($reference/group-as/@in-xml,group-as/@in-xml)[1]"/>
<xsl:variable name="in-xml" select="$reference/@in-xml"/>
<xsl:variable name="with-remarks" select="$reference/remarks"/>


<xsl:element name="{ $type }" namespace="http://csrc.nist.gov/ns/oscal/metaschema/1.0">
<xsl:for-each select="self::define-assembly[empty(model)]">
<xsl:attribute name="as-type">empty</xsl:attribute>
</xsl:for-each>
<xsl:attribute name="scope" select="if (exists(parent::METASCHEMA)) then 'global' else 'local'"/>
<xsl:if test="@name = $visited">
<xsl:if test="@_key-name = $visited">
<xsl:attribute name="recursive">true</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="@*" mode="build"/>
<xsl:if test="not(@in-xml='UNWRAPPED')">

<xsl:apply-templates select="@*" mode="build"/>
<xsl:apply-templates select="$reference/@*" mode="build"/>

<xsl:if test="not($in-xml='UNWRAPPED')">
<xsl:attribute name="gi" select="($using-name, root-name, use-name,@name)[1]"/>
</xsl:if>
<xsl:attribute name="key" select="($using-name, root-name, use-name,@name)[1]"/>

<xsl:attribute name="min-occurs" select="$minOccurs"/>
<xsl:attribute name="max-occurs" select="$maxOccurs"/>
<xsl:if test="exists(root-name) and not(@name=$visited)">
<xsl:if test="exists(root-name) and not(@_key-name=$visited)">
<xsl:attribute name="min-occurs" select="'1'"/>
</xsl:if>
<xsl:for-each select="$in-xml"><!-- UNWRAPPED or WITH_WRAPPER - supports unwrapped markup-multiline fields -->
Expand All @@ -62,18 +72,25 @@
<xsl:for-each select="$group-json"><!-- ARRAY (default), SINGLETON_OR_ARRAY, BY_KEY -->
<xsl:attribute name="group-json" select="."/>
</xsl:for-each>
<xsl:apply-templates select="json-key" mode="build"/>
<xsl:apply-templates select="($reference/json-key,json-key)[1]" mode="build"/>
<xsl:apply-templates select="($reference/json-value-key,json-value-key)[1]" mode="build"/>
<xsl:for-each select="$group-name">
<xsl:attribute name="group-name" select="."/>
</xsl:for-each>
<xsl:if test="not(@name = $visited)">
<xsl:apply-templates select="formal-name | description"/>
<xsl:apply-templates select="formal-name | description"/>
<xsl:if test="not(@_key-name = $visited)">
<xsl:apply-templates select="define-flag | flag" mode="build"/>
<xsl:apply-templates select="model" mode="build">
<xsl:with-param name="visited" tunnel="true" select="$visited, string(@name)"/>
<xsl:with-param name="visited" tunnel="true" select="$visited, string(@_key-name)"/>
</xsl:apply-templates>
<xsl:variable name="value-keyname">
<xsl:apply-templates select="." mode="value-keyname"/>
</xsl:variable>
<xsl:for-each select="self::define-field">
<value as-type="{(@as-type,'string')[1]}">
<xsl:for-each select="(@_metaschema-xml-id|@_metaschema-json-id)">
<xsl:attribute name="{ name(.) }" select=". || '/' || $value-keyname"/>
</xsl:for-each>
<xsl:apply-templates select="." mode="value-key"/>
</value>
</xsl:for-each>
Expand All @@ -84,18 +101,25 @@
</xsl:template>

<xsl:template match="define-flag" mode="build">
<xsl:param name="given-type" select="()"/>
<xsl:param name="required" select="@required='yes'"/>
<xsl:param name="using-name" select="()"/>
<xsl:param name="with-remarks" select="()"/>
<flag max-occurs="1" min-occurs="{if ($required) then 1 else 0}" as-type="{ ($given-type,@as-type, 'string')[1] }">
<xsl:apply-templates select="@*" mode="build"/>
<xsl:param name="reference" select="."/>

<xsl:variable name="given-type" select="$reference/@as-type"/>
<xsl:variable name="is-required" select="($reference/@required | @required) ='yes'"/>
<xsl:variable name="using-name" select="$reference/(use-name,@ref)[1]"/>
<xsl:variable name="with-remarks" select="$reference/with-remarks"/>

<flag max-occurs="1" min-occurs="{if ($is-required) then 1 else 0}" as-type="{ ($given-type,@as-type, 'string')[1] }">

<xsl:apply-templates select="@*" mode="build"/>
<xsl:apply-templates select="$reference/@*" mode="build"/>

<xsl:for-each select="parent::METASCHEMA">
<xsl:attribute name="scope">global</xsl:attribute>
</xsl:for-each>
<xsl:attribute name="gi" select="($using-name,use-name,@name,@ref)[1]"/>

<xsl:attribute name="gi" select="($using-name,use-name,@name,@ref)[1]"/>
<xsl:attribute name="key" select="($using-name,use-name,@name,@ref)[1]"/>
<xsl:attribute name="link" select="(@ref,../@name)[1]"/>

<xsl:apply-templates select="formal-name | description"/>
<xsl:apply-templates select="constraint"/>
<xsl:apply-templates select="$with-remarks, remarks"/>
Expand Down Expand Up @@ -138,6 +162,24 @@
</xsl:template>

<xsl:template mode="build" match="model//assembly">
<xsl:apply-templates mode="build" select="key('global-assemblies', @_key-ref)">
<xsl:with-param name="reference" select="."/>
</xsl:apply-templates>
</xsl:template>

<xsl:template mode="build" match="model//field">
<xsl:apply-templates mode="build" select="key('global-fields', @_key-ref)">
<xsl:with-param name="reference" select="."/>
</xsl:apply-templates>
</xsl:template>

<xsl:template mode="build" match="flag">
<xsl:apply-templates mode="build" select="key('global-flags', @_key-ref)">
<xsl:with-param name="reference" select="."/>
</xsl:apply-templates>
</xsl:template>

<!--<xsl:template mode="build" match="model//assembly">
<xsl:apply-templates mode="build" select="key('global-assemblies', @ref)">
<xsl:with-param name="minOccurs" select="(@min-occurs,'0')[1]"/>
<xsl:with-param name="maxOccurs" select="(@max-occurs,'1')[1]"/>
Expand All @@ -148,9 +190,10 @@
<xsl:with-param name="using-name" select="use-name"/>
<xsl:with-param name="with-remarks" select="remarks"/>
</xsl:apply-templates>
</xsl:template>
</xsl:template>-->

<xsl:template mode="build" match="model//field">

<!--<xsl:template mode="build" match="model//field">
<xsl:apply-templates mode="build" select="key('global-fields', @ref)">
<xsl:with-param name="minOccurs" select="(@min-occurs,'0')[1]"/>
<xsl:with-param name="maxOccurs" select="(@max-occurs,'1')[1]"/>
Expand All @@ -161,9 +204,9 @@
<xsl:with-param name="using-name" select="use-name"/>
<xsl:with-param name="with-remarks" select="remarks"/>
</xsl:apply-templates>
</xsl:template>
</xsl:template>-->

<xsl:template mode="build" match="flag">
<!--<xsl:template mode="build" match="flag">
<xsl:apply-templates mode="build" select="key('global-flags', @ref)">
<xsl:with-param name="minOccurs" select="(@min-occurs,'0')[1]"/>
<xsl:with-param name="maxOccurs" select="(@max-occurs,'1')[1]"/>
Expand All @@ -175,7 +218,7 @@
<xsl:with-param name="with-remarks" select="remarks"/>
<xsl:with-param name="given-type" select="@as-type"/>
</xsl:apply-templates>
</xsl:template>
</xsl:template>-->

<xsl:template match="constraint" mode="build">
<xsl:copy>
Expand All @@ -196,23 +239,31 @@

<!-- When a field has no flags not designated as a json-value-flag, it is 'naked'; its value is given without a key
(in target JSON it will be the value of a (scalar) property, not a value on a property of an object property. -->

<xsl:template mode="value-key" priority="3" match="define-field[empty(flag[not(@ref=../json-value-key/@flag-name)] | define-flag[not(@ref=../json-value-key/@flag-name)])]"/>

<xsl:template priority="2" match="define-field[exists(json-value-key)]" mode="value-key">
<xsl:attribute name="key" select="json-value-key"/>
<xsl:template match="define-field" mode="value-key">
<xsl:attribute name="key">
<xsl:apply-templates select="." mode="value-keyname"/>
</xsl:attribute>
</xsl:template>

<xsl:template match="define-field[@as-type='markup-line']" mode="value-key">
<xsl:attribute name="key" select="$markdown-value-label"/>
<xsl:template priority="2" match="define-field[exists(json-value-key)]" mode="value-keyname">
<xsl:value-of select="json-value-key"/>
</xsl:template>

<xsl:template match="define-field[@as-type='markup-multiline']" mode="value-key">
<xsl:attribute name="key" select="$markdown-multiline-label"/>
<xsl:template match="define-field[@as-type='markup-line']" mode="value-keyname">
<xsl:value-of select="$markdown-value-label"/>
</xsl:template>


<xsl:template match="define-field" mode="value-key">
<xsl:attribute name="key" select="$string-value-label"/>
<xsl:template match="define-field[@as-type='markup-multiline']" mode="value-keyname">
<xsl:value-of select="$markdown-multiline-label"/>
</xsl:template>


<xsl:template match="define-field" mode="value-keyname">
<xsl:value-of select="$string-value-label"/>
</xsl:template>


</xsl:stylesheet>
Loading

0 comments on commit f48177c

Please sign in to comment.