metatools/sysdeftools/lib/mergesysdef-module.xsl
changeset 660 66ff3e731c60
parent 656 88e01c8f013e
child 663 8e27d440923e
equal deleted inserted replaced
659:7afa5fba0903 660:66ff3e731c60
   134 		<xsl:message terminate="yes">ERROR: Syntax <xsl:value-of select="$other/@schema"/> not supported</xsl:message>
   134 		<xsl:message terminate="yes">ERROR: Syntax <xsl:value-of select="$other/@schema"/> not supported</xsl:message>
   135 	</xsl:if>
   135 	</xsl:if>
   136 	<xsl:if test="name(*) != name($other/*)">
   136 	<xsl:if test="name(*) != name($other/*)">
   137 		<xsl:message terminate="yes">ERROR: Can only merge system models of the same rank</xsl:message>
   137 		<xsl:message terminate="yes">ERROR: Can only merge system models of the same rank</xsl:message>
   138 	</xsl:if>
   138 	</xsl:if>
   139 	 
   139 
   140 	<xsl:copy>
   140 	<xsl:copy>
   141 		<xsl:attribute name="schema">
   141 		<xsl:attribute name="schema">
   142 			<xsl:call-template name="compare-versions">
   142 			<xsl:call-template name="compare-versions">
   143 				<xsl:with-param name="v1" select="@schema"/>
   143 				<xsl:with-param name="v1" select="@schema"/>
   144 				<xsl:with-param name="v2" select="$other/@schema"/>
   144 				<xsl:with-param name="v2" select="$other/@schema"/>
   218 			<xsl:with-param name="origin" select="$down"/>
   218 			<xsl:with-param name="origin" select="$down"/>
   219 			<xsl:with-param name="root" select="current()/.."/>
   219 			<xsl:with-param name="root" select="current()/.."/>
   220 			<xsl:with-param name="replaces" select="$replaces"/>
   220 			<xsl:with-param name="replaces" select="$replaces"/>
   221 		</xsl:apply-templates>		
   221 		</xsl:apply-templates>		
   222 
   222 
       
   223 		<!-- and now check for error cases, and tack those on -->
       
   224 		<xsl:call-template name="check-and-add-out-of-order-items">
       
   225 			<xsl:with-param name="match" select="$other/systemModel"/>
       
   226 			<xsl:with-param name="down" select="$down"/>
       
   227 			<xsl:with-param name="replaces" select="$replaces"/>
       
   228 		</xsl:call-template> 
   223 	</xsl:copy>
   229 	</xsl:copy>
   224 </xsl:template>
   230 </xsl:template>
       
   231 
       
   232 <xsl:template name="check-and-add-out-of-order-items"><xsl:param name="match"/><xsl:param name="down"/><xsl:param name="replaces"/>
       
   233 	<xsl:if test="$match">
       
   234 		<!-- determine the order of the children in the upstream and downstream docs --> 
       
   235 		<xsl:variable name="up-order">
       
   236 			<xsl:for-each select="*[@id=$match/*[not(@before)]/@id]"><xsl:value-of select="@id"/><xsl:text> </xsl:text></xsl:for-each>
       
   237 		</xsl:variable>
       
   238 		<xsl:variable name="down-order">
       
   239 			<xsl:for-each select="$match/*[@id = current()/*[not(@before)]/@id]"><xsl:value-of select="@id"/> <xsl:text> </xsl:text></xsl:for-each>
       
   240 		</xsl:variable>
       
   241 
       
   242 		<!-- check for error cases, and tack those on -->
       
   243 		<xsl:if test="$up-order != $down-order">
       
   244 			<xsl:variable name="down-final" select="$match/*[@id = current()/*[not(@before)]/@id][last()]/@id"/>
       
   245 				<!-- the last item in the downstream model that is also in the upstream one -->
       
   246 
       
   247 			<xsl:variable name="out-of-order" select="$match/*[@id][not(@before=current()/*/@id) and not(@id=current()/*/@id) and following-sibling::*[@id=$down-final]]"/>
       
   248 				<!-- contains all items in the downstream model that can't be put in order-->
       
   249 			<xsl:if test="$out-of-order">
       
   250 				<xsl:message>Warning: Order of <xsl:value-of select="name(*)"/>s in upstream document does not match order in downstream.  The following <xsl:value-of select="name(*)"/>s will be appended to the end<xsl:if test="@id"> of <xsl:value-of select="@id"/></xsl:if>: <xsl:for-each select="$out-of-order"><xsl:value-of select="concat(@id,' ')"/></xsl:for-each></xsl:message>
       
   251 			</xsl:if>
       
   252 			<xsl:apply-templates mode="merge-copy-of" select="$out-of-order">
       
   253 				<xsl:with-param name="origin" select="$down"/>
       
   254 				<xsl:with-param name="root" select="current()/ancestor::SystemDefinition"/>			
       
   255 				<xsl:with-param name="replaces" select="$replaces"/>
       
   256 			</xsl:apply-templates>			
       
   257 		</xsl:if>
       
   258 	</xsl:if>
       
   259 </xsl:template>
       
   260 
   225 
   261 
   226 <xsl:template match="@*|*|comment()" mode="merge-models"><xsl:copy-of select="."/></xsl:template>
   262 <xsl:template match="@*|*|comment()" mode="merge-models"><xsl:copy-of select="."/></xsl:template>
   227 
   263 
   228 
   264 
   229 <xsl:template match="meta|comment()[following-sibling::meta]" mode="merge-models"/>
   265 <xsl:template match="meta|comment()[following-sibling::meta]" mode="merge-models"/>
   368 	<xsl:call-template name="best-prev">
   404 	<xsl:call-template name="best-prev">
   369 		<xsl:with-param name="alt" select="$match"/>
   405 		<xsl:with-param name="alt" select="$match"/>
   370 	</xsl:call-template>
   406 	</xsl:call-template>
   371 </xsl:variable>
   407 </xsl:variable>
   372 
   408 
       
   409 
       
   410 	<!-- check the order of the items in the upstream and downstream doc. If they don't match up, we can't merge them nicely -->
       
   411 	<xsl:variable name="up-order">
       
   412 		<xsl:for-each select="../*[@id=$match/../*[not(@before)]/@id]"><xsl:value-of select="@id"/><xsl:text> </xsl:text></xsl:for-each>
       
   413 	</xsl:variable>
       
   414 	<xsl:variable name="down-order">
       
   415 		<xsl:for-each select="$match/../*[@id = current()/../*[not(@before)]/@id]"><xsl:value-of select="@id"/> <xsl:text> </xsl:text></xsl:for-each>
       
   416 	</xsl:variable>
       
   417 
   373 	<!-- prev = the previous item before the current one (no metas, only named items)-->
   418 	<!-- prev = the previous item before the current one (no metas, only named items)-->
   374 	<xsl:variable name="prev" select="preceding-sibling::*[@id=$prev-id]"/> 
   419 	<xsl:variable name="prev" select="preceding-sibling::*[@id=$prev-id]"/> 
   375 
   420 
   376 
   421 
   377 	<!-- copy all items between this and prev that are solely in the downstream model -->	 		
   422 	<!-- copy all items between this and prev that are solely in the downstream model -->	 		
   378 
   423 
   379 	<xsl:choose>
   424 	<!-- <xsl:variable name="upstream-ids" select="ancestor::SystemDefinition//@id[parent::component or parent::collection or parent::package or parent::layer]"/> -->
       
   425 	<xsl:variable name="upstream-ids" select="../*/@id"/> <!-- this is much faster than using all IDs. before only currently works in the same parent anyway -->
       
   426 
       
   427 	<!-- $upstream-ids is used to avoid inserting an item that's being moved -->
       
   428 
       
   429 	<xsl:choose>
       
   430 		<xsl:when test="$match and $up-order != $down-order">
       
   431 		<!-- if the contents are in a different order, there's no way to merge them together. Don't try. Tack them on to the end later -->
       
   432 				<xsl:message>Warning: Order of <xsl:value-of select="name()"/>s in upstream <xsl:value-of select="../@id"/>
       
   433 				<xsl:if test="not(../@id)">document</xsl:if> does not match the order of the <xsl:value-of select="name()"/>s in common in the downstream equivalent. Contents will not be properly merged: <xsl:value-of select="$up-order"/>  != 	<xsl:value-of select="$down-order"/></xsl:message>
       
   434 		</xsl:when>
       
   435 
   380 		<xsl:when test="$match and $prev">
   436 		<xsl:when test="$match and $prev">
   381 			<xsl:call-template name="copy-sorted-content">
   437 			<xsl:call-template name="copy-sorted-content">
   382 				<xsl:with-param name="base" select="../*[@id]"/>
   438 				<xsl:with-param name="base" select="../*[@id]"/>
   383 				<xsl:with-param name="to-sort" select="$other/*[@id][following-sibling::*[@id=$match/@id]][preceding-sibling::*[@id=$prev/@id]]"/>
   439 				<xsl:with-param name="to-sort" select="$other/*[@id and not(@before=$upstream-ids)][following-sibling::*[@id=$match/@id]][preceding-sibling::*[@id=$prev/@id]]"/>
   384 				<xsl:with-param name="start" select="$prev"/>
   440 				<xsl:with-param name="start" select="$prev"/>
   385 				<xsl:with-param name="end" select="."/>
   441 				<xsl:with-param name="end" select="."/>
   386 				<xsl:with-param name="down" select="$down"/>
   442 				<xsl:with-param name="down" select="$down"/>
   387 			</xsl:call-template>
   443 			</xsl:call-template>
   388 		</xsl:when>
   444 		</xsl:when>
   389 		<xsl:when test="$match and not($prev)">
   445 		<xsl:when test="$match and not($prev)">
   390 			<xsl:call-template name="copy-sorted-content">
   446 			<xsl:call-template name="copy-sorted-content">
   391 				<xsl:with-param name="base" select="../*[@id]"/>
   447 				<xsl:with-param name="base" select="../*[@id]"/>
   392 				<xsl:with-param name="to-sort" select="$other/*[@id][following-sibling::*[@id=$match/@id]]"/>
   448 				<xsl:with-param name="to-sort" select="$other/*[@id and not(@before=$upstream-ids)][following-sibling::*[@id=$match/@id]]"/>
   393 				<xsl:with-param name="start" select="$prev"/>
   449 				<xsl:with-param name="start" select="$prev"/>
   394 				<xsl:with-param name="end" select="."/>
   450 				<xsl:with-param name="end" select="."/>
   395 				<xsl:with-param name="down" select="$down"/>
   451 				<xsl:with-param name="down" select="$down"/>
   396 			</xsl:call-template>
   452 			</xsl:call-template>
   397 		</xsl:when>
   453 		</xsl:when>
   398 	</xsl:choose>
   454 	</xsl:choose>
   399 
   455 
   400  	<!-- just copy anything identified as being before this, assume they're all ok -->
   456  	<!-- just copy anything identified as being before this, assume they're all ok -->
       
   457 
   401 	<xsl:apply-templates mode="merge-copy-of" select="$other/*[@before=current()/@id]">
   458 	<xsl:apply-templates mode="merge-copy-of" select="$other/*[@before=current()/@id]">
   402 		<xsl:with-param name="remove-before" select="1"/>
   459 		<xsl:with-param name="remove-before" select="1"/>
   403 		<xsl:with-param name="origin" select="$down"/>
   460 		<xsl:with-param name="origin" select="$down"/>
   404 		<xsl:with-param name="root" select="$this/ancestor::SystemDefinition"/>	
   461 		<xsl:with-param name="root" select="$this/ancestor::SystemDefinition"/>	
   405 		<xsl:with-param name="replaces" select="$replaces"/>
   462 		<xsl:with-param name="replaces" select="$replaces"/>
   407 	
   464 	
   408 	<xsl:copy>
   465 	<xsl:copy>
   409 		<xsl:apply-templates select="@*" mode="merge-models"> <!-- copy upstream attributes -->
   466 		<xsl:apply-templates select="@*" mode="merge-models"> <!-- copy upstream attributes -->
   410 			<xsl:with-param name="other" select="$match"/>
   467 			<xsl:with-param name="other" select="$match"/>
   411 		</xsl:apply-templates>
   468 		</xsl:apply-templates>
   412 		
   469 		<xsl:if test="self::component and not(@origin-model) and ($up/@name or ancestor::systemModel/@name)">
   413 		<xsl:if test="self::component and not(@origin-model) and $up/@name">
       
   414 			<!-- insert origin-model and optional root for components only -->
   470 			<!-- insert origin-model and optional root for components only -->
   415 			<xsl:attribute name="origin-model">
   471 			<xsl:attribute name="origin-model">
   416 				<xsl:value-of select="$up/@name"/>
   472 				<xsl:value-of select="$up/@name"/>
       
   473 				<xsl:if test="not($up/@name)"><xsl:value-of select="ancestor::systemModel/@name"/></xsl:if>
   417 			</xsl:attribute>
   474 			</xsl:attribute>
   418 			<xsl:if test="not(@root)">
   475 			<xsl:if test="not(@root)">
   419 				<xsl:copy-of select="$up/@root"/>
   476 				<xsl:copy-of select="$up/@root"/>
   420 			</xsl:if>
   477 			</xsl:if>
   421 		</xsl:if>
   478 		</xsl:if>
   464 						</xsl:apply-templates>
   521 						</xsl:apply-templates>
   465 					</xsl:if>
   522 					</xsl:if>
   466 				</xsl:for-each>
   523 				</xsl:for-each>
   467 			</xsl:otherwise>
   524 			</xsl:otherwise>
   468 		</xsl:choose>
   525 		</xsl:choose>
       
   526 
       
   527 		<!-- and now check for error cases, and tack those on -->
       
   528 		<xsl:call-template name="check-and-add-out-of-order-items">
       
   529 			<xsl:with-param name="match" select="$match"/>
       
   530 			<xsl:with-param name="down" select="$down"/>
       
   531 			<xsl:with-param name="replaces" select="$replaces"/>
       
   532 		</xsl:call-template> 
       
   533 
   469 	</xsl:copy>
   534 	</xsl:copy>
   470 
   535  	</xsl:otherwise>
   471 		</xsl:otherwise>
       
   472 	</xsl:choose>
   536 	</xsl:choose>
   473 </xsl:template>
   537 </xsl:template>
   474 
   538 
   475 
   539 
   476 
   540 
   552 			<xsl:copy>
   616 			<xsl:copy>
   553 				<xsl:call-template name="merge-copy-of-atts">
   617 				<xsl:call-template name="merge-copy-of-atts">
   554 					<xsl:with-param name="remove-before" select="$remove-before"/>
   618 					<xsl:with-param name="remove-before" select="$remove-before"/>
   555 					<xsl:with-param name="root" select="$root"/>
   619 					<xsl:with-param name="root" select="$root"/>
   556 				</xsl:call-template>
   620 				</xsl:call-template>
   557 				<xsl:if test="not(@origin-model) and $origin/@name">
   621 				<xsl:if test="not(@origin-model) and ($origin/@name or ancestor::systemModel/@name)">
   558 					<xsl:attribute name="origin-model">
   622 					<xsl:attribute name="origin-model">
   559 						<xsl:value-of select="$origin/@name"/>
   623 						<xsl:value-of select="$origin/@name"/>
       
   624 						<xsl:if test="not($origin/@name)"><xsl:value-of select="ancestor::systemModel/@name"/></xsl:if>
   560 					</xsl:attribute>
   625 					</xsl:attribute>
   561 					<xsl:if test="not(@root)">
   626 					<xsl:if test="not(@root)">
   562 						<xsl:copy-of select="$origin/@root"/>
   627 						<xsl:copy-of select="$origin/@root"/>
   563 					</xsl:if>
   628 					</xsl:if>
   564 				</xsl:if>
   629 				</xsl:if>