Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   package org.apache.maven.plugin.changelog;
   
   /*
    * 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.
   */
  
  
  import java.io.File;
  import java.io.Writer;
  import java.util.Date;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Locale;
  import java.util.Map;
Generate a changelog report.

Version:
$Id: ChangeLogReport.java 1517983 2013-08-27 20:57:20Z krosenvold $
  
  @SuppressWarnings"ALL" )
  @Mojo( name = "changelog" )
  public class ChangeLogReport
      extends AbstractMavenReport
  {
    
A special token that represents the SCM relative path for a file. It can be used in displayFileDetailUrl.
  
      private static final String FILE_TOKEN = "%FILE%";

    
A special token that represents a Mantis/Bugzilla/JIRA/etc issue ID. It can be used in the issueLinkUrl.
 
     private static final String ISSUE_TOKEN = "%ISSUE%";

    
A special token that represents the SCM revision number. It can be used in displayChangeSetDetailUrl and displayFileRevDetailUrl.
 
     private static final String REV_TOKEN = "%REV%";

    
The number of days to use as a range, when this is not specified.
 
     private static final int DEFAULT_RANGE = 30;
 
     public static final String DEFAULT_ISSUE_ID_REGEX_PATTERN = "[a-zA-Z]{2,}-\\d+";

    
Used to specify the format to use for the dates in the headings of the report.

Since:
2.1
 
     @Parameter( property = "changelog.headingDateFormat", defaultValue = "yyyy-MM-dd" )
     private String headingDateFormat = "yyyy-MM-dd";

    
Used to specify whether to build the log using range, tag or date.
 
     @Parameter( property = "changelog.type", defaultValue = "range", required = true )
     private String type;

    
Used to specify the number of days of log entries to retrieve.
 
     @Parameter( property = "changelog.range", defaultValue = "-1" )
     private int range;

    
Used to specify the absolute date (or list of dates) to start log entries from.
 
     @Parameter
     private List<Stringdates;

    
Used to specify the tag (or list of tags) to start log entries from.
 
     @Parameter
     private List<Stringtags;

    
Used to specify the date format of the log entries that are retrieved from your SCM system.
 
     @Parameter( property = "changelog.dateFormat", defaultValue = "yyyy-MM-dd HH:mm:ss", required = true )
     private String dateFormat;

    
Input dir. Directory where the files under SCM control are located.
 
     @Parameter( property = "basedir", required = true )
     private File basedir;

    
Output file for xml document
 
     @Parameter( defaultValue = "${project.build.directory}/changelog.xml", required = true )
     private File outputXML;

    
Allows the user to make changelog regenerate the changelog.xml file for the specified time in minutes.
 
     @Parameter( property = "outputXMLExpiration", defaultValue = "60", required = true )
     private int outputXMLExpiration;

    
Comment format string used for interrogating the revision control system. Currently only used by the ClearcaseChangeLogGenerator.
 
     @Parameter( property = "changelog.commentFormat" )
     private String commentFormat;

    
The file encoding when writing non-HTML reports.
 
     @Parameter( property = "changelog.outputEncoding", defaultValue = "${project.reporting.outputEncoding}" )
     private String outputEncoding;

    
The user name (used by svn and starteam protocol).
 
     @Parameter( property = "username" )
     private String username;

    
The user password (used by svn and starteam protocol).
 
     @Parameter( property = "password" )
     private String password;

    
The private key (used by java svn).
 
     @Parameter( property = "privateKey" )
     private String privateKey;

    
The passphrase (used by java svn).
 
     @Parameter( property = "passphrase" )
     private String passphrase;

    
The url of tags base directory (used by svn protocol).
 
     @Parameter( property = "tagBase" )
     private String tagBase;

    
The URL to view the scm. Basis for external links from the generated report.
 
     @Parameter( property = "project.scm.url" )
     protected String scmUrl;

    
Skip the Changelog report generation. Most useful on the command line via "-Dchangelog.skip=true".

Since:
2.3
 
     @Parameter( property = "changelog.skip", defaultValue = "false" )
     protected boolean skip;

    
Encodes slashes in file uri. Required for some repository browsers like gitblit

Since:
2.3
 
     @Parameter( property = "encodeFileUri", defaultValue = "false" )
     protected boolean encodeFileUri;

    
List of files to include. Specified as fileset patterns of files to include in the report

Since:
2.3
 
     @Parameter
     private String[] includes;

    
List of files to include. Specified as fileset patterns of files to omit in the report

Since:
2.3
 
     @Parameter
     private String[] excludes;


    
The Maven Project Object
 
     @Component
     private MavenProject project;

    
The directory where the report will be generated
 
     @Parameter( property = "project.reporting.outputDirectory", required = true, readonly = true )
     private File outputDirectory;

    
 
     @Component
     private Renderer siteRenderer;

    
 
     @Parameter( property = "settings.offline", required = true, readonly = true )
     private boolean offline;

    
 
     @Component
     private ScmManager manager;

    
 
     @Component
     private Settings settings;

    
Allows the user to choose which scm connection to use when connecting to the scm. Can either be "connection" or "developerConnection".
 
     @Parameter( defaultValue = "connection", required = true )
     private String connectionType;

    
A template string that is used to create the URL to the file details. There is a special token that you can use in your template:
  • %FILE% - this is the path to a file

Example: http://checkstyle.cvs.sourceforge.net/checkstyle%FILE%?view=markup

Note: If you don't supply the token in your template, the path of the file will simply be appended to your template URL.

 
     @Parameter( property = "displayFileDetailUrl", defaultValue = "${project.scm.url}" )
     protected String displayFileDetailUrl;

    
A pattern used to identify 'issue tracker' IDs such as those used by JIRA, Bugzilla and alike in the SCM commit messages. Any matched patterns are replaced with issueLinkUrl URL. The default value is a JIRA-style issue identification pattern.

Note: Default value is [a-zA-Z]{2,}-\d+

Since:
2.2
 
     @Parameter( property = "issueIDRegexPattern", defaultValue = , required = true )
     private String issueIDRegexPattern;

    
The issue tracker URL used when replacing any matched issueIDRegexPattern found in the SCM commit messages. The default is URL is the codehaus JIRA URL. If %ISSUE% is found in the URL it is replaced with the matched issue ID, otherwise the matched issue ID is appended to the URL.

Since:
2.2
 
     @Parameter( property = "issueLinkUrl", defaultValue = "http://jira.codehaus.org/browse/%ISSUE%", required = true )
     private String issueLinkUrl;

    
A template string that is used to create the changeset URL.

If not defined no change set link will be created.

There is one special token that you can use in your template:

  • %REV% - this is the changeset revision

Example: http://fisheye.sourceforge.net/changelog/a-project/?cs=%REV%

Note: If you don't supply the %REV% token in your template, the revision will simply be appended to your template URL.

Since:
2.2
 
     @Parameter( property = "displayChangeSetDetailUrl" )
     protected String displayChangeSetDetailUrl;

    
A template string that is used to create the revision aware URL to the file details in a similar fashion to the displayFileDetailUrl. When a report contains both file and file revision information, as in the Change Log report, this template string can be used to create a revision aware URL to the file details.

If not defined this template string defaults to the same value as the displayFileDetailUrl and thus revision number aware links will not be used.

There are two special tokens that you can use in your template:

  • %FILE% - this is the path to a file
  • %REV% - this is the revision of the file

Example: http://fisheye.sourceforge.net/browse/a-project/%FILE%?r=%REV%

Note: If you don't supply the %FILE% token in your template, the path of the file will simply be appended to your template URL.

Since:
2.2
 
     @Parameter( property = "displayFileRevDetailUrl" )
     protected String displayFileRevDetailUrl;

    
List of developers to be shown on the report.

Since:
2.2
 
     @Parameter( property = "project.developers" )
     protected List<Developerdevelopers;

    
List of provider implementations.
 
     @Parameter
 
     // temporary field holder while generating the report
 
     // field for SCM Connection URL
     private String connection;
 
     // field used to hold a map of the developers by Id
     private HashMap<StringDeveloperdevelopersById;
 
     // field used to hold a map of the developers by Name
     private HashMap<StringDeveloperdevelopersByName;

    
The system properties to use (needed by the perforce scm provider).
 
     @Parameter
     private Properties systemProperties;
 
     private final Pattern sinkFileNamePattern = Pattern.compile"\\\\" );

    
 
     public void executeReportLocale locale )
         throws MavenReportException
     {
         //check if sources exists <-- required for parent poms
         if ( !.exists() )
         {
             doGenerateEmptyReportgetBundlelocale ), getSink() );
 
             return;
         }
 
         if (  != null )
         {
             for ( Map.Entry<StringStringentry : .entrySet() )
             {
                 String providerType = entry.getKey();
                 String providerImplementation = entry.getValue();
                 getLog().info(
                     "Change the default '" + providerType + "' provider implementation to '" + providerImplementation
                         + "'." );
                 .setScmProviderImplementationproviderTypeproviderImplementation );
             }
         }
 
 
         initializeDeveloperMaps();
 
         verifySCMTypeParams();
 
         if (  != null )
         {
             // Add all system properties configured by the user
             Iterator<?> iter = .keySet().iterator();
 
             while ( iter.hasNext() )
             {
                 String key = (Stringiter.next();
 
                 String value = .getPropertykey );
 
                 System.setPropertykeyvalue );
 
                 getLog().debug"Setting system property: " + key + '=' + value );
             }
         }
 
         doGenerateReportgetChangedSets(), getBundlelocale ), getSink() );
     }

    
