--- a/sysdeftools/mergesysdef-module.xsl Thu May 06 16:24:41 2010 +0100
+++ b/sysdeftools/mergesysdef-module.xsl Thu May 06 16:31:38 2010 +0100
@@ -42,7 +42,7 @@
</xsl:template>
-<xsl:template match="@id|@before" mode="translate-namespaces"><xsl:param name="nsdoc"/>
+<xsl:template match="@id|@before|@replace" mode="translate-namespaces"><xsl:param name="nsdoc"/>
<xsl:attribute name="{name()}">
<xsl:variable name="id">
<xsl:choose>
@@ -59,8 +59,8 @@
<xsl:when test="contains(.,':')">
<xsl:value-of select="ancestor-or-self::*/namespace::*[name()=substring-before(current()/.,':')]"/>
</xsl:when>
- <xsl:when test="/SystemDefinition/@id-namespace">
- <xsl:value-of select="/SystemDefinition/@id-namespace"/>
+ <xsl:when test="ancestor::SystemDefinition/@id-namespace">
+ <xsl:value-of select="ancestor::SystemDefinition/@id-namespace"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$defaultnamespace"/>
@@ -77,7 +77,7 @@
<xsl:when test="$nsdoc/namespace::*[.=$ns]">
<xsl:value-of select="concat(name($nsdoc/namespace::*[.=$ns]),':',$id)"/>
</xsl:when>
- <xsl:when test="/SystemDefinition/@id-namespace=$ns">
+ <xsl:when test="ancestor::SystemDefinition/@id-namespace=$ns">
<xsl:variable name="myns">
<xsl:apply-templates mode="ns-prefix" select="$nsdoc">
<xsl:with-param name="ns" select="$ns"/>
@@ -93,7 +93,7 @@
</xsl:attribute>
</xsl:template>
-<xsl:template match="/SystemDefinition" mode="ns-prefix">
+<xsl:template match="SystemDefinition" mode="ns-prefix">
<xsl:param name="ns"/> <!-- the namespace URI -->
<xsl:param name="pre"/> <!-- the preferred prefix to use if possbile -->
<xsl:param name="dontuse"/> <!-- space prefixed, separated and terminated list of namespace prefixes to not use -->
@@ -121,7 +121,7 @@
<!-- need to make sure this handles <meta> correctly -->
-<xsl:template match="/SystemDefinition" mode="merge-models">
+<xsl:template match="SystemDefinition" mode="merge-models">
<xsl:param name="other"/> <!-- the downstream SystemDefinition this is merged with -->
<xsl:param name="up" select="systemModel"/> <!-- the element containing the origin @name used for any component from "this" model. -->
<xsl:param name="down" select="$other/systemModel"/> <!-- the element containing origin @name used for any component from $other model. -->
@@ -135,7 +135,13 @@
</xsl:if>
<xsl:copy>
- <xsl:copy-of select="@*"/> <!-- use attributes from origin model -->
+ <xsl:attribute name="schema">
+ <xsl:call-template name="compare-versions">
+ <xsl:with-param name="v1" select="@schema"/>
+ <xsl:with-param name="v2" select="$other/@schema"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:copy-of select="@*[name()!='schema']"/> <!-- use attributes from origin model -->
<xsl:variable name="namespaces">
<xsl:copy> <!-- needs <copy> so the processor doesn't lose the namespaces -->
<!--copy namespaces as needed -->
@@ -183,6 +189,7 @@
<xsl:with-param name="other" select="exslt:node-set($otherdoc)/*"/>
<xsl:with-param name="up" select="$up"/>
<xsl:with-param name="down" select="$down"/>
+ <xsl:with-param name="replaces" select="exslt:node-set($otherdoc)//*[self::component or self::collection or self::package or self::layer]/@replace"/>
</xsl:apply-templates>
</xsl:copy>
@@ -192,6 +199,7 @@
<xsl:param name="other"/> <!-- the parent of the downstream systemModel this is merged with -->
<xsl:param name="up"/>
<xsl:param name="down"/>
+ <xsl:param name="replaces"/>
<xsl:copy><xsl:copy-of select="@*"/>
<!-- copy metas and comments in between meta. Do not try to merge metadata between models -->
<xsl:copy-of select="meta | $other/systemModel/meta | comment()[following-sibling::meta]"/>
@@ -199,6 +207,7 @@
<xsl:with-param name="other" select="$other/systemModel"/>
<xsl:with-param name="up" select="$up"/>
<xsl:with-param name="down" select="$down"/>
+ <xsl:with-param name="replaces" select="$replaces"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
@@ -357,12 +366,28 @@
<xsl:param name="other"/> <!-- the downstream item of the parent's rank that contains a potential items this is merged with -->
<xsl:param name="up"/>
<xsl:param name="down"/>
+ <xsl:param name="replaces"/>
<xsl:variable name="this" select="."/> <!-- current item -->
-
+
<!-- match = this item in the downstream model -->
<xsl:variable name="match" select="$other/*[@id=current()/@id]"/>
-
-
+
+ <xsl:choose>
+ <xsl:when test="$replaces[.=$this/@id] or (self::component and $match)"> <!-- replace the item instead of merge -->
+ <xsl:message>Note: <xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" <xsl:choose>
+ <xsl:when test="self::component and $match">overridden in downstream sysdef</xsl:when>
+ <xsl:otherwise><xsl:for-each select="$replaces[.=$this/@id]/..">replaced by <xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>"</xsl:for-each></xsl:otherwise>
+ </xsl:choose>
+ </xsl:message>
+ <!-- if the removed item is in the downstream doc, just copy that and ignore the upstream contents -->
+ <xsl:apply-templates mode="merge-copy-of" select="$match">
+ <xsl:with-param name="origin" select="$down"/>
+ <xsl:with-param name="root" select="$this/ancestor::systemModel"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- remove this if it's in the list of stuff to be replaced-->
+
<!-- prev = the previous item before the current one (no metas, only named items)-->
<xsl:variable name="prev" select="preceding-sibling::*[@id][1]"/>
@@ -410,9 +435,16 @@
</xsl:if>
</xsl:if>
- <xsl:for-each select="$match/@*"> <!-- copy downstream attributes, only if not set on upstream -->
+ <xsl:for-each select="$match/@*[name()!='replace']"> <!-- copy downstream attributes, only if not set on upstream -->
<xsl:if test="not($this/@*[name()=name(current())])"><xsl:copy-of select="."/></xsl:if>
</xsl:for-each>
+
+ <xsl:if test="$match/@replace"> <!-- check replace separately -->
+ <xsl:if test="not($this/ancestor::SystemDefinition//*[(self::component or self::collection or self::package or self::layer) and $match/@replace=@id])">
+ <!-- only remove replace if it's been used -->
+ <xsl:copy-of select="$match/@replace"/>
+ </xsl:if>
+ </xsl:if>
<xsl:choose>
<xsl:when test="self::component">
@@ -435,6 +467,7 @@
<xsl:with-param name="other" select="$match"/>
<xsl:with-param name="up" select="$up"/>
<xsl:with-param name="down" select="$down"/>
+ <xsl:with-param name="replaces" select="$replaces"/>
</xsl:apply-templates>
<!-- don't copy if explicitly or implicitly placed already-->
<xsl:for-each select="$match/*[not(@before) and not(following-sibling::*[@id=$this/*/@id])]">
@@ -448,8 +481,11 @@
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
+
+ </xsl:otherwise>
+ </xsl:choose>
- <xsl:if test="self::layer and not(following-sibling::layer)">
+ <xsl:if test="self::layer and not(following-sibling::layer)">
<!-- for the last layer, tack on any remaining layers -->
<xsl:apply-templates mode="merge-copy-of" select="$other/layer[not(@before) and not(following-sibling::*[@id=$this/../layer/@id]) and not(@id=$this/../layer/@id)]">
<xsl:with-param name="origin" select="$down"/>
@@ -489,12 +525,10 @@
</xsl:when>
<xsl:otherwise>
<xsl:copy>
- <xsl:choose>
- <xsl:when test="$remove-before">
- <xsl:copy-of select="@*[name()!='before']"/>
- </xsl:when>
- <xsl:otherwise><xsl:copy-of select="@*"/></xsl:otherwise>
- </xsl:choose>
+ <xsl:call-template name="merge-copy-of-atts">
+ <xsl:with-param name="remove-before" select="$remove-before"/>
+ <xsl:with-param name="root" select="$root"/>
+ </xsl:call-template>
<xsl:copy-of select="exslt:node-set($content)"/>
</xsl:copy>
</xsl:otherwise>
@@ -508,11 +542,27 @@
<xsl:copy-of select="."/>
</xsl:template>
+
+<xsl:template name="merge-copy-of-atts">
+ <xsl:param name="remove-before" select="0"/> <!-- set to true if any before attribute is to be removed -->
+ <xsl:param name="root"/> <!--the systemModel element in the upstream doc -->
+ <xsl:choose>
+ <xsl:when test="$remove-before">
+ <xsl:copy-of select="@*[name()!='before' and name()!='replace']"/>
+ </xsl:when>
+ <xsl:otherwise><xsl:copy-of select="@*[name()!='replace']"/></xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="@replace and not($root/descendant::*[(self::component or self::collection or self::package or self::layer) and @id=current()/@replace])">
+ <!-- only include replace if it's not been used -->
+ <xsl:copy-of select="@replace"/>
+ </xsl:if>
+</xsl:template>
+
<xsl:template match="component" mode="merge-copy-of">
<xsl:param name="remove-before" select="0"/> <!-- set to true if any before attribute is to be removed -->
<xsl:param name="origin"/> <!--the element containing the @name to use the origin-model attribute -->
<xsl:param name="root"/> <!--the systemModel element in the upstream doc -->
-
+
<xsl:choose>
<!-- this might slow things down, consider making optional -->
<xsl:when test="$root/descendant::collection[@id!=current()/../@id]/component[@id=current()/@id]">
@@ -522,12 +572,10 @@
</xsl:when>
<xsl:otherwise>
<xsl:copy>
- <xsl:choose>
- <xsl:when test="$remove-before">
- <xsl:copy-of select="@*[name()!='before']"/>
- </xsl:when>
- <xsl:otherwise><xsl:copy-of select="@*"/></xsl:otherwise>
- </xsl:choose>
+ <xsl:call-template name="merge-copy-of-atts">
+ <xsl:with-param name="remove-before" select="$remove-before"/>
+ <xsl:with-param name="root" select="$root"/>
+ </xsl:call-template>
<xsl:if test="not(@origin-model) and $origin/@name">
<xsl:attribute name="origin-model">
<xsl:value-of select="$origin/@name"/>