## 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.
#set($h1='#')
#set($h2='##')
#set($h3='###')
#set($relVersion=$announceParameters.releaseVersion)
#set($relCount=$announceParameters.releaseCount)
#macro(formatAction $item)
## Use replaceAll to fix up LF-only line ends on Windows.
## Also replace < and > with entity versions to avoid HTML being misinterpreted.
    #set($action=$item.action.replaceAll("\n","
").replaceAll("<", "&lt;").replaceAll(">", "&gt;"))
    #if($item.issue)
        #set($issue = $item.issue)
        #set($url = "https://issues.apache.org/jira/browse/$issue")
    #else
        #set($issue = "")
    #end
* #if($issue)[$issue]($url):#end

    ${action}#if($item.dueTo) Thanks to ${item.dueTo}.#end

#end
## -----------------------------------------
$h1 Apache Log4j ${relVersion} Release Notes

The ${developmentTeam} is pleased to announce the Log4j Audit ${relVersion} release!

Apache Log4j Audit is a framework for performing

## Hack to improve layout: replace all pairs of spaces with a single new-line
$h2 $release.description.replaceAll("  ", "
")

#if ($release.actions.size() == 0)
No changes defined in this version.
#else
Changes in this version include:

    #if ($release.getActions('add').size() !=0)
        $h3 New Features
        #foreach($actionItem in $release.getActions('add'))
            #formatAction($actionItem)
        #end
    #end

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

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

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

Apache Log4j Audit ${relVersion} requires a minimum of Java 8 to build and run.

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

${project.url}