sysdeftools/mergesysdef-module.xsl
branchHighFidelityModel
changeset 201 280dc2a9385b
parent 164 8309dda95234
child 319 b085ba15cdaa
equal deleted inserted replaced
200:6337e330f518 201:280dc2a9385b
    40 </xsl:apply-templates>
    40 </xsl:apply-templates>
    41 </xsl:element>
    41 </xsl:element>
    42 </xsl:template>
    42 </xsl:template>
    43 
    43 
    44 
    44 
    45 <xsl:template match="@id|@before" mode="translate-namespaces"><xsl:param name="nsdoc"/>
    45 <xsl:template match="@id|@before|@replace" mode="translate-namespaces"><xsl:param name="nsdoc"/>
    46 	<xsl:attribute name="{name()}">
    46 	<xsl:attribute name="{name()}">
    47 		<xsl:variable name="id">
    47 		<xsl:variable name="id">
    48 			<xsl:choose>
    48 			<xsl:choose>
    49 				<xsl:when test="contains(.,':')">
    49 				<xsl:when test="contains(.,':')">
    50 					<xsl:value-of select="substring-after(.,':')"/>
    50 					<xsl:value-of select="substring-after(.,':')"/>
    57 		<xsl:variable name="ns">
    57 		<xsl:variable name="ns">
    58 			<xsl:choose>
    58 			<xsl:choose>
    59 				<xsl:when test="contains(.,':')">
    59 				<xsl:when test="contains(.,':')">
    60 					<xsl:value-of select="ancestor-or-self::*/namespace::*[name()=substring-before(current()/.,':')]"/>
    60 					<xsl:value-of select="ancestor-or-self::*/namespace::*[name()=substring-before(current()/.,':')]"/>
    61 				</xsl:when>
    61 				</xsl:when>
    62 				<xsl:when test="/SystemDefinition/@id-namespace">
    62 				<xsl:when test="ancestor::SystemDefinition/@id-namespace">
    63 					<xsl:value-of select="/SystemDefinition/@id-namespace"/>
    63 					<xsl:value-of select="ancestor::SystemDefinition/@id-namespace"/>
    64 				</xsl:when>
    64 				</xsl:when>
    65 				<xsl:otherwise>
    65 				<xsl:otherwise>
    66 					<xsl:value-of select="$defaultnamespace"/>
    66 					<xsl:value-of select="$defaultnamespace"/>
    67 				</xsl:otherwise>
    67 				</xsl:otherwise>
    68 			</xsl:choose>
    68 			</xsl:choose>
    75 				<xsl:value-of select="$id"/>
    75 				<xsl:value-of select="$id"/>
    76 			</xsl:when>
    76 			</xsl:when>
    77 			<xsl:when test="$nsdoc/namespace::*[.=$ns]">
    77 			<xsl:when test="$nsdoc/namespace::*[.=$ns]">
    78 				<xsl:value-of select="concat(name($nsdoc/namespace::*[.=$ns]),':',$id)"/>
    78 				<xsl:value-of select="concat(name($nsdoc/namespace::*[.=$ns]),':',$id)"/>
    79 			</xsl:when>
    79 			</xsl:when>
    80 			<xsl:when test="/SystemDefinition/@id-namespace=$ns">
    80 			<xsl:when test="ancestor::SystemDefinition/@id-namespace=$ns">
    81 				<xsl:variable name="myns">
    81 				<xsl:variable name="myns">
    82 					<xsl:apply-templates mode="ns-prefix" select="$nsdoc">
    82 					<xsl:apply-templates mode="ns-prefix" select="$nsdoc">
    83 						<xsl:with-param name="ns" select="$ns"/>
    83 						<xsl:with-param name="ns" select="$ns"/>
    84 					</xsl:apply-templates>
    84 					</xsl:apply-templates>
    85 				</xsl:variable>			
    85 				</xsl:variable>			
    91 			</xsl:otherwise>
    91 			</xsl:otherwise>
    92 		</xsl:choose>		
    92 		</xsl:choose>		
    93 	</xsl:attribute>
    93 	</xsl:attribute>
    94 </xsl:template>
    94 </xsl:template>
    95 
    95 
    96 <xsl:template match="/SystemDefinition" mode="ns-prefix">
    96 <xsl:template match="SystemDefinition" mode="ns-prefix">
    97 	<xsl:param name="ns"/> <!-- the namespace URI -->
    97 	<xsl:param name="ns"/> <!-- the namespace URI -->
    98 	<xsl:param name="pre"/> <!-- the preferred prefix to use if possbile -->
    98 	<xsl:param name="pre"/> <!-- the preferred prefix to use if possbile -->
    99 	<xsl:param name="dontuse"/> <!-- space prefixed, separated and terminated list of namespace prefixes to not use -->
    99 	<xsl:param name="dontuse"/> <!-- space prefixed, separated and terminated list of namespace prefixes to not use -->
   100 	<xsl:param name="chars">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz</xsl:param> <!-- single letter namespace prefixes to try -->
   100 	<xsl:param name="chars">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz</xsl:param> <!-- single letter namespace prefixes to try -->
   101 	<xsl:variable name="name" select="substring(substring-after($ns,'http://www.'),1,1)"/>
   101 	<xsl:variable name="name" select="substring(substring-after($ns,'http://www.'),1,1)"/>
   119 </xsl:template>
   119 </xsl:template>
   120 
   120 
   121 
   121 
   122 <!--  need to make sure this handles <meta> correctly -->
   122 <!--  need to make sure this handles <meta> correctly -->
   123 
   123 
   124 <xsl:template match="/SystemDefinition" mode="merge-models">
   124 <xsl:template match="SystemDefinition" mode="merge-models">
   125 	<xsl:param name="other"/>	<!-- the downstream SystemDefinition this is merged with -->
   125 	<xsl:param name="other"/>	<!-- the downstream SystemDefinition this is merged with -->
   126 	<xsl:param name="up" select="systemModel"/>	<!-- the element containing the origin @name used for any component from "this" model. -->
   126 	<xsl:param name="up" select="systemModel"/>	<!-- the element containing the origin @name used for any component from "this" model. -->
   127 	<xsl:param name="down" select="$other/systemModel"/> <!-- the element containing origin @name used for any component from $other model. -->
   127 	<xsl:param name="down" select="$other/systemModel"/> <!-- the element containing origin @name used for any component from $other model. -->
   128 	
   128 	
   129 	<!-- do some testing -->
   129 	<!-- do some testing -->
   133 	<xsl:if test="name(*) != name($other/*)">
   133 	<xsl:if test="name(*) != name($other/*)">
   134 		<xsl:message terminate="yes">ERROR: Can only merge system models of the same rank</xsl:message>
   134 		<xsl:message terminate="yes">ERROR: Can only merge system models of the same rank</xsl:message>
   135 	</xsl:if>
   135 	</xsl:if>
   136 	 
   136 	 
   137 	<xsl:copy>
   137 	<xsl:copy>
   138 		<xsl:copy-of  select="@*"/> <!--  use attributes from origin model -->
   138 		<xsl:attribute name="schema">
       
   139 			<xsl:call-template name="compare-versions">
       
   140 				<xsl:with-param name="v1" select="@schema"/>
       
   141 				<xsl:with-param name="v2" select="$other/@schema"/>
       
   142 			</xsl:call-template>
       
   143 		</xsl:attribute>
       
   144 		<xsl:copy-of  select="@*[name()!='schema']"/> <!--  use attributes from origin model -->
   139 		<xsl:variable name="namespaces">
   145 		<xsl:variable name="namespaces">
   140 			<xsl:copy> <!-- needs <copy> so the processor doesn't lose the namespaces -->
   146 			<xsl:copy> <!-- needs <copy> so the processor doesn't lose the namespaces -->
   141 				<!--copy namespaces as needed -->
   147 				<!--copy namespaces as needed -->
   142 				
   148 				
   143 				<xsl:copy-of select="namespace::*[name()!='xml']"/> <!-- all upstream namespaces -->
   149 				<xsl:copy-of select="namespace::*[name()!='xml']"/> <!-- all upstream namespaces -->
   181 	</xsl:variable>
   187 	</xsl:variable>
   182 		<xsl:apply-templates mode="merge-models">
   188 		<xsl:apply-templates mode="merge-models">
   183 			<xsl:with-param name="other" select="exslt:node-set($otherdoc)/*"/>
   189 			<xsl:with-param name="other" select="exslt:node-set($otherdoc)/*"/>
   184 			<xsl:with-param name="up" select="$up"/>
   190 			<xsl:with-param name="up" select="$up"/>
   185 			<xsl:with-param name="down" select="$down"/>
   191 			<xsl:with-param name="down" select="$down"/>
       
   192 			<xsl:with-param name="replaces" select="exslt:node-set($otherdoc)//*[self::component or self::collection or self::package or self::layer]/@replace"/>
   186 		</xsl:apply-templates>
   193 		</xsl:apply-templates>
   187 	
   194 	
   188 	</xsl:copy>
   195 	</xsl:copy>
   189 </xsl:template>
   196 </xsl:template>
   190 
   197 
   191 <xsl:template match="systemModel" mode="merge-models">
   198 <xsl:template match="systemModel" mode="merge-models">
   192 	<xsl:param name="other"/>	<!-- the parent of the downstream systemModel this is merged with -->
   199 	<xsl:param name="other"/>	<!-- the parent of the downstream systemModel this is merged with -->
   193 	<xsl:param name="up"/>
   200 	<xsl:param name="up"/>
   194 	<xsl:param name="down"/>
   201 	<xsl:param name="down"/>
       
   202 	<xsl:param name="replaces"/>
   195 	<xsl:copy><xsl:copy-of  select="@*"/>
   203 	<xsl:copy><xsl:copy-of  select="@*"/>
   196 		<!--  copy metas and comments in between meta. Do not try to merge metadata between models -->
   204 		<!--  copy metas and comments in between meta. Do not try to merge metadata between models -->
   197 			<xsl:copy-of select="meta | $other/systemModel/meta | comment()[following-sibling::meta]"/>	
   205 			<xsl:copy-of select="meta | $other/systemModel/meta | comment()[following-sibling::meta]"/>	
   198 		<xsl:apply-templates mode="merge-models">
   206 		<xsl:apply-templates mode="merge-models">
   199 			<xsl:with-param name="other" select="$other/systemModel"/>
   207 			<xsl:with-param name="other" select="$other/systemModel"/>
   200 			<xsl:with-param name="up" select="$up"/>
   208 			<xsl:with-param name="up" select="$up"/>
   201 			<xsl:with-param name="down" select="$down"/>
   209 			<xsl:with-param name="down" select="$down"/>
       
   210 			<xsl:with-param name="replaces" select="$replaces"/>
   202 		</xsl:apply-templates>
   211 		</xsl:apply-templates>
   203 	</xsl:copy>
   212 	</xsl:copy>
   204 </xsl:template>
   213 </xsl:template>
   205 
   214 
   206 <xsl:template match="@*|*|comment()" mode="merge-models"><xsl:copy-of select="."/></xsl:template>
   215 <xsl:template match="@*|*|comment()" mode="merge-models"><xsl:copy-of select="."/></xsl:template>
   355 
   364 
   356 <xsl:template match="layer | package | collection | component" mode="merge-models">
   365 <xsl:template match="layer | package | collection | component" mode="merge-models">
   357 	<xsl:param name="other"/>	<!-- the downstream item of the parent's rank that contains a potential items this is merged with -->
   366 	<xsl:param name="other"/>	<!-- the downstream item of the parent's rank that contains a potential items this is merged with -->
   358 	<xsl:param name="up"/>
   367 	<xsl:param name="up"/>
   359 	<xsl:param name="down"/>
   368 	<xsl:param name="down"/>
       
   369 	<xsl:param name="replaces"/>
   360 	<xsl:variable name="this" select="."/>	<!-- current item -->
   370 	<xsl:variable name="this" select="."/>	<!-- current item -->
   361 	
   371 
   362 	<!-- match = this item in the downstream model -->	
   372 	<!-- match = this item in the downstream model -->	
   363 	<xsl:variable name="match" select="$other/*[@id=current()/@id]"/>
   373 	<xsl:variable name="match" select="$other/*[@id=current()/@id]"/>
   364 	
   374 
   365 	
   375 	<xsl:choose>
       
   376 		<xsl:when test="$replaces[.=$this/@id] or (self::component and $match)">  <!-- replace the item instead of merge -->
       
   377 			<xsl:message>Note: <xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" <xsl:choose>
       
   378 				<xsl:when test="self::component and $match">overridden in downstream sysdef</xsl:when>
       
   379 				<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>
       
   380 			</xsl:choose>
       
   381 			</xsl:message>
       
   382 			<!-- if the removed item is in the downstream doc, just copy that and ignore the upstream contents -->
       
   383 			<xsl:apply-templates mode="merge-copy-of" select="$match">
       
   384 				<xsl:with-param name="origin" select="$down"/>
       
   385 				<xsl:with-param name="root" select="$this/ancestor::systemModel"/>			
       
   386 			</xsl:apply-templates>		
       
   387 		</xsl:when>
       
   388 		<xsl:otherwise>
       
   389 			<!-- remove this if it's in the list of stuff to be replaced-->
       
   390 
   366 	<!-- prev = the previous item before the current one (no metas, only named items)-->
   391 	<!-- prev = the previous item before the current one (no metas, only named items)-->
   367 	<xsl:variable name="prev" select="preceding-sibling::*[@id][1]"/> 
   392 	<xsl:variable name="prev" select="preceding-sibling::*[@id][1]"/> 
   368 
   393 
   369 	<!-- copy all items between this and prev  that are solely in the downstream model -->	 		
   394 	<!-- copy all items between this and prev  that are solely in the downstream model -->	 		
   370 
   395 
   408 			<xsl:if test="not(@root)">
   433 			<xsl:if test="not(@root)">
   409 				<xsl:copy-of select="$up/@root"/>
   434 				<xsl:copy-of select="$up/@root"/>
   410 			</xsl:if>
   435 			</xsl:if>
   411 		</xsl:if>
   436 		</xsl:if>
   412 		
   437 		
   413 		<xsl:for-each select="$match/@*">  <!-- copy downstream attributes, only if not set on upstream -->
   438 		<xsl:for-each select="$match/@*[name()!='replace']">  <!-- copy downstream attributes, only if not set on upstream -->
   414 			<xsl:if test="not($this/@*[name()=name(current())])"><xsl:copy-of select="."/></xsl:if>
   439 			<xsl:if test="not($this/@*[name()=name(current())])"><xsl:copy-of select="."/></xsl:if>
   415 		</xsl:for-each>
   440 		</xsl:for-each>
       
   441 
       
   442 		<xsl:if test="$match/@replace"> <!-- check replace separately -->
       
   443 			<xsl:if test="not($this/ancestor::SystemDefinition//*[(self::component or self::collection or self::package or self::layer) and $match/@replace=@id])">
       
   444 				<!-- only remove replace if it's been used -->
       
   445 				<xsl:copy-of select="$match/@replace"/>
       
   446 			</xsl:if>
       
   447 		</xsl:if>
   416 		
   448 		
   417 		<xsl:choose>
   449 		<xsl:choose>
   418 			<xsl:when test="self::component">
   450 			<xsl:when test="self::component">
   419 				<!-- copy all units, metas and comments from this
   451 				<!-- copy all units, metas and comments from this
   420 					copy all metas in the merged component
   452 					copy all metas in the merged component
   433 				
   465 				
   434 				<xsl:apply-templates mode="merge-models">
   466 				<xsl:apply-templates mode="merge-models">
   435 					<xsl:with-param name="other" select="$match"/>
   467 					<xsl:with-param name="other" select="$match"/>
   436 					<xsl:with-param name="up" select="$up"/>
   468 					<xsl:with-param name="up" select="$up"/>
   437 					<xsl:with-param name="down" select="$down"/>
   469 					<xsl:with-param name="down" select="$down"/>
       
   470 					<xsl:with-param name="replaces" select="$replaces"/>
   438 				</xsl:apply-templates>
   471 				</xsl:apply-templates>
   439 				<!--  don't copy if explicitly or implicitly placed already-->
   472 				<!--  don't copy if explicitly or implicitly placed already-->
   440 				<xsl:for-each select="$match/*[not(@before) and not(following-sibling::*[@id=$this/*/@id])]">
   473 				<xsl:for-each select="$match/*[not(@before) and not(following-sibling::*[@id=$this/*/@id])]">
   441 					<xsl:if test="not($this/*[@id=current()/@id])">
   474 					<xsl:if test="not($this/*[@id=current()/@id])">
   442 						<xsl:apply-templates mode="merge-copy-of" select=".">
   475 						<xsl:apply-templates mode="merge-copy-of" select=".">
   446 					</xsl:if>
   479 					</xsl:if>
   447 				</xsl:for-each>
   480 				</xsl:for-each>
   448 			</xsl:otherwise>
   481 			</xsl:otherwise>
   449 		</xsl:choose>
   482 		</xsl:choose>
   450 	</xsl:copy>
   483 	</xsl:copy>
       
   484 
       
   485 		</xsl:otherwise>
       
   486 	</xsl:choose>
   451 	
   487 	
   452 	<xsl:if test="self::layer and not(following-sibling::layer)">
   488 	<xsl:if test="self::layer and not(following-sibling::layer)">	
   453 		<!-- for the last layer, tack on any remaining layers -->
   489 		<!-- for the last layer, tack on any remaining layers -->
   454 		<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)]">
   490 		<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)]">
   455 			<xsl:with-param name="origin" select="$down"/>
   491 			<xsl:with-param name="origin" select="$down"/>
   456 			<xsl:with-param name="root" select="$this/ancestor::systemModel"/>			
   492 			<xsl:with-param name="root" select="$this/ancestor::systemModel"/>			
   457 		</xsl:apply-templates>		
   493 		</xsl:apply-templates>		
   487 						<xsl:text>&#xa;</xsl:text>
   523 						<xsl:text>&#xa;</xsl:text>
   488 					</xsl:message>
   524 					</xsl:message>
   489 				</xsl:when>
   525 				</xsl:when>
   490 				<xsl:otherwise>
   526 				<xsl:otherwise>
   491 					<xsl:copy>
   527 					<xsl:copy>
   492 						<xsl:choose>
   528 						<xsl:call-template name="merge-copy-of-atts">
   493 							<xsl:when test="$remove-before">
   529 							<xsl:with-param name="remove-before" select="$remove-before"/>
   494 								<xsl:copy-of select="@*[name()!='before']"/>
   530 							<xsl:with-param name="root" select="$root"/>
   495 							</xsl:when>
   531 						</xsl:call-template>
   496 							<xsl:otherwise><xsl:copy-of select="@*"/></xsl:otherwise>
       
   497 						</xsl:choose>
       
   498 						<xsl:copy-of select="exslt:node-set($content)"/>
   532 						<xsl:copy-of select="exslt:node-set($content)"/>
   499 					</xsl:copy>
   533 					</xsl:copy>
   500 				</xsl:otherwise>
   534 				</xsl:otherwise>
   501 			</xsl:choose>					
   535 			</xsl:choose>					
   502 		</xsl:otherwise>
   536 		</xsl:otherwise>
   506 
   540 
   507 <xsl:template match="comment()|@*" mode="merge-copy-of">
   541 <xsl:template match="comment()|@*" mode="merge-copy-of">
   508 	<xsl:copy-of select="."/>
   542 	<xsl:copy-of select="."/>
   509 </xsl:template>
   543 </xsl:template>
   510 
   544 
       
   545 
       
   546 <xsl:template name="merge-copy-of-atts">
       
   547 	<xsl:param name="remove-before" select="0"/> <!-- set to true if any before attribute is to be removed -->
       
   548 	<xsl:param name="root"/> 	<!--the systemModel element in the upstream doc  -->
       
   549 	<xsl:choose>
       
   550 		<xsl:when test="$remove-before">
       
   551 			<xsl:copy-of select="@*[name()!='before' and name()!='replace']"/>
       
   552 		</xsl:when>
       
   553 		<xsl:otherwise><xsl:copy-of select="@*[name()!='replace']"/></xsl:otherwise>
       
   554 	</xsl:choose>
       
   555 	<xsl:if test="@replace and not($root/descendant::*[(self::component or self::collection or self::package or self::layer) and @id=current()/@replace])">
       
   556 		<!-- only include replace if it's not been used -->
       
   557 		<xsl:copy-of select="@replace"/>
       
   558 	</xsl:if>
       
   559 </xsl:template>
       
   560 
   511 <xsl:template match="component" mode="merge-copy-of">
   561 <xsl:template match="component" mode="merge-copy-of">
   512 	<xsl:param name="remove-before" select="0"/> <!-- set to true if any before attribute is to be removed -->
   562 	<xsl:param name="remove-before" select="0"/> <!-- set to true if any before attribute is to be removed -->
   513 	<xsl:param name="origin"/>	<!--the element containing the @name to use the origin-model attribute  -->
   563 	<xsl:param name="origin"/>	<!--the element containing the @name to use the origin-model attribute  -->
   514 	<xsl:param name="root"/> 	<!--the systemModel element in the upstream doc  -->
   564 	<xsl:param name="root"/> 	<!--the systemModel element in the upstream doc  -->
   515 	
   565 
   516 	<xsl:choose>
   566 	<xsl:choose>
   517 		<!-- this might slow things down, consider making optional -->
   567 		<!-- this might slow things down, consider making optional -->
   518 		<xsl:when test="$root/descendant::collection[@id!=current()/../@id]/component[@id=current()/@id]">
   568 		<xsl:when test="$root/descendant::collection[@id!=current()/../@id]/component[@id=current()/@id]">
   519 			<xsl:message>Warning: <xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" moved in downstream model. Ignoring moved <xsl:value-of select="name()"/>
   569 			<xsl:message>Warning: <xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" moved in downstream model. Ignoring moved <xsl:value-of select="name()"/>
   520 				<xsl:text>&#xa;</xsl:text>
   570 				<xsl:text>&#xa;</xsl:text>
   521 			</xsl:message>
   571 			</xsl:message>
   522 		</xsl:when>
   572 		</xsl:when>
   523 		<xsl:otherwise>
   573 		<xsl:otherwise>
   524 			<xsl:copy>
   574 			<xsl:copy>
   525 				<xsl:choose>
   575 				<xsl:call-template name="merge-copy-of-atts">
   526 					<xsl:when test="$remove-before">
   576 					<xsl:with-param name="remove-before" select="$remove-before"/>
   527 						<xsl:copy-of select="@*[name()!='before']"/>
   577 					<xsl:with-param name="root" select="$root"/>
   528 					</xsl:when>
   578 				</xsl:call-template>
   529 					<xsl:otherwise><xsl:copy-of select="@*"/></xsl:otherwise>
       
   530 				</xsl:choose>
       
   531 				<xsl:if test="not(@origin-model) and $origin/@name">
   579 				<xsl:if test="not(@origin-model) and $origin/@name">
   532 					<xsl:attribute name="origin-model">
   580 					<xsl:attribute name="origin-model">
   533 						<xsl:value-of select="$origin/@name"/>
   581 						<xsl:value-of select="$origin/@name"/>
   534 					</xsl:attribute>
   582 					</xsl:attribute>
   535 					<xsl:if test="not(@root)">
   583 					<xsl:if test="not(@root)">