Initializes any configuration parameters that have not/can not be defined or defaulted by the Mojo API.
 
     {
         if (  == null || .length() == 0 )
         {
              = ;
         }
     }

    
Creates maps of the project developers by developer Id and developer Name for quick lookups.
 
     private void initializeDeveloperMaps()
     {
          = new HashMap<StringDeveloper>();
          = new HashMap<StringDeveloper>();
 
         if (  != null )
         {
             for ( Developer developer :  )
             {
                 .putdeveloper.getId(), developer );
                 .putdeveloper.getName(), developer );
             }
         }
     }

    
populates the changedSets field by either connecting to the SCM or using an existing XML generated in a previous run of the report

 
     protected List<ChangeLogSetgetChangedSets()
         throws MavenReportException
     {
         List<ChangeLogSetchangelogList = null;
 
         if ( !.isAbsolute() )
         {
              = new File.getBasedir(), .getPath() );
         }
 
         if ( .exists() )
         {
             if (  > 0
                 &&  * 60000 > System.currentTimeMillis() - .lastModified() )
             {
                 try
                 {
                     //ReaderFactory.newReader( outputXML, getOutputEncoding() );
                     //FileInputStream fIn = new FileInputStream( outputXML );
 
                     getLog().info"Using existing changelog.xml..." );
 
                     changelogList =
                         ChangeLog.loadChangedSets( ReaderFactory.newReadergetOutputEncoding() ) );
                 }
                 catch ( FileNotFoundException e )
                 {
                     //do nothing, just regenerate
                 }
                 catch ( Exception e )
                 {
                     throw new MavenReportException"An error occurred while parsing " + .getAbsolutePath(),
                                                     e );
                 }
             }
         }
 
         if ( changelogList == null )
         {
             if (  )
             {
                 throw new MavenReportException"This report requires online mode." );
             }
 
             getLog().info"Generating changed sets xml to: " + .getAbsolutePath() );
 
             changelogList = generateChangeSetsFromSCM();
 
             try
             {
                 writeChangelogXmlchangelogList );
             }
             catch ( FileNotFoundException e )
             {
                 throw new MavenReportException"Can't create " + .getAbsolutePath(), e );
             }
             catch ( UnsupportedEncodingException e )
             {
                 throw new MavenReportException"Can't create " + .getAbsolutePath(), e );
             }
             catch ( IOException e )
             {
                 throw new MavenReportException"Can't create " + .getAbsolutePath(), e );
             }
         }
 
         return changelogList;
     }
 
     private void writeChangelogXmlList<ChangeLogSetchangelogList )
         throws IOException
     {
         StringBuilder changelogXml = new StringBuilder();
 
         changelogXml.append"<?xml version=\"1.0\" encoding=\"" ).appendgetOutputEncoding() ).append"\"?>\n" );
         changelogXml.append"<changelog>" );
 
         for ( ChangeLogSet changelogSet : changelogList )
         {
             changelogXml.append"\n  " );
 
             String changeset = changelogSet.toXMLgetOutputEncoding() );
 
             //remove xml header
             if ( changeset.startsWith"<?xml" ) )
             {
                 int idx = changeset.indexOf"?>" ) + 2;
                 changeset = changeset.substringidx );
             }
 
             changelogXml.appendchangeset );
         }
 
         changelogXml.append"\n</changelog>" );
 
         .getParentFile().mkdirs();
 
         //PrintWriter pw = new PrintWriter( new BufferedOutputStream( new FileOutputStream( outputXML ) ) );
         //pw.write( changelogXml.toString() );
         //pw.flush();
         //pw.close();
         // MCHANGELOG-86
         Writer writer = WriterFactory.newWriternew BufferedOutputStreamnew FileOutputStream ) ),
                                                  getOutputEncoding() );
         writer.writechangelogXml.toString() );
         writer.flush();
         writer.close();
     }

    
