view bug-list.xsl @ 3:36ae3ec94442

xslt: prepare taskjuggler tasks structure
author cin
date Mon, 24 Aug 2015 10:16:41 +0300
parents d1400de5832b
children f8f966388b68
line wrap: on
line source

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common">
	<xsl:output method="xml" indent="yes" />
	<xsl:variable name="bugs" select="/bugzilla/bug" />
	<xsl:key name="bugid" match="/bugzilla/bug" use="string(bug_id)" />
	<xsl:variable name="roots"
		select="$bugs[not(blocked[key('bugid',.)])]" />

	<!-- BUILD BUG TREE -->
	<xsl:variable name="tree">
		<xsl:apply-templates mode="tree" select="$roots" />
	</xsl:variable>

	<xsl:template match="bug" mode="tree">
		<xsl:element name="bug">
			<xsl:attribute name="id"><xsl:value-of select="bug_id" /></xsl:attribute>
			<xsl:if test="component = 'product' or not(number(estimated_time))">
				<xsl:attribute name="product"><xsl:value-of select="boolean(1)" /></xsl:attribute>
			</xsl:if>
			<xsl:for-each select="dependson">
				<xsl:apply-templates mode="tree" select="key('bugid', .)" />
			</xsl:for-each>
		</xsl:element>
	</xsl:template>

	<!-- CALCULATE RELATIONS -->
	<xsl:variable name="relations">
		<xsl:apply-templates select="$bugs" mode="relations" />
	</xsl:variable>

	<xsl:template match="bug" mode="relations">
		<xsl:variable name="bugid" select="string(bug_id)" />
		<bug id="{$bugid}">
			<xsl:apply-templates select="exsl:node-set($tree)//bug[@id = $bugid]"
				mode="traverse-relations">
			</xsl:apply-templates>
		</bug>
	</xsl:template>

	<xsl:template match="bug" mode="traverse-relations">
		<xsl:variable name="bugid" select="@id" />
		<xsl:variable name="path" select="ancestor::bug" />
		<xsl:variable name="level" select="count($path)" />
		<xsl:for-each select="$path[@product]">
			<xsl:variable name="pos" select="position()" />
			<xsl:variable name="rank" select="$level - position()" />
			<rel container="{@id}" rank="{$rank}" level="{$level}">
				<xsl:for-each select="$path[position() >= $pos]">
					<bug id="{@id}" />
				</xsl:for-each>
			</rel>
		</xsl:for-each>
	</xsl:template>

	<!-- CALCULATE STRUCTURE -->

	<xsl:variable name="parents">
		<xsl:apply-templates select="exsl:node-set($relations)"
			mode="parents" />
	</xsl:variable>

	<xsl:template match="bug" mode="parents">
		<xsl:variable name="parent"
			select="rel[ not(../rel/@rank &lt; @rank) ][1]" />
		<bug id="{@id}" parent="{$parent/@container}" rank="{$parent/@rank}"
			level="{$parent/@level}" />
	</xsl:template>

	<xsl:variable name="structure">
		<xsl:apply-templates select="$roots" mode="structure" />
	</xsl:variable>

	<xsl:template match="bug" mode="structure">
		<xsl:variable name="id" select="string(bug_id)" />
		<xsl:variable name="self" select="." />
		<bug id="{$id}">
			<xsl:for-each select="exsl:node-set($parents)/bug[@parent = $id]">
				<xsl:variable name="child" select="@id" />
				<xsl:apply-templates select="$bugs[bug_id = $child]"
					mode="structure" />
			</xsl:for-each>
			<xsl:variable name="dependencies"
				select="dependson[not(text() = exsl:node-set($parents)/bug[@parent = $id]/@id)]" />
			<xsl:if test="$dependencies">
				<depends>
					<xsl:for-each select="$dependencies">
						<bug id="{.}" />
					</xsl:for-each>
				</depends>
			</xsl:if>
		</bug>
	</xsl:template>

	<!-- -->
	<xsl:template match="/">
		<root>
			<xsl:copy-of select="$tree" />
			<xsl:copy-of select="$relations" />
			<xsl:copy-of select="$parents" />
			<xsl:copy-of select="$structure" />
		</root>
	</xsl:template>

	<xsl:template match="bug">
		<xsl:value-of select="bug_id" />
		<xsl:text>&#xa;</xsl:text>
	</xsl:template>

	<xsl:template match="bug[component = 'product']">
		<xsl:value-of select="bug_id" />
		<xsl:text>:&#xa;</xsl:text>
		<xsl:for-each select="dependson">
			<xsl:apply-templates select="key('bugid', .)" />
		</xsl:for-each>
		<xsl:text>---END---&#xa;</xsl:text>
	</xsl:template>

	<xsl:template match="text()" />

	<xsl:template name="bug-template">
		<xsl:param name="indent" select="0" />
		<xsl:variable name="isOrganizing" select="component = 'product'"></xsl:variable>

		<xsl:call-template name="start-task">
			<xsl:with-param name="indent" select="$indent" />
		</xsl:call-template>

		<xsl:if test="$isOrganizing">

		</xsl:if>

		<xsl:choose>
			<xsl:when test="$isOrganizing">
				<xsl:for-each select="dependson">
					<xsl:for-each select="key('bugs-key', .)">
						<xsl:call-template name="bug-template">
							<xsl:with-param name="indent" select="$indent + 1" />
						</xsl:call-template>
					</xsl:for-each>
				</xsl:for-each>
			</xsl:when>
			<xsl:otherwise>
				<xsl:if test="number(estimated_time)">
					<xsl:call-template name="begin-line">
						<xsl:with-param name="indent" select="$indent + 1" />
					</xsl:call-template>
					<xsl:value-of select="concat('effort ', estimated_time, 'h')" />
					<xsl:call-template name="end-line" />
				</xsl:if>
			</xsl:otherwise>
		</xsl:choose>

		<xsl:call-template name="end-task">
			<xsl:with-param name="indent" select="$indent" />
		</xsl:call-template>
	</xsl:template>

	<xsl:template name="make-bug-id">
		<xsl:param name="id"></xsl:param>
		<xsl:value-of select="concat('bug', $id)"></xsl:value-of>
	</xsl:template>

	<xsl:template name="start-task">
		<xsl:param name="indent" />
		<xsl:call-template name="begin-line">
			<xsl:with-param name="indent" select="$indent" />
		</xsl:call-template>
		<xsl:text>task </xsl:text>
		<xsl:call-template name="make-bug-id">
			<xsl:with-param name="id" select="bug_id" />
		</xsl:call-template>
		<xsl:value-of select="concat(' &quot;',short_desc,'&quot; {')" />
		<xsl:call-template name="end-line" />
	</xsl:template>

	<xsl:template name="end-task">
		<xsl:param name="indent" />
		<xsl:call-template name="begin-line">
			<xsl:with-param name="indent" select="$indent" />
		</xsl:call-template>
		<xsl:text>}</xsl:text>
		<xsl:call-template name="end-line" />
	</xsl:template>

	<xsl:template name="begin-line">
		<xsl:param name="indent" />
		<xsl:if test="number($indent) > 0">
			<xsl:text>    </xsl:text>
			<xsl:call-template name="begin-line">
				<xsl:with-param name="indent" select="$indent - 1" />
			</xsl:call-template>
		</xsl:if>
	</xsl:template>
	<xsl:template name="end-line">
		<xsl:text>&#xa;</xsl:text>
	</xsl:template>
</xsl:stylesheet>