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> |
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> |