creates a ChangeLog object and then connects to the SCM to generate the changed sets

Returns:
changedlogsets generated from the SCM
Throws:
org.apache.maven.reporting.MavenReportException
 
         throws MavenReportException
     {
         try
         {
             List<ChangeLogSetchangeSets = new ArrayList<ChangeLogSet>();
 
             ScmRepository repository = getScmRepository();
 
             ScmProvider provider = .getProviderByRepositoryrepository );
 
             ChangeLogScmResult result;
 
             if ( "range".equals ) )
             {
                 result = provider.changeLogrepositorynew ScmFileSet ), nullnull, (ScmBranchnull,
                                               );
 
                 checkResultresult );
 
                 changeSets.addresult.getChangeLog() );
             }
             else if ( "tag".equals ) )
             {
                 if ( repository.getProvider().equals"svn" ) )
                 {
                     throw new MavenReportException"The type '" +  + "' isn't supported for svn." );
                 }
 
                 Iterator<StringtagsIter = .iterator();
 
                 String startTag = tagsIter.next();
                 String endTag = null;
 
                 if ( tagsIter.hasNext() )
                 {
                     while ( tagsIter.hasNext() )
                     {
                         endTag = tagsIter.next();
 
                         result = provider.changeLogrepositorynew ScmFileSet ), new ScmRevisionstartTag ),
                                                      new ScmRevisionendTag ) );
 
                         checkResultresult );
 
                         changeSets.addresult.getChangeLog() );
 
                         startTag = endTag;
                     }
                 }
                 else
                 {
                     result = provider.changeLogrepositorynew ScmFileSet ), new ScmRevisionstartTag ),
                                                  new ScmRevisionendTag ) );
 
                     checkResultresult );
 
                     changeSets.addresult.getChangeLog() );
                 }
             }
             else if ( "date".equals ) )
             {
                 Iterator<StringdateIter = .iterator();
 
                 String startDate = dateIter.next();
                 String endDate = null;
 
                 if ( dateIter.hasNext() )
                 {
                     while ( dateIter.hasNext() )
                     {
                         endDate = dateIter.next();
 
                         result = provider.changeLogrepositorynew ScmFileSet ), parseDatestartDate ),
                                                      parseDateendDate ), 0, (ScmBranchnull );
 
                         checkResultresult );
 
                         changeSets.addresult.getChangeLog() );
 
                         startDate = endDate;
                     }
                 }
                 else
                 {
                     result = provider.changeLogrepositorynew ScmFileSet ), parseDatestartDate ),
                                                  parseDateendDate ), 0, (ScmBranchnull );
 
                     checkResultresult );
 
                     changeSets.addresult.getChangeLog() );
                 }
             }
             else
             {
                 throw new MavenReportException"The type '" +  + "' isn't supported." );
             }
             filterchangeSets );
             return changeSets;
 
         }
         catch ( ScmException e )
         {
             throw new MavenReportException"Cannot run changelog command : "e );
         }
         catch ( MojoExecutionException e )
         {
             throw new MavenReportException"An error has occurred during changelog command : "e );
         }
     }

    
filters out unwanted files from the changesets
 
     private void filterList<ChangeLogSetchangeSets )
     {
         List<Patterninclude = compilePatterns );
         List<Patternexclude = compilePatterns );
         if (  == null &&  == null )
         {
             return;
         }
         for ( ChangeLogSet changeLogSet : changeSets )
         {
             List<ChangeSetset = changeLogSet.getChangeSets();
             filtersetincludeexclude );
         }
 
     }
 
     private List<PatterncompilePatternsString[] patternArray )
     {
         if ( patternArray == null )
         {
             return new ArrayList<Pattern>();
         }
         List<Patternpatterns = new ArrayList<Pattern>( patternArray.length );
         for ( String string : patternArray )
         {
             //replaces * with [/\]* (everything but file seperators)
             //replaces ** with .*
             //quotes the rest of the string
             string = "\\Q" + string + "\\E";
             string = string.replace"**""\\E.?REPLACEMENT?\\Q" );
             string = string.replace"*""\\E[^/\\\\]?REPLACEMENT?\\Q" );
             string = string.replace"?REPLACEMENT?""*" );
             string = string.replace"\\Q\\E""" );
             patterns.add( Pattern.compilestring ) );
         }
         return patterns;
     }
 
     private void filterList<ChangeSetsetsList<PatternincludesList<Patternexcludes )
     {
         Iterator<ChangeSetit = sets.iterator();
         while ( it.hasNext() )
         {
             ChangeSet changeSet = it.next();
             List<ChangeFilefiles = changeSet.getFiles();
             Iterator<ChangeFileiterator = files.iterator();
             while ( iterator.hasNext() )
             {
                 ChangeFile changeFile = iterator.next();
                 String name = changeFile.getName();
                 if ( !isIncludedincludesname ) || isExcludedexcludesname ) )
                 {
                     iterator.remove();
                 }
             }
             if ( files.isEmpty() )
             {
                 it.remove();
             }
         }
     }
 
     private boolean isExcludedList<PatternexcludesString name )
     {
         if ( excludes == null || excludes.isEmpty() )
         {
             return false;
         }
         for ( Pattern pattern : excludes )
         {
             if ( pattern.matchername ).matches() )
             {
                 return true;
             }
         }
         return false;
     }
 
     private boolean isIncludedList<PatternincludesString name )
     {
         if ( includes == null || includes.isEmpty() )
         {
             return true;
         }
         for ( Pattern pattern : includes )
         {
             if ( pattern.matchername ).matches() )
             {
                 return true;
             }
         }
         return false;
     }

    
Converts the localized date string pattern to date object.

Returns:
A date
 
     private Date parseDateString date )
         throws MojoExecutionException
     {
         if ( date == null || date.trim().length() == 0 )
         {
             return null;
         }
 
         SimpleDateFormat formatter = new SimpleDateFormat"yyyy-MM-dd" );
 
         try
         {
             return formatter.parsedate );
         }
         catch ( ParseException e )
         {
             throw new MojoExecutionException"Please use this date pattern: " + formatter.toLocalizedPattern(), e );
         }
     }
 
     public ScmRepository getScmRepository()
         throws ScmException
     {
         ScmRepository repository;
 
         try
         {
             repository = .makeScmRepositorygetConnection() );
 
             ScmProviderRepository providerRepo = repository.getProviderRepository();
 
             if ( !StringUtils.isEmpty ) )
             {
                 providerRepo.setUser );
             }
 
             if ( !StringUtils.isEmpty ) )
             {
                 providerRepo.setPassword );
             }
 
             if ( repository.getProviderRepository() instanceof ScmProviderRepositoryWithHost )
             {
                 ScmProviderRepositoryWithHost repo = (ScmProviderRepositoryWithHostrepository.getProviderRepository();
 
                 loadInfosFromSettingsrepo );
 
                 if ( !StringUtils.isEmpty ) )
                 {
                     repo.setUser );
                 }
 
                 if ( !StringUtils.isEmpty ) )
                 {
                     repo.setPassword );
                 }
 
                 if ( !StringUtils.isEmpty ) )
                 {
                     repo.setPrivateKey );
                 }
 
                 if ( !StringUtils.isEmpty ) )
                 {
                     repo.setPassphrase );
                 }
             }
 
             if ( !StringUtils.isEmpty ) && repository.getProvider().equals"svn" ) )
             {
                 SvnScmProviderRepository svnRepo = (SvnScmProviderRepositoryrepository.getProviderRepository();
 
                 svnRepo.setTagBase );
             }
         }
         catch ( Exception e )
         {
             throw new ScmException"Can't load the scm provider."e );
         }
 
         return repository;
     }

    
Load username password from settings if user has not set them in JVM properties

Parameters:
repo
 
     private void loadInfosFromSettingsScmProviderRepositoryWithHost repo )
     {
         if (  == null ||  == null )
         {
             String host = repo.getHost();
 
             int port = repo.getPort();
 
             if ( port > 0 )
             {
                 host += ":" + port;
             }
 
             Server server = this..getServerhost );
 
             if ( server != null )
             {
                 if (  == null )
                 {
                      = this..getServerhost ).getUsername();
                 }
 
                 if (  == null )
                 {
                      = this..getServerhost ).getPassword();
                 }
 
                 if (  == null )
                 {
                      = this..getServerhost ).getPrivateKey();
                 }
 
                 if (  == null )
                 {
                      = this..getServerhost ).getPassphrase();
                 }
             }
         }
     }
 
     public void checkResultScmResult result )
         throws MojoExecutionException
     {
         if ( !result.isSuccess() )
         {
             getLog().error"Provider message:" );
 
             getLog().errorresult.getProviderMessage() == null ? "" : result.getProviderMessage() );
 
             getLog().error"Command output:" );
 
             getLog().errorresult.getCommandOutput() == null ? "" : result.getCommandOutput() );
 
             throw new MojoExecutionException"Command failed." );
         }
     }

    
used to retrieve the SCM connection string

Returns:
the url string used to connect to the SCM
Throws:
org.apache.maven.reporting.MavenReportException when there is insufficient information to retrieve the SCM connection string
 
     protected String getConnection()
         throws MavenReportException
     {
         if ( this. != null )
        {
            return ;
        }
        if ( .getScm() == null )
        {
            throw new MavenReportException"SCM Connection is not set." );
        }
        String scmConnection = .getScm().getConnection();
        if ( StringUtils.isNotEmptyscmConnection ) && "connection".equals.toLowerCase() ) )
        {
             = scmConnection;
        }
        String scmDeveloper = .getScm().getDeveloperConnection();
        if ( StringUtils.isNotEmptyscmDeveloper ) && "developerconnection".equals.toLowerCase() ) )
        {
             = scmDeveloper;
        }
        if ( StringUtils.isEmpty ) )
        {
            throw new MavenReportException"SCM Connection is not set." );
        }
        return ;
    }

    
checks whether there are enough configuration parameters to generate the report

Throws:
org.apache.maven.reporting.MavenReportException when there is insufficient paramters to generate the report
    private void verifySCMTypeParams()
        throws MavenReportException
    {
        if ( "range".equals ) )
        {
            if (  == -1 )
            {
                 = ;
            }
        }
        else if ( "date".equals ) )
        {
            if (  == null )
            {
                throw new MavenReportException"The dates parameter is required when type=\"date\"."
                                                    + " The value should be the absolute date for the start of the log." );
            }
        }
        else if ( "tag".equals ) )
        {
            if (  == null )
            {
                throw new MavenReportException"The tags parameter is required when type=\"tag\"." );
            }
        }
        else
        {
            throw new MavenReportException"The type parameter has an invalid value: " + 
                                                + ".  The value should be \"range\", \"date\", or \"tag\"." );
        }
    }

    
generates an empty report in case there are no sources to generate a report with

Parameters:
bundle the resource bundle to retrieve report phrases from
sink the report formatting tool
    protected void doGenerateEmptyReportResourceBundle bundleSink sink )
    {
        sink.head();
        sink.title();
        sink.textbundle.getString"report.changelog.header" ) );
        sink.title_();
        sink.head_();
        sink.body();
        sink.section1();
        sink.sectionTitle1();
        sink.textbundle.getString"report.changelog.mainTitle" ) );
        sink.sectionTitle1_();
        sink.paragraph();
        sink.textbundle.getString"report.changelog.nosources" ) );
        sink.paragraph_();
        sink.section1_();
        sink.body_();
        sink.flush();
        sink.close();
    }

    
method that generates the report for this mojo. This method is overridden by dev-activity and file-activity mojo

Parameters:
changeLogSets changed sets to generate the report from
bundle the resource bundle to retrieve report phrases from
sink the report formatting tool
    protected void doGenerateReportList<ChangeLogSetchangeLogSetsResourceBundle bundleSink sink )
    {
        sink.head();
        sink.title();
        sink.textbundle.getString"report.changelog.header" ) );
        sink.title_();
        sink.head_();
        sink.body();
        sink.section1();
        sink.sectionTitle1();
        sink.textbundle.getString"report.changelog.mainTitle" ) );
        sink.sectionTitle1_();
        // Summary section
        doSummarySectionchangeLogSetsbundlesink );
        for ( ChangeLogSet changeLogSet : changeLogSets )
        {
            doChangedSetchangeLogSetbundlesink );
        }
        sink.section1_();
        sink.body_();
        sink.flush();
        sink.close();
    }

    
generates the report summary section of the report

Parameters:
changeLogSets changed sets to generate the report from
bundle the resource bundle to retrieve report phrases from
sink the report formatting tool
    private void doSummarySectionList<ChangeLogSetchangeLogSetsResourceBundle bundleSink sink )
    {
        sink.paragraph();
        sink.textbundle.getString"report.changelog.ChangedSetsTotal" ) );
        sink.text": " + changeLogSets.size() );
        sink.paragraph_();
    }

    
generates a section of the report referring to a changeset

Parameters:
set the current ChangeSet to generate this section of the report
bundle the resource bundle to retrieve report phrases from
sink the report formatting tool
    private void doChangedSetChangeLogSet setResourceBundle bundleSink sink )
    {
        sink.section2();
        doChangeSetTitlesetbundlesink );
        doSummarysetbundlesink );
        doChangedSetTableset.getChangeSets(), bundlesink );
        sink.section2_();
    }

    
Generate the title for the report.

Parameters:
set change set to generate the report from
bundle the resource bundle to retrieve report phrases from
sink the report formatting tool
    protected void doChangeSetTitleChangeLogSet setResourceBundle bundleSink sink )
    {
        sink.sectionTitle2();
        SimpleDateFormat headingDateFormater = new SimpleDateFormat );
        if ( "tag".equals ) )
        {
            if ( set.getStartVersion() == null || set.getStartVersion().getName() == null )
            {
                sink.textbundle.getString"report.SetTagCreation" ) );
                if ( set.getEndVersion() != null && set.getEndVersion().getName() != null )
                {
                    sink.text' ' + bundle.getString"report.SetTagUntil" ) + " '" + set.getEndVersion() + '\'' );
                }
            }
            else if ( set.getEndVersion() == null || set.getEndVersion().getName() == null )
            {
                sink.textbundle.getString"report.SetTagSince" ) );
                sink.text" '" + set.getStartVersion() + '\'' );
            }
            else
            {
                sink.textbundle.getString"report.SetTagBetween" ) );
                sink.text(
                    " '" + set.getStartVersion() + "' " + bundle.getString"report.And" ) + " '" + set.getEndVersion()
                        + '\'' );
            }
        }
        else if ( set.getStartDate() == null )
        {
            sink.textbundle.getString"report.SetRangeUnknown" ) );
        }
        else if ( set.getEndDate() == null )
        {
            sink.textbundle.getString"report.SetRangeSince" ) );
            sink.text' ' + headingDateFormater.formatset.getStartDate() ) );
        }
        else
        {
            sink.textbundle.getString"report.SetRangeBetween" ) );
            sink.text(
                ' ' + headingDateFormater.formatset.getStartDate() ) + ' ' + bundle.getString"report.And" ) + ' '
                    + headingDateFormater.formatset.getEndDate() ) );
        }
        sink.sectionTitle2_();
    }

    
Generate the summary section of the report.

Parameters:
set change set to generate the report from
bundle the resource bundle to retrieve report phrases from
sink the report formatting tool
    protected void doSummaryChangeLogSet setResourceBundle bundleSink sink )
    {
        sink.paragraph();
        sink.textbundle.getString"report.TotalCommits" ) );
        sink.text": " + set.getChangeSets().size() );
        sink.lineBreak();
        sink.textbundle.getString"report.changelog.FilesChanged" ) );
        sink.text": " + countFilesChangedset.getChangeSets() ) );
        sink.paragraph_();
    }

    
counts the number of files that were changed in the specified SCM

Parameters:
entries a collection of SCM changes
Returns:
number of files changed for the changedsets
    protected long countFilesChangedCollection<ChangeSetentries )
    {
        if ( entries == null )
        {
            return 0;
        }
        if ( entries.isEmpty() )
        {
            return 0;
        }
        HashMap<StringList<ChangeFile>> fileList = new HashMap<StringList<ChangeFile>>();
        for ( ChangeSet entry : entries )
        {
            for ( ChangeFile file : entry.getFiles() )
            {
                String name = file.getName();
                List<ChangeFilelist = fileList.getname );
                if ( list != null )
                {
                    list.addfile );
                }
                else
                {
                    list = new LinkedList<ChangeFile>();
                    list.addfile );
                    fileList.putnamelist );
                }
            }
        }
        return fileList.size();
    }

    
generates the report table showing the SCM log entries

Parameters:
entries a list of change log entries to generate the report from
bundle the resource bundle to retrieve report phrases from
sink the report formatting tool
    private void doChangedSetTableCollection<ChangeSetentriesResourceBundle bundleSink sink )
    {
        sink.table();
        sink.tableRow();
        sink.tableHeaderCell();
        sink.textbundle.getString"report.changelog.timestamp" ) );
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        sink.textbundle.getString"report.changelog.author" ) );
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        sink.textbundle.getString"report.changelog.details" ) );
        sink.tableHeaderCell_();
        sink.tableRow_();
        initReportUrls();
        List<ChangeSetsortedEntries = new ArrayList<ChangeSet>( entries );
        Collections.sortsortedEntriesnew Comparator<ChangeSet>()
        {
            public int compareChangeSet changeSet0ChangeSet changeSet1 )
            {
                return changeSet1.getDate().compareTochangeSet0.getDate() );
            }
        } );
        for ( ChangeSet entry : sortedEntries )
        {
            doChangedSetDetailentrysink );
        }
        sink.table_();
    }

    
reports on the details of an SCM entry log

Parameters:
entry an SCM entry to generate the report from
sink the report formatting tool
    private void doChangedSetDetailChangeSet entrySink sink )
    {
        sink.tableRow();
        sink.tableCell();
        sink.textentry.getDateFormatted() + ' ' + entry.getTimeFormatted() );
        sink.tableCell_();
        sink.tableCell();
        sinkAuthorDetailssinkentry.getAuthor() );
        sink.tableCell_();
        sink.tableCell();
        //doRevision( entry.getFiles(), bundle, sink );
        doChangedFilesentry.getFiles(), sink );
        sink.lineBreak();
        StringReader sr = new StringReaderentry.getComment() );
        BufferedReader br = new BufferedReadersr );
        String line;
        try
        {
            if ( (  != null && .length() > 0 ) && (  != null
                && .length() > 0 ) )
            {
                Pattern pattern = Pattern.compile );
                line = br.readLine();
                while ( line != null )
                {
                    sinkIssueLinksinklinepattern );
                    line = br.readLine();
                    if ( line != null )
                    {
                        sink.lineBreak();
                    }
                }
            }
            else
            {
                line = br.