<?xml version="1.0"?>

<!--
 * ========================================================================
 * 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * ========================================================================
-->

<!--
 Customized version of maven annnouncement plugin style sheet to create
 release notes for commons-pool.   
-->
    
<jsl:stylesheet
    select="$doc"
    xmlns:j="jelly:core"
    xmlns:jsl="jelly:jsl"
    xmlns:x="jelly:xml"
    xmlns:u="jelly:util"
    xmlns:maven="jelly:maven"
    xmlns="dummy" trim="true">

  <!-- This stylesheet expects the versionVariable to be defined before calling it -->
  <jsl:template match="document/body/release">

    <x:set var="version" select="string(@version)"/>
    <x:set var="description" select="string(@description)"/>
    <j:if test="${versionVariable.equals(version)}">
      <j:whitespace trim="false">
                         Commons POOL Version ${version} 
                                 RELEASE NOTES
      </j:whitespace>

<j:useBean var="formatter" class="org.apache.maven.announcement.Formatter"/>

<j:set var="header" trim="false" value="${description}"/>

<j:forEach var="line" items="${formatter.format(header,78)}">
<j:whitespace trim="false">
${line}</j:whitespace>
</j:forEach>
      <j:whitespace trim="false">
      
                             SUMMARY OF CHANGES</j:whitespace>

      <x:set var="actions" select="action[@type='add']" sort="@type" />
        <j:if test="${!empty(actions)}">
<j:whitespace trim="false">

  New Features:
</j:whitespace>
        <j:forEach var="action" items="${actions}">
          <x:set var="item" select="."/><jsl:applyTemplates select="$action"/>
        </j:forEach>
      </j:if>
      <x:set var="actions" select="action[@type='fix']" sort="@type" />
        <j:if test="${!empty(actions)}">
<j:whitespace trim="false">

BUG FIXES
</j:whitespace>
        <j:forEach var="action" items="${actions}">
          <x:set var="item" select="."/><jsl:applyTemplates select="$action"/>
        </j:forEach>
      </j:if>
      <x:set var="actions" select="action[@type='update']" sort="@type" />
        <j:if test="${!empty(actions)}">
<j:whitespace trim="false">

BEHAVIOR CHANGES
</j:whitespace>
        <j:forEach var="action" items="${actions}">
          <x:set var="item" select="."/><jsl:applyTemplates select="$action"/>
        </j:forEach>
      </j:if>

For more information on Commons Pool, see
${pom.url}
      <x:set var="actions" select="action[@type='remove']" sort="@type" />
        <j:if test="${!empty(actions)}">
<j:whitespace trim="false">

  Removed features:
</j:whitespace>
        <j:forEach var="action" items="${actions}">
          <x:set var="item" select="."/><jsl:applyTemplates select="$action"/>
        </j:forEach>
      </j:if>
      <j:whitespace trim="false"> 

      </j:whitespace>
    </j:if>
  </jsl:template>
  
  <jsl:template match="action" trim="true">
    <x:set var="body" select="string(.)"/>
    <j:set var="counter" value=""/>
        
    <j:set var="issue"><x:expr select="@issue"/></j:set>
    <j:set var="dueto"><x:expr select="@due-to"/></j:set>
        
    <j:set var="text" trim="true">
      ${body}
      <j:if test="${issue != ''}"><j:whitespace> Issue: ${issue}.</j:whitespace></j:if>
      <j:if test="${dueto != ''}"><j:whitespace> Thanks to ${dueto}.</j:whitespace></j:if>
    </j:set>
        
    <j:forEach var="line" items="${formatter.format(text,75)}">
      <j:choose>
        <j:when test="${counter.length() == '0'}">
          <j:whitespace trim="false">
o ${line}</j:whitespace>
        </j:when>
        <j:otherwise>
          <j:whitespace trim="false">
  ${line}</j:whitespace>
        </j:otherwise>
      </j:choose>
      <j:set var="counter" value="${counter}X"/>
    </j:forEach>
  </jsl:template>
  <jsl:template match="@*"/>
  <jsl:template match="text()"/>
</jsl:stylesheet>
