## 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
##
##  https://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.
##
${project.name} ${version}
Release Notes

The ${developmentTeam} is pleased to announce the release of ${project.name} ${version}.

$introduction.replaceAll("(?<!\015)\012", "
").replaceAll("(?m)^ +","")

## The available variables are described here:
## http://maven.apache.org/plugins/maven-changes-plugin/examples/using-a-custom-announcement-template.html
##
## Hack to improve layout: replace all pairs of spaces with a single new-line
$release.description.replaceAll("  ", "
")

## set up indent sizes. Only change indent1
#set($props=${project.properties})
#set($jiralen=$props.get("commons.jira.id").length())
## indent1 =   POOL-nnnn:
#set($blanklen=$jiralen+6)## +6 for "-nnnn:"
## must be at least as long as the longest JIRA id
#set($blanks="                                  ")
#set($indent1=$blanks.substring(0,$blanklen))
## indent2 allows for issue wrapper
#set($indent2="$indent1   ")
##
#macro ( processaction )
## Use replaceAll to fix up LF-only line ends on Windows.
#set($action=$actionItem.getAction().replaceAll("\n","
"))
## Replace &lt; with < so can embed tag markup
#set($action=$action.replaceAll("&lt;","<"))
## use an empty date to mean don't format the entry
## TODO how to enable leading spaces without compromising html report
## unfortunately leading spaces are trimmed even from CDATA sections
#if ($actionItem.getDate() && $actionItem.getDate().length()==0)
$action
#else
## Fix up indentation for multi-line action descriptions
#set($action=$action.replaceAll("(?m)^  +",$indent2))
#if ($actionItem.getIssue())
#set($issue="$actionItem.getIssue():")
## Pad shorter issue numbers
#if ($issue.length() < $indent1.length())#set ($issue="$issue ")#end
#if ($issue.length() < $indent1.length())#set ($issue="$issue ")#end
#if ($issue.length() < $indent1.length())#set ($issue="$issue ")#end
#else
#set($issue=$indent1)
#end
#if ($actionItem.getDueTo())
#set($dueto=" Thanks to $actionItem.getDueTo().")
#else
#set($dueto="")
#end
o $issue ${action}$dueto
#end
#set($action="")
#set($issue="")
#set($dueto="")
#end
##
#if ($release.getActions().size() == 0)
No changes defined in this version.
#else
Changes in this version include:

#if ($release.getActions('add').size() !=0)
New features:
#foreach($actionItem in $release.getActions('add'))
#processaction()
#end 

#end
##
#if ($release.getActions('fix').size() !=0)
Fixed Bugs:
#foreach($actionItem in $release.getActions('fix'))
#processaction()
#end

#end
##
#if ($release.getActions('update').size() !=0)
Changes:
#foreach($actionItem in $release.getActions('update'))
#processaction()
#end

#end
##
#if ($release.getActions('remove').size() !=0)
Removed:
#foreach($actionItem in $release.getActions('remove'))
#processaction()
#end
#end
## End of main loop
#end

Historical list of changes: ${project.url}/changes.html

For complete information on ${project.name}, including instructions on how to submit bug reports,
patches, or suggestions for improvement, see the ${project.name} website:

${project.url}

Download it from ${project.url}/download_beanutils.cgi

Have fun!
-Apache Commons BeanUtils team

-----------------------------------------------------------------------------
