--- a/metatools/sysdeftools/lib/mergesysdef-module.xsl Mon Oct 18 16:16:46 2010 +0800
+++ b/metatools/sysdeftools/lib/mergesysdef-module.xsl Mon Oct 18 10:23:52 2010 +0100
@@ -213,7 +213,6 @@
<xsl:with-param name="replaces" select="$replaces"/>
</xsl:apply-templates>
-
<!-- tack on any remaining layers -->
<xsl:apply-templates mode="merge-copy-of" select="$other/systemModel/layer[not(@before) and not(following-sibling::*[@id=current()/layer/@id]) and not(@id=current()/layer/@id)]">
<xsl:with-param name="origin" select="$down"/>
@@ -273,67 +272,16 @@
<xsl:choose>
<xsl:when test="not($to-sort)"/> <!-- nothing left to copy. stop -->
<xsl:when test="not($base)"/> <!-- reached end. stop -->
- <xsl:when test="$base[1]/@id=$end/following-sibling::*[1]/@id"/> <!-- passed $end. Stop -->
- <xsl:when test="$base[1]/@id = $to-sort[1]/@id"> <!-- both lists start with same item -->
- <xsl:if test="$base[1]/@id!=$end/@id"> <!-- not at end, so keep going -->
- <xsl:call-template name="copy-sorted-content">
- <xsl:with-param name="base" select="$base[position() != 1]"/>
- <xsl:with-param name="to-sort" select="$to-sort[position() != 1]"/>
- <xsl:with-param name="remainder" select="$remainder"/>
- <xsl:with-param name="start" select="$start"/>
- <xsl:with-param name="end" select="$end"/>
- <xsl:with-param name="down" select="$down"/>
- </xsl:call-template>
- </xsl:if>
- </xsl:when>
- <xsl:when test="$remainder[@id = $base[1]/@id]"> <!-- left over item is in $base -->
- <xsl:call-template name="copy-sorted-content">
- <xsl:with-param name="base" select="$base[position() != 1]"/>
- <xsl:with-param name="to-sort" select="$to-sort"/>
- <xsl:with-param name="remainder" select="$remainder[@id != $base[1]/@id]"/>
- <xsl:with-param name="start" select="$start"/>
- <xsl:with-param name="end" select="$end"/>
- <xsl:with-param name="down" select="$down"/>
- </xsl:call-template>
- </xsl:when>
- <xsl:when test="not($base[@id = $to-sort[1]/@id])"> <!-- in to-sort, but not base -->
- <xsl:if test="$base[1]/@id=$end/@id and not($base[@id=$to-sort[1]/@before])">
- <!-- if at end, then this needs to be copied
- don't copy if the before ID is found in $base -->
- <xsl:apply-templates mode="merge-copy-of" select="$to-sort[1]">
- <xsl:with-param name="origin" select="$down"/>
- <xsl:with-param name="root" select="$end/ancestor::SystemDefinition"/>
- </xsl:apply-templates>
- </xsl:if>
- <xsl:call-template name="copy-sorted-content">
- <xsl:with-param name="base" select="$base"/>
- <xsl:with-param name="to-sort" select="$to-sort[position() != 1]"/>
- <xsl:with-param name="remainder" select="$remainder"/>
- <xsl:with-param name="start" select="$start"/>
- <xsl:with-param name="end" select="$end"/>
- <xsl:with-param name="down" select="$down"/>
- </xsl:call-template>
- </xsl:when>
- <xsl:when test="not($to-sort[@id = $base[1]/@id])"> <!-- in base, but not to-sort -->
- <xsl:call-template name="copy-sorted-content">
- <xsl:with-param name="base" select="$base[position() != 1]"/>
- <xsl:with-param name="to-sort" select="$to-sort"/>
- <xsl:with-param name="remainder" select="$remainder"/>
- <xsl:with-param name="start" select="$start"/>
- <xsl:with-param name="end" select="$end"/>
- <xsl:with-param name="down" select="$down"/>
- </xsl:call-template>
- </xsl:when>
- <xsl:when test="$base[@id = $to-sort[1]/@id]"> <!-- is in base, but not 1st one-->
- <xsl:call-template name="copy-sorted-content">
- <xsl:with-param name="base" select="$base"/>
- <xsl:with-param name="to-sort" select="$to-sort[position() != 1] "/>
- <xsl:with-param name="remainder" select="$remainder | $to-sort[1]"/>
- <xsl:with-param name="start" select="$start"/>
- <xsl:with-param name="end" select="$end"/>
- <xsl:with-param name="down" select="$down"/>
- </xsl:call-template>
- </xsl:when>
+ <xsl:otherwise>
+ <xsl:for-each select="$to-sort">
+ <xsl:if test="((@before=$end/@id) or not(@before) or not($base/ancestor::SystemDefinition//*[@id=current()/@before])) and not($base[@id=current()/@id])">
+ <xsl:apply-templates mode="merge-copy-of" select=".">
+ <xsl:with-param name="origin" select="$down"/>
+ <xsl:with-param name="root" select="$end/ancestor::SystemDefinition"/>
+ </xsl:apply-templates>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:otherwise>
</xsl:choose>
</xsl:template>
@@ -374,6 +322,22 @@
</xsl:template>
+<xsl:template name="best-prev"><xsl:param name="cur" select="."/><xsl:param name="alt"/>
+<xsl:if test="$alt">
+<xsl:variable name="prev" select="$cur/preceding-sibling::*[@id][1]"/>
+<xsl:choose>
+ <xsl:when test="not($prev)"/>
+ <xsl:when test="$alt/preceding-sibling::*[@id=$prev/@id]"><xsl:value-of select="$prev/@id"/></xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="best-prev">
+ <xsl:with-param name="cur" select="$prev"/>
+ <xsl:with-param name="alt" select="$alt"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+</xsl:choose>
+</xsl:if>
+</xsl:template>
+
<xsl:template match="layer | package | collection | component" mode="merge-models">
<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"/>
@@ -386,9 +350,9 @@
<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"/>" in "<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"/>" in "<xsl:value-of select="../@id"/>"</xsl:for-each></xsl:otherwise>
- </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"/>" in "<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">
@@ -400,29 +364,37 @@
<xsl:otherwise>
<!-- remove this if it's in the list of stuff to be replaced-->
+<xsl:variable name="prev-id">
+ <xsl:call-template name="best-prev">
+ <xsl:with-param name="alt" select="$match"/>
+ </xsl:call-template>
+</xsl:variable>
+
<!-- prev = the previous item before the current one (no metas, only named items)-->
- <xsl:variable name="prev" select="preceding-sibling::*[@id][1]"/>
+ <xsl:variable name="prev" select="preceding-sibling::*[@id=$prev-id]"/>
- <!-- copy all items between this and prev that are solely in the downstream model -->
+
+ <!-- copy all items between this and prev that are solely in the downstream model -->
<xsl:choose>
- <xsl:when test="$match and (not($prev) or $other/*[@id= $prev/@id] )">
+ <xsl:when test="$match and $prev">
<xsl:call-template name="copy-sorted-content">
<xsl:with-param name="base" select="../*[@id]"/>
- <xsl:with-param name="to-sort" select="$other/*[@id]"/>
+ <xsl:with-param name="to-sort" select="$other/*[@id][following-sibling::*[@id=$match/@id]][preceding-sibling::*[@id=$prev/@id]]"/>
<xsl:with-param name="start" select="$prev"/>
<xsl:with-param name="end" select="."/>
<xsl:with-param name="down" select="$down"/>
</xsl:call-template>
</xsl:when>
- <xsl:when test="not($match/preceding-sibling::*[@id=$this/../*/@id]) and $other/*[@id= current()/@id]/preceding-sibling::*[@id and not(@before)]">
- <!-- if this is the first item in other that's also in this, then put all new items from other here -->
- <xsl:apply-templates mode="merge-copy-of" select="$match/preceding-sibling::*[@id and not(@before)]">
- <xsl:with-param name="origin" select="$down"/>
- <xsl:with-param name="root" select="$this/ancestor::SystemDefinition"/>
- <xsl:with-param name="replaces" select="$replaces"/>
- </xsl:apply-templates>
- </xsl:when>
+ <xsl:when test="$match and not($prev)">
+ <xsl:call-template name="copy-sorted-content">
+ <xsl:with-param name="base" select="../*[@id]"/>
+ <xsl:with-param name="to-sort" select="$other/*[@id][following-sibling::*[@id=$match/@id]]"/>
+ <xsl:with-param name="start" select="$prev"/>
+ <xsl:with-param name="end" select="."/>
+ <xsl:with-param name="down" select="$down"/>
+ </xsl:call-template>
+ </xsl:when>
</xsl:choose>
<!-- just copy anything identified as being before this, assume they're all ok -->
@@ -432,7 +404,6 @@
<xsl:with-param name="root" select="$this/ancestor::SystemDefinition"/>
<xsl:with-param name="replaces" select="$replaces"/>
</xsl:apply-templates>
-
<xsl:copy>
<xsl:apply-templates select="@*" mode="merge-models"> <!-- copy upstream attributes -->