You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by br...@apache.org on 2006/03/22 07:02:55 UTC
svn commit: r387745 [1/2] - in
/maven/sandbox/plugins/changelog-maven-plugin: ./ src/ src/main/
src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/maven/ src/main/java/org/apache/maven/changelog/
src/main/resources/ sr...
Author: brett
Date: Tue Mar 21 22:02:52 2006
New Revision: 387745
URL: http://svn.apache.org/viewcvs?rev=387745&view=rev
Log:
Import of changelog-maven-plugin code from https://svn.codehaus.org/mojo/trunk/mojo/changelog-maven-plugin/, r1708
Code authored by people that have an Apache CLA on file:
* Edwin Punzalan (Initial contribution derived from code under https://svn.apache.org/repos/asf/maven/maven-1/plugins/trunk/changelog)
* Trygve Laugstol
* Brett Porter
* Emmanuel Venisse
* Brian Fox
Contains code donated under the Apache License 2.0 by:
* Julian Wood <wo...@ucalgary.ca> - r973, handle date and time being non-sequentially parsed by the handler
All code is under the Apache License v2.0
Added:
maven/sandbox/plugins/changelog-maven-plugin/
maven/sandbox/plugins/changelog-maven-plugin/pom.xml (with props)
maven/sandbox/plugins/changelog-maven-plugin/src/
maven/sandbox/plugins/changelog-maven-plugin/src/main/
maven/sandbox/plugins/changelog-maven-plugin/src/main/java/
maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/
maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/
maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/
maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/
maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLog.java (with props)
maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLogHandler.java (with props)
maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLogReport.java (with props)
maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/DeveloperActivityReport.java (with props)
maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/FileActivityComparator.java (with props)
maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/FileActivityReport.java (with props)
maven/sandbox/plugins/changelog-maven-plugin/src/main/resources/
maven/sandbox/plugins/changelog-maven-plugin/src/main/resources/scm-activity.properties (with props)
maven/sandbox/plugins/changelog-maven-plugin/src/site/
maven/sandbox/plugins/changelog-maven-plugin/src/site/apt/
maven/sandbox/plugins/changelog-maven-plugin/src/site/apt/howto.apt (with props)
maven/sandbox/plugins/changelog-maven-plugin/src/site/resources/
maven/sandbox/plugins/changelog-maven-plugin/src/site/resources/sample-changelog.html (with props)
maven/sandbox/plugins/changelog-maven-plugin/src/site/resources/sample-dev-activity.html (with props)
maven/sandbox/plugins/changelog-maven-plugin/src/site/resources/sample-file-activity.html (with props)
maven/sandbox/plugins/changelog-maven-plugin/src/site/site.xml (with props)
Added: maven/sandbox/plugins/changelog-maven-plugin/pom.xml
URL: http://svn.apache.org/viewcvs/maven/sandbox/plugins/changelog-maven-plugin/pom.xml?rev=387745&view=auto
==============================================================================
--- maven/sandbox/plugins/changelog-maven-plugin/pom.xml (added)
+++ maven/sandbox/plugins/changelog-maven-plugin/pom.xml Tue Mar 21 22:02:52 2006
@@ -0,0 +1,176 @@
+<project>
+ <parent>
+ <artifactId>mojo</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <version>7</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>changelog-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <name>Maven Changelog Plug-in</name>
+ <version>2.0-beta-2-SNAPSHOT</version>
+ <description>Produce SCM changelog reports.</description>
+ <developers>
+ <developer>
+ <id>kaz</id>
+ <name>Pete Kazmier</name>
+ <email>pete-apache-dev@kazmier.com</email>
+ <organization></organization>
+ <roles>
+ <role>Documentation</role>
+ <role>Java Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>epugh</id>
+ <name>Eric Pugh</name>
+ <email>epugh@opensourceconnections.com</email>
+ <organization></organization>
+ <roles>
+ <role>Java Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>evenisse</id>
+ <name>Emmanuel Venisse</name>
+ <email>emmanuel@venisse.net</email>
+ <organization></organization>
+ <roles>
+ <role>Java Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>jvanzyl</id>
+ <name>Jason van Zyl</name>
+ <email>jason@zenplex.com</email>
+ <organization>Zenplex</organization>
+ <roles>
+ <role>Architect</role>
+ <role>Release Manager</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>dlr</id>
+ <name>Daniel Rall</name>
+ <email>dlr@finemaltcoding.com</email>
+ <organization>CollabNet, Inc.</organization>
+ <roles>
+ <role>Java Developer</role>
+ <role>Documentation</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>felipeal</id>
+ <name>Felipe Leme</name>
+ <email>maven@felipeal.net</email>
+ <organization>Falcon Informatica</organization>
+ <roles>
+ <role>Java Developer</role>
+ </roles>
+ <timezone>-3</timezone>
+ </developer>
+ </developers>
+ <contributors>
+ <contributor>
+ <name>David Jackman</name>
+ </contributor>
+ </contributors>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.reporting</groupId>
+ <artifactId>maven-reporting-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>regexp</groupId>
+ <artifactId>regexp</artifactId>
+ <version>1.3</version>
+ </dependency>
+ <dependency>
+ <groupId>ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.6.5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.reporting</groupId>
+ <artifactId>maven-reporting-impl</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>netbeans</groupId>
+ <artifactId>cvslib</artifactId>
+ <version>3.6</version>
+ </dependency>
+ <dependency>
+ <groupId>doxia</groupId>
+ <artifactId>doxia-sink-api</artifactId>
+ <version>1.0-alpha-5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-settings</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.scm</groupId>
+ <artifactId>maven-scm-api</artifactId>
+ <version>1.0-beta-3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.scm</groupId>
+ <artifactId>maven-scm-manager-plexus</artifactId>
+ <version>1.0-beta-3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.scm</groupId>
+ <artifactId>maven-scm-provider-bazaar</artifactId>
+ <version>1.0-beta-3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.scm</groupId>
+ <artifactId>maven-scm-provider-clearcase</artifactId>
+ <version>1.0-beta-3-SNAPSHOT</version>
+ </dependency>
+ <!-- Replace this cvs provider by a pure java cvs provider when it will be available -->
+ <dependency>
+ <groupId>org.apache.maven.scm</groupId>
+ <artifactId>maven-scm-provider-cvsexe</artifactId>
+ <version>1.0-beta-3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.scm</groupId>
+ <artifactId>maven-scm-provider-local</artifactId>
+ <version>1.0-beta-3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.scm</groupId>
+ <artifactId>maven-scm-provider-perforce</artifactId>
+ <version>1.0-beta-3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.scm</groupId>
+ <artifactId>maven-scm-provider-starteam</artifactId>
+ <version>1.0-beta-3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.scm</groupId>
+ <artifactId>maven-scm-provider-svnexe</artifactId>
+ <version>1.0-beta-3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.scm</groupId>
+ <artifactId>maven-scm-provider-vss</artifactId>
+ <version>1.0-beta-3-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
Propchange: maven/sandbox/plugins/changelog-maven-plugin/pom.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/sandbox/plugins/changelog-maven-plugin/pom.xml
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLog.java
URL: http://svn.apache.org/viewcvs/maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLog.java?rev=387745&view=auto
==============================================================================
--- maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLog.java (added)
+++ maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLog.java Tue Mar 21 22:02:52 2006
@@ -0,0 +1,66 @@
+package org.apache.maven.changelog;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+// java imports
+
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Change log task. It uses a ChangeLogGenerator and ChangeLogParser to create
+ * a Collection of ChangeLogEntry objects, which are used to produce an XML
+ * output that represents the list of changes.
+ *
+ * @author <a href="mailto:glenn@somanetworks.com">Glenn McAllister</a>
+ * @author <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a>
+ * @author <a href="mailto:jason@zenplex.com">Jason van Zyl</a>
+ * @author <a href="mailto:dion@multitask.com.au">dIon Gillard</a>
+ * @author <a href="mailto:bodewig@apache.org">Stefan Bodewig</a>
+ * @author <a href="mailto:peter@apache.org">Peter Donald</a>
+ * @version $Id$
+ */
+public class ChangeLog
+{
+ /**
+ * parses a previously generated changelog xml document and return its changed sets
+ *
+ * @param stream the changelog xml document
+ * @return changelog sets parsed from the xml document
+ * @throws ParserConfigurationException when instantiation of the SAX parser failed
+ * @throws SAXException when an error occurred while parsing the xml document
+ * @throws IOException when an error occurred while accessing the xml document
+ */
+ public static List loadChangedSets( InputStream stream )
+ throws ParserConfigurationException, SAXException, IOException
+ {
+ SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+
+ List changeLogSets = new ArrayList();
+
+ parser.parse( stream, new ChangeLogHandler( changeLogSets ) );
+
+ return changeLogSets;
+ }
+} // end of ChangeLog
Propchange: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLog.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLog.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLogHandler.java
URL: http://svn.apache.org/viewcvs/maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLogHandler.java?rev=387745&view=auto
==============================================================================
--- maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLogHandler.java (added)
+++ maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLogHandler.java Tue Mar 21 22:02:52 2006
@@ -0,0 +1,222 @@
+package org.apache.maven.changelog;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.maven.scm.ChangeFile;
+import org.apache.maven.scm.ChangeSet;
+import org.apache.maven.scm.command.changelog.ChangeLogSet;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.LinkedList;
+
+/**
+ * Change log generated xml parser. SAXParser listener for processing a previously generated xml into several
+ * change log sets.
+ */
+public class ChangeLogHandler
+ extends DefaultHandler
+{
+ private Collection changeSets;
+
+ private String bufData = "";
+
+ private ChangeFile bufFile;
+
+ private ChangeSet bufEntry;
+
+ private LinkedList bufEntries;
+
+ private ChangeLogSet bufSet;
+
+ private String currentPattern;
+
+ /**
+ * contructor
+ *
+ * @param changeSets collection object to store all change sets found within the xml document
+ */
+ public ChangeLogHandler( Collection changeSets )
+ {
+ this.changeSets = changeSets;
+ }
+
+ /**
+ * @see org.xml.sax.helpers.DefaultHandler#characters(char[],int,int)
+ */
+ public void characters( char[] ch, int start, int length )
+ throws SAXException
+ {
+ bufData += new String( ch, start, length );
+ }
+
+ /**
+ * @see org.xml.sax.helpers.DefaultHandler#endElement(String,String,String)
+ */
+ public void endElement( String uri, String localName, String qName )
+ throws SAXException
+ {
+ if ( "changeset".equals( qName ) )
+ {
+ changeSets.add( bufSet );
+ }
+
+ if ( "changelog-entry".equals( qName ) )
+ {
+ bufEntries.add( bufEntry );
+ }
+
+ if ( "file".equals( qName ) )
+ {
+ bufEntry.addFile( bufFile );
+ }
+ else if ( "date".equals( qName ) )
+ {
+ try
+ {
+ long ms = 0;
+ if ( bufEntry.getDate() != null )
+ {
+ ms = bufEntry.getDate().getTime();
+ }
+ bufEntry.setDate( new Date( ms + new SimpleDateFormat( currentPattern ).parse( bufData ).getTime() ) );
+ }
+ catch ( ParseException e )
+ {
+ throw new SAXException( e );
+ }
+ }
+ else if ( "time".equals( qName ) )
+ {
+ try
+ {
+ long ms = 0;
+ if ( bufEntry.getDate() != null )
+ {
+ ms = bufEntry.getDate().getTime();
+ }
+ bufEntry.setDate( new Date( ms + new SimpleDateFormat( currentPattern ).parse( bufData ).getTime() ) );
+ }
+ catch ( ParseException e )
+ {
+ throw new SAXException( e );
+ }
+ }
+ else if ( "author".equals( qName ) )
+ {
+ bufEntry.setAuthor( bufData );
+ }
+ else if ( "msg".equals( qName ) )
+ {
+ bufEntry.setComment( bufData );
+ }
+
+ if ( "revision".equals( qName ) )
+ {
+ bufFile.setRevision( bufData );
+ }
+ else if ( "name".equals( qName ) )
+ {
+ bufFile.setName( bufData );
+ }
+ }
+
+ /**
+ * @see org.xml.sax.helpers.DefaultHandler#startElement(String,String,String,Attributes)
+ */
+ public void startElement( String uri, String localName, String qName, Attributes attributes )
+ throws SAXException
+ {
+ bufData = "";
+
+ if ( "file".equals( qName ) )
+ {
+ bufFile = new ChangeFile( "" );
+ }
+ else if ( "changelog-entry".equals( qName ) )
+ {
+ bufEntry = new ChangeSet();
+ }
+ else if ( "date".equals( qName ) )
+ {
+ currentPattern = attributes.getValue( "pattern" );
+ if ( currentPattern == null )
+ {
+ currentPattern = "yyyy-MM-dd";
+ }
+ }
+ else if ( "time".equals( qName ) )
+ {
+ currentPattern = attributes.getValue( "pattern" );
+ if ( currentPattern == null )
+ {
+ currentPattern = "HH:mm:ss";
+ }
+ }
+ else if ( "changeset".equals( qName ) )
+ {
+ bufEntries = new LinkedList();
+
+ currentPattern = attributes.getValue( "datePattern" );
+ if ( currentPattern == null )
+ {
+ currentPattern = "yyyy-MM-dd";
+ }
+
+ SimpleDateFormat formatter = new SimpleDateFormat( currentPattern );
+
+ String start = attributes.getValue( "start" );
+
+ String end = attributes.getValue( "end" );
+
+ Date startDate = null;
+
+ Date endDate = null;
+
+ if ( start != null )
+ {
+ try
+ {
+ startDate = formatter.parse( start );
+ }
+ catch ( ParseException e )
+ {
+ throw new SAXException( "Can't parse start date '" + start + "'.", e );
+ }
+ }
+
+ if ( end != null )
+ {
+ try
+ {
+ endDate = formatter.parse( end );
+ }
+ catch ( ParseException e )
+ {
+ throw new SAXException( "Can't parse end date '" + end + "'.", e );
+ }
+ }
+
+ bufSet = new ChangeLogSet( bufEntries, startDate, endDate );
+ }
+ }
+}
Propchange: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLogHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLogHandler.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLogReport.java
URL: http://svn.apache.org/viewcvs/maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLogReport.java?rev=387745&view=auto
==============================================================================
--- maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLogReport.java (added)
+++ maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLogReport.java Tue Mar 21 22:02:52 2006
@@ -0,0 +1,1224 @@
+package org.apache.maven.changelog;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.reporting.AbstractMavenReport;
+import org.apache.maven.reporting.MavenReportException;
+import org.apache.maven.scm.ChangeFile;
+import org.apache.maven.scm.ChangeSet;
+import org.apache.maven.scm.ScmException;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.ScmResult;
+import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
+import org.apache.maven.scm.command.changelog.ChangeLogSet;
+import org.apache.maven.scm.manager.ScmManager;
+import org.apache.maven.scm.provider.ScmProvider;
+import org.apache.maven.scm.provider.ScmProviderRepository;
+import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost;
+import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
+import org.apache.maven.scm.repository.ScmRepository;
+import org.apache.maven.settings.Server;
+import org.apache.maven.settings.Settings;
+import org.codehaus.doxia.sink.Sink;
+import org.codehaus.doxia.site.renderer.SiteRenderer;
+import org.codehaus.plexus.util.StringUtils;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
+
+
+/**
+ * @goal changelog
+ * @description A Maven 2.0 Changelog report plugin
+ */
+public class ChangeLogReport
+ extends AbstractMavenReport
+{
+ /**
+ * Used to specify whether to build the log from a range, absolute date.
+ *
+ * @parameter
+ */
+ private String type = "range";
+
+ /**
+ * Used to specify the number of days of log entries to retrieve.
+ *
+ * @parameter
+ */
+ private int range = -1;
+
+ /**
+ * Used to specify the absolute date (or list of dates) to start log entries from.
+ *
+ * @parameter
+ */
+ private List dates;
+
+ /**
+ * Used to specify the tag (or list of tags) to start log entries from.
+ *
+ * @parameter
+ */
+ private List tags;
+
+ /**
+ * Used to specify the date format of log entries to retrieve.
+ *
+ * @parameter
+ */
+ private String dateFormat = "yyyy-MM-dd";
+
+ /**
+ * Input dir. Directory where the sources are located.
+ *
+ * @parameter expression="${project.build.sourceDirectory}"
+ * @required
+ */
+ private File basedir;
+
+ /**
+ * Output file for xml document
+ *
+ * @parameter expression="${project.build.directory}/changelog.xml"
+ * @required
+ */
+ private File outputXML;
+
+ /**
+ * Allows the user to make changelog regenerate the changelog.xml file for the specified time in minutes.
+ *
+ * @parameter expression="${outputXMLExpiration}" default-value="60"
+ * @required
+ */
+ private int outputXMLExpiration;
+
+ /**
+ * Comment format string used for interrogating
+ * the revision control system.
+ * Currently only used by the ClearcaseChangeLogGenerator.
+ */
+ private String commentFormat;
+
+ /**
+ * Output encoding for the xml document
+ *
+ * @parameter
+ */
+ private String outputEncoding = "ISO-8859-1";
+
+ /**
+ * The user name (used by svn and starteam protocol).
+ *
+ * @parameter expression="${username}"
+ */
+ private String username;
+
+ /**
+ * The user password (used by svn and starteam protocol).
+ *
+ * @parameter expression="${password}"
+ */
+ private String password;
+
+ /**
+ * The private key (used by java svn).
+ *
+ * @parameter expression="${privateKey}"
+ */
+ private String privateKey;
+
+ /**
+ * The passphrase (used by java svn).
+ *
+ * @parameter expression="${passphrase}"
+ */
+ private String passphrase;
+
+ /**
+ * The url of tags base directory (used by svn protocol).
+ *
+ * @parameter expression="${tagBase}"
+ */
+ private String tagBase;
+
+ /**
+ * The URL to view the scm. Basis for external links from the generated report.
+ *
+ * @parameter expression="${project.scm.url}"
+ */
+ private String scmUrl;
+
+ /**
+ * The Maven Project Object
+ *
+ * @parameter expression="${project}"
+ * @required
+ * @readonly
+ */
+ private MavenProject project;
+
+ /**
+ * The directory where the report will be generated
+ *
+ * @parameter expression="${project.build.directory}/site"
+ * @required
+ * @readonly
+ */
+ private File outputDirectory;
+
+ /**
+ * @parameter expression="${component.org.codehaus.doxia.site.renderer.SiteRenderer}"
+ * @required
+ * @readonly
+ */
+ private SiteRenderer siteRenderer;
+
+ /**
+ * @parameter expression="${settings.offline}"
+ * @required
+ * @readonly
+ */
+ private boolean offline;
+
+ /**
+ * @parameter expression="${component.org.apache.maven.scm.manager.ScmManager}"
+ * @required
+ * @readonly
+ */
+ private ScmManager manager;
+
+ /**
+ * @parameter expression="${settings}"
+ * @required
+ * @readonly
+ */
+ 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 default-value="connection"
+ * @required
+ */
+ private String connectionType;
+
+ /**
+ * Allows the user to specify the file detail URL to use when viewing an scm file.
+ *
+ * @parameter expression="${project.scm.url}"
+ */
+ private String displayFileDetailUrl;
+
+ // temporary field holder while generating the report
+ private String rpt_Repository, rpt_OneRepoParam, rpt_MultiRepoParam;
+
+ // field for SCM Connection URL
+ private String connection;
+
+ /**
+ * @see org.apache.maven.reporting.AbstractMavenReport#executeReport(java.util.Locale)
+ */
+ public void executeReport( Locale locale )
+ throws MavenReportException
+ {
+ //check if sources exists <-- required for parent poms
+ if ( !basedir.exists() )
+ {
+ doGenerateEmptyReport( getBundle( locale ), getSink() );
+
+ return;
+ }
+
+ verifySCMTypeParams();
+
+ doGenerateReport( getChangedSets(), getBundle( locale ), getSink() );
+ }
+
+ /**
+ * populates the changedSets field by either connecting to the SCM or using an existing XML generated in a previous
+ * run of the report
+ *
+ * @throws MavenReportException
+ */
+ protected List getChangedSets()
+ throws MavenReportException
+ {
+ List changelogList = null;
+
+ if ( outputXML.exists() )
+ {
+ if ( outputXMLExpiration * 60000 > System.currentTimeMillis() - outputXML.lastModified() )
+ {
+ try
+ {
+ FileInputStream fIn = new FileInputStream( outputXML );
+
+ getLog().info( "Using existing changelog.xml..." );
+
+ changelogList = ChangeLog.loadChangedSets( fIn );
+ }
+ catch ( FileNotFoundException e )
+ {
+ //do nothing, just regenerate
+ }
+ catch ( Exception e )
+ {
+ throw new MavenReportException( "An error occurred while parsing " + outputXML.getAbsolutePath(),
+ e );
+ }
+ }
+ }
+
+ if ( changelogList == null )
+ {
+ if ( offline )
+ {
+ throw new MavenReportException( "This report requires online mode." );
+ }
+
+ getLog().info( "Generating changed sets xml to: " + outputXML.getAbsolutePath() );
+
+ changelogList = generateChangeSetsFromSCM();
+
+ try
+ {
+ writeChangelogXml( changelogList );
+ }
+ catch ( FileNotFoundException e )
+ {
+ throw new MavenReportException( "Can't create " + outputXML.getAbsolutePath(), e );
+ }
+ }
+
+ return changelogList;
+ }
+
+ private void writeChangelogXml( List changelogList )
+ throws FileNotFoundException
+ {
+ StringBuffer changelogXml = new StringBuffer();
+
+ changelogXml.append( "<?xml version=\"1.0\" encoding=\"" ).append( outputEncoding ).append( "\"?>\n" );
+ changelogXml.append( "<changelog>" );
+
+ for ( Iterator sets = changelogList.iterator(); sets.hasNext(); )
+ {
+ changelogXml.append( "\n " );
+
+ ChangeLogSet changelogSet = (ChangeLogSet) sets.next();
+ String changeset = changelogSet.toXML( outputEncoding );
+
+ //remove xml header
+ if ( changeset.startsWith( "<?xml" ) )
+ {
+ int idx = changeset.indexOf( "?>" ) + 2;
+ changeset = changeset.substring( idx );
+ }
+
+ changelogXml.append( changeset );
+ }
+
+ changelogXml.append( "\n</changelog>" );
+
+ outputXML.getParentFile().mkdirs();
+
+ PrintWriter pw = new PrintWriter( new BufferedOutputStream( new FileOutputStream( outputXML ) ) );
+ pw.write( changelogXml.toString() );
+ pw.flush();
+ pw.close();
+ }
+
+ /**
+ * creates a ChangeLog object and then connects to the SCM to generate the changed sets
+ *
+ * @return changedlogsets generated from the SCM
+ * @throws MavenReportException
+ */
+ protected List generateChangeSetsFromSCM()
+ throws MavenReportException
+ {
+ try
+ {
+ List changeSets = new ArrayList();
+
+ ScmRepository repository = getScmRepository();
+
+ ScmProvider provider = manager.getProviderByRepository( repository );
+
+ ChangeLogScmResult result;
+
+ if ( "range".equals( type ) )
+ {
+ result =
+ provider.changeLog( repository, new ScmFileSet( basedir ), null, null, range, null, dateFormat );
+
+ checkResult( result );
+
+ changeSets.add( result.getChangeLog() );
+ }
+ else if ( "tag".equals( type ) )
+ {
+ Iterator tagsIter = tags.iterator();
+
+ String startTag = (String) tagsIter.next();
+ String endTag = null;
+
+ if ( tagsIter.hasNext() )
+ {
+ while ( tagsIter.hasNext() )
+ {
+ endTag = (String) tagsIter.next();
+
+ result = provider.changeLog( repository, new ScmFileSet( basedir ), startTag, endTag );
+
+ checkResult( result );
+
+ changeSets.add( result.getChangeLog() );
+
+ startTag = endTag;
+ }
+ }
+ else
+ {
+ result = provider.changeLog( repository, new ScmFileSet( basedir ), startTag, endTag );
+
+ checkResult( result );
+
+ changeSets.add( result.getChangeLog() );
+ }
+ }
+ else if ( "date".equals( type ) )
+ {
+ Iterator dateIter = dates.iterator();
+
+ String startDate = (String) dateIter.next();
+ String endDate = null;
+
+ if ( dateIter.hasNext() )
+ {
+ while ( dateIter.hasNext() )
+ {
+ endDate = (String) dateIter.next();
+
+ result = provider.changeLog( repository, new ScmFileSet( basedir ), parseDate( startDate ),
+ parseDate( endDate ), 0, null );
+
+ checkResult( result );
+
+ changeSets.add( result.getChangeLog() );
+
+ startDate = endDate;
+ }
+ }
+ else
+ {
+ result = provider.changeLog( repository, new ScmFileSet( basedir ), parseDate( startDate ),
+ parseDate( endDate ), 0, null );
+
+ checkResult( result );
+
+ changeSets.add( result.getChangeLog() );
+ }
+ }
+ else
+ {
+ throw new MavenReportException( "The type'" + type + "' isn't supported." );
+ }
+
+ return changeSets;
+ }
+ catch ( ScmException e )
+ {
+ throw new MavenReportException( "Cannot run changelog command : ", e );
+ }
+ catch ( MojoExecutionException e )
+ {
+ throw new MavenReportException( "An erro is occurred durint changelog command : ", e );
+ }
+ }
+
+ /**
+ * Converts the localized date string pattern to date object.
+ *
+ * @return A date
+ */
+ private Date parseDate( String date )
+ throws MojoExecutionException
+ {
+ if ( date == null || date.trim().length() == 0 )
+ {
+ return null;
+ }
+
+ SimpleDateFormat formatter = new SimpleDateFormat( "yyyy-MM-dd" );
+
+ try
+ {
+ return formatter.parse( date );
+ }
+ catch ( ParseException e )
+ {
+ throw new MojoExecutionException( "Please use this date pattern: " + formatter.toLocalizedPattern(), e );
+ }
+ }
+
+ public ScmRepository getScmRepository()
+ throws ScmException
+ {
+ ScmRepository repository;
+
+ try
+ {
+ repository = manager.makeScmRepository( getConnection() );
+
+ ScmProviderRepository providerRepo = repository.getProviderRepository();
+
+ if ( !StringUtils.isEmpty( username ) )
+ {
+ providerRepo.setUser( username );
+ }
+
+ if ( !StringUtils.isEmpty( password ) )
+ {
+ providerRepo.setPassword( password );
+ }
+
+ if ( repository.getProviderRepository() instanceof ScmProviderRepositoryWithHost )
+ {
+ ScmProviderRepositoryWithHost repo = (ScmProviderRepositoryWithHost) repository.getProviderRepository();
+
+ loadInfosFromSettings( repo );
+
+ if ( !StringUtils.isEmpty( username ) )
+ {
+ repo.setUser( username );
+ }
+
+ if ( !StringUtils.isEmpty( password ) )
+ {
+ repo.setPassword( password );
+ }
+
+ if ( !StringUtils.isEmpty( privateKey ) )
+ {
+ repo.setPrivateKey( privateKey );
+ }
+
+ if ( !StringUtils.isEmpty( passphrase ) )
+ {
+ repo.setPassphrase( passphrase );
+ }
+ }
+
+ if ( !StringUtils.isEmpty( tagBase ) && repository.getProvider().equals( "svn" ) )
+ {
+ SvnScmProviderRepository svnRepo = (SvnScmProviderRepository) repository.getProviderRepository();
+
+ svnRepo.setTagBase( tagBase );
+ }
+ }
+ 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
+ *
+ * @param repo
+ */
+ private void loadInfosFromSettings( ScmProviderRepositoryWithHost repo )
+ {
+ if ( username == null || password == null )
+ {
+ String host = repo.getHost();
+
+ int port = repo.getPort();
+
+ if ( port > 0 )
+ {
+ host += ":" + port;
+ }
+
+ Server server = this.settings.getServer( host );
+
+ if ( server != null )
+ {
+ if ( username == null )
+ {
+ username = this.settings.getServer( host ).getUsername();
+ }
+
+ if ( password == null )
+ {
+ password = this.settings.getServer( host ).getPassword();
+ }
+
+ if ( privateKey == null )
+ {
+ privateKey = this.settings.getServer( host ).getPrivateKey();
+ }
+
+ if ( passphrase == null )
+ {
+ passphrase = this.settings.getServer( host ).getPassphrase();
+ }
+ }
+ }
+ }
+
+ public void checkResult( ScmResult result )
+ throws MojoExecutionException
+ {
+ if ( !result.isSuccess() )
+ {
+ getLog().error( "Provider message:" );
+
+ getLog().error( result.getProviderMessage() == null ? "" : result.getProviderMessage() );
+
+ getLog().error( "Command output:" );
+
+ getLog().error( result.getCommandOutput() == null ? "" : result.getCommandOutput() );
+
+ throw new MojoExecutionException( "Command failed." );
+ }
+ }
+
+ /**
+ * used to retrieve the SCM connection string
+ *
+ * @return the url string used to connect to the SCM
+ * @throws MavenReportException when there is insufficient information to retrieve the SCM connection string
+ */
+ protected String getConnection()
+ throws MavenReportException
+ {
+ if ( this.connection != null )
+ {
+ return connection;
+ }
+
+ if ( project.getScm() == null )
+ {
+ throw new MavenReportException( "SCM Connection is not set." );
+ }
+
+ String scmConnection = project.getScm().getConnection();
+ if ( StringUtils.isNotEmpty( scmConnection ) && "connection".equals( connectionType.toLowerCase() ) )
+ {
+ connection = scmConnection;
+ }
+
+ String scmDeveloper = project.getScm().getDeveloperConnection();
+ if ( StringUtils.isNotEmpty( scmDeveloper ) && "developerconnection".equals( connectionType.toLowerCase() ) )
+ {
+ connection = scmDeveloper;
+ }
+
+ if ( StringUtils.isEmpty( connection ) )
+ {
+ throw new MavenReportException( "SCM Connection is not set." );
+ }
+
+ return connection;
+ }
+
+ /**
+ * checks whether there are enough configuration parameters to generate the report
+ *
+ * @throws MavenReportException when there is insufficient paramters to generate the report
+ */
+ private void verifySCMTypeParams()
+ throws MavenReportException
+ {
+ if ( "range".equals( type ) )
+ {
+ if ( range == -1 )
+ {
+ range = 30;
+ }
+ }
+ else if ( "date".equals( type ) )
+ {
+ if ( dates == 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( type ) )
+ {
+ if ( tags == null )
+ {
+ throw new MavenReportException( "The tags parameter is required when type=\"tag\"." );
+ }
+ }
+ else
+ {
+ throw new MavenReportException( "The type parameter has an invalid value: " + type +
+ ". The value should be \"range\", \"date\", or \"tag\"." );
+ }
+ }
+
+ /**
+ * generates an empty report in case there are no sources to generate a report with
+ *
+ * @param bundle the resource bundle to retrieve report phrases from
+ * @param sink the report formatting tool
+ */
+ protected void doGenerateEmptyReport( ResourceBundle bundle, Sink sink )
+ {
+ sink.head();
+ sink.title();
+ sink.text( bundle.getString( "report.changelog.header" ) );
+ sink.title_();
+ sink.head_();
+
+ sink.body();
+ sink.section1();
+
+ sink.sectionTitle1();
+ sink.text( bundle.getString( "report.changelog.mainTitle" ) );
+ sink.sectionTitle1_();
+
+ sink.paragraph();
+ sink.text( "No sources found to create a report." );
+ 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
+ *
+ * @param changeLogSets changed sets to generate the report from
+ * @param bundle the resource bundle to retrieve report phrases from
+ * @param sink the report formatting tool
+ */
+ protected void doGenerateReport( List changeLogSets, ResourceBundle bundle, Sink sink )
+ {
+ sink.head();
+ sink.title();
+ sink.text( bundle.getString( "report.changelog.header" ) );
+ sink.title_();
+ sink.head_();
+
+ sink.body();
+ sink.section1();
+
+ sink.sectionTitle1();
+ sink.text( bundle.getString( "report.changelog.mainTitle" ) );
+ sink.sectionTitle1_();
+
+ // Summary section
+ doSummarySection( changeLogSets, bundle, sink );
+
+ for ( Iterator sets = changeLogSets.iterator(); sets.hasNext(); )
+ {
+ ChangeLogSet changeLogSet = (ChangeLogSet) sets.next();
+
+ doChangedSet( changeLogSet, bundle, sink );
+ }
+
+ sink.section1_();
+ sink.body_();
+
+ sink.flush();
+ sink.close();
+ }
+
+ /**
+ * generates the report summary section of the report
+ *
+ * @param changeLogSets changed sets to generate the report from
+ * @param bundle the resource bundle to retrieve report phrases from
+ * @param sink the report formatting tool
+ */
+ private void doSummarySection( List changeLogSets, ResourceBundle bundle, Sink sink )
+ {
+ sink.paragraph();
+
+ sink.text( bundle.getString( "report.changelog.ChangedSetsTotal" ) );
+ sink.text( ": " + changeLogSets.size() );
+
+ sink.paragraph_();
+ }
+
+ /**
+ * generates a section of the report referring to a changeset
+ *
+ * @param set the current ChangeSet to generate this section of the report
+ * @param bundle the resource bundle to retrieve report phrases from
+ * @param sink the report formatting tool
+ */
+ private void doChangedSet( ChangeLogSet set, ResourceBundle bundle, Sink sink )
+ {
+ sink.section1();
+
+ sink.sectionTitle2();
+ if ( set.getStartDate() == null )
+ {
+ sink.text( bundle.getString( "report.SetRangeUnknown" ) );
+ }
+ else if ( set.getEndDate() == null )
+ {
+ sink.text( bundle.getString( "report.SetRangeSince" ) );
+ sink.text( " " + set.getStartDate() );
+ }
+ else
+ {
+ sink.text( bundle.getString( "report.SetRangeBetween" ) );
+ sink.text( " " + set.getStartDate() + " " + bundle.getString( "report.To" ) + " " + set.getEndDate() );
+ }
+ sink.sectionTitle2_();
+
+ sink.paragraph();
+ sink.text( bundle.getString( "report.TotalCommits" ) );
+ sink.text( ": " + set.getChangeSets().size() );
+ sink.lineBreak();
+ sink.text( bundle.getString( "report.changelog.FilesChanged" ) );
+ sink.text( ": " + countFilesChanged( set.getChangeSets() ) );
+ sink.paragraph_();
+
+ doChangedSetTable( set.getChangeSets(), bundle, sink );
+
+ sink.section1_();
+ }
+
+ /**
+ * counts the number of files that were changed in the specified SCM
+ *
+ * @param entries a collection of SCM changes
+ * @return number of files changed for the changedsets
+ */
+ protected long countFilesChanged( Collection entries )
+ {
+ if ( entries == null )
+ {
+ return 0;
+ }
+
+ if ( entries.isEmpty() )
+ {
+ return 0;
+ }
+
+ HashMap fileList = new HashMap();
+
+ for ( Iterator i = entries.iterator(); i.hasNext(); )
+ {
+ ChangeSet entry = (ChangeSet) i.next();
+
+ List files = entry.getFiles();
+
+ for ( Iterator fileIterator = files.iterator(); fileIterator.hasNext(); )
+ {
+ ChangeFile file = (ChangeFile) fileIterator.next();
+
+ String name = file.getName();
+
+ if ( fileList.containsKey( name ) )
+ {
+ LinkedList list = (LinkedList) fileList.get( name );
+
+ list.add( file );
+ }
+ else
+ {
+ LinkedList list = new LinkedList();
+
+ list.add( file );
+
+ fileList.put( name, list );
+ }
+ }
+ }
+
+ return fileList.size();
+ }
+
+ /**
+ * generates the report table showing the SCM log entries
+ *
+ * @param entries a list of change log entries to generate the report from
+ * @param bundle the resource bundle to retrieve report phrases from
+ * @param sink the report formatting tool
+ */
+ private void doChangedSetTable( Collection entries, ResourceBundle bundle, Sink sink )
+ {
+ sink.table();
+
+ sink.tableRow();
+ sink.tableHeaderCell();
+ sink.text( bundle.getString( "report.changelog.timestamp" ) );
+ sink.tableHeaderCell_();
+ sink.tableHeaderCell();
+ sink.text( bundle.getString( "report.changelog.author" ) );
+ sink.tableHeaderCell_();
+ sink.tableHeaderCell();
+ sink.text( bundle.getString( "report.changelog.details" ) );
+ sink.tableHeaderCell_();
+ sink.tableRow_();
+
+ for ( Iterator i = entries.iterator(); i.hasNext(); )
+ {
+ ChangeSet entry = (ChangeSet) i.next();
+
+ doChangedSetDetail( entry, bundle, sink );
+ }
+
+ sink.table_();
+ }
+
+ /**
+ * reports on the details of an SCM entry log
+ *
+ * @param entry an SCM entry to generate the report from
+ * @param bundle the resource bundle to retrieve report phrases from
+ * @param sink the report formatting tool
+ */
+ private void doChangedSetDetail( ChangeSet entry, ResourceBundle bundle, Sink sink )
+ {
+ sink.tableRow();
+
+ sink.tableCell();
+ sink.text( entry.getDateFormatted() + " " + entry.getTimeFormatted() );
+ sink.tableCell_();
+
+ sink.tableCell();
+ sink.text( entry.getAuthor() );
+ sink.tableCell_();
+
+ sink.tableCell();
+ initReportUrls();
+ //doRevision( entry.getFiles(), bundle, sink );
+ doChangedFiles( entry.getFiles(), sink );
+ sink.lineBreak();
+ sink.text( entry.getComment() );
+ sink.tableCell_();
+
+ sink.tableRow_();
+ }
+
+ /**
+ * populates the report url used to create links from certain elements of the report
+ */
+ protected void initReportUrls()
+ {
+ if ( scmUrl != null )
+ {
+ int idx = scmUrl.indexOf( '?' );
+
+ if ( idx > 0 )
+ {
+ rpt_Repository = scmUrl.substring( 0, idx );
+
+ if ( scmUrl.equals( displayFileDetailUrl ) )
+ {
+ String rpt_TmpMultiRepoParam = scmUrl.substring( rpt_Repository.length() );
+
+ rpt_OneRepoParam = "?" + rpt_TmpMultiRepoParam.substring( 1 );
+
+ rpt_MultiRepoParam = "&" + rpt_TmpMultiRepoParam.substring( 1 );
+ }
+ else
+ {
+ idx = displayFileDetailUrl.indexOf( "?" );
+
+ if ( idx > 0 )
+ {
+ displayFileDetailUrl = displayFileDetailUrl.substring( 0, idx );
+
+ String rpt_TmpMultiRepoParam = displayFileDetailUrl.substring( idx + 1 );
+
+ rpt_OneRepoParam = "?" + rpt_TmpMultiRepoParam;
+
+ rpt_MultiRepoParam = "&" + rpt_TmpMultiRepoParam;
+ }
+ else
+ {
+ rpt_OneRepoParam = "";
+
+ rpt_MultiRepoParam = "";
+ }
+ }
+ }
+ else
+ {
+ rpt_Repository = scmUrl;
+
+ rpt_OneRepoParam = "";
+
+ rpt_MultiRepoParam = "";
+ }
+ }
+ }
+
+ /**
+ * generates the section of the report listing all the files revisions
+ *
+ * @param files list of files to generate the reports from
+ */
+ private void doChangedFiles( List files, Sink sink )
+ {
+ for ( Iterator i = files.iterator(); i.hasNext(); )
+ {
+ ChangeFile file = (ChangeFile) i.next();
+ sinkLogFile( sink, file.getName(), file.getRevision() );
+ }
+ }
+
+ /**
+ * generates the section of the report detailing the revisions made and the files changed
+ *
+ * @param sink the report formatting tool
+ * @param name filename of the changed file
+ * @param revision the revision code for this file
+ */
+ private void sinkLogFile( Sink sink, String name, String revision )
+ {
+ sink.paragraph();
+
+ try
+ {
+ String connection = getConnection();
+
+ generateLinks( connection, name, revision, sink );
+ }
+ catch ( Exception e )
+ {
+ getLog().debug( e );
+
+ sink.text( name + " v " + revision );
+ }
+
+ sink.paragraph_();
+ }
+
+ /**
+ * attaches the http links from the changed files
+ *
+ * @param connection the string used to connect to the SCM
+ * @param name filename of the file that was changed
+ * @param sink the report formatting tool
+ */
+ protected void generateLinks( String connection, String name, Sink sink )
+ {
+ generateLinks( connection, name, null, sink );
+ }
+
+ /**
+ * attaches the http links from the changed files
+ *
+ * @param connection the string used to connect to the SCM
+ * @param name filename of the file that was changed
+ * @param revision the revision code
+ * @param sink the report formatting tool
+ */
+ protected void generateLinks( String connection, String name, String revision, Sink sink )
+ {
+ String linkFile = null;
+ String linkRev = null;
+
+ if ( displayFileDetailUrl != null )
+ {
+ if ( connection.startsWith( "scm:perforce" ) )
+ {
+ String path = getAbsolutePath( displayFileDetailUrl, name );
+ linkFile = path + "?ac=22";
+ if ( revision != null )
+ {
+ linkRev = path + "?ac=64&rev=" + revision;
+ }
+ }
+ else if ( connection.startsWith( "scm:clearcase" ) )
+ {
+ String path = getAbsolutePath( displayFileDetailUrl, name );
+ linkFile = path + rpt_OneRepoParam;
+ }
+ else if ( connection.indexOf( "cvsmonitor.pl" ) > 0 )
+ {
+ String module = rpt_OneRepoParam.replaceAll( "^.*(&module=.*?(?:&|$)).*$", "$1" );
+ linkFile = displayFileDetailUrl + "?cmd=viewBrowseFile" + module + "&file=" + name;
+ if ( revision != null )
+ {
+ linkRev =
+ rpt_Repository + "?cmd=viewBrowseVersion" + module + "&file=" + name + "&version=" + revision;
+ }
+ }
+ else
+ {
+ String path = getAbsolutePath( displayFileDetailUrl, name );
+ linkFile = path + rpt_OneRepoParam;
+ if ( revision != null )
+ {
+ linkRev = path + "?rev=" + revision + "&content-type=text/vnd.viewcvs-markup" + rpt_MultiRepoParam;
+ }
+ }
+ }
+
+ if ( linkFile != null )
+ {
+ sink.link( linkFile );
+ sink.text( name );
+ sink.link_();
+ }
+ else
+ {
+ sink.text( name );
+ }
+
+ sink.text( " " );
+
+ if ( linkRev != null )
+ {
+ sink.link( linkRev );
+ sink.text( "v " + revision );
+ sink.link_();
+ }
+ else if ( revision != null )
+ {
+ sink.text( "v " + revision );
+ }
+ }
+
+ /**
+ * calculates the path from a base directory to a target file
+ *
+ * @param base base directory to create the absolute path from
+ * @param target target file to create the absolute path to
+ */
+ private String getAbsolutePath( final String base, final String target )
+ {
+ String absPath = "";
+
+ StringTokenizer baseTokens = new StringTokenizer( base.replaceAll( "\\\\", "/" ), "/", true );
+
+ StringTokenizer targetTokens = new StringTokenizer( target.replaceAll( "\\\\", "/" ), "/" );
+
+ String targetRoot = targetTokens.nextToken();
+
+ while ( baseTokens.hasMoreTokens() )
+ {
+ String baseToken = baseTokens.nextToken();
+
+ if ( baseToken.equals( targetRoot ) )
+ {
+ break;
+ }
+
+ absPath += baseToken;
+ }
+
+ return absPath + target.substring( 1 );
+ }
+
+ /**
+ * @see org.apache.maven.reporting.AbstractMavenReport#getProject()
+ */
+ protected MavenProject getProject()
+ {
+ return project;
+ }
+
+ /**
+ * @see org.apache.maven.reporting.AbstractMavenReport#getOutputDirectory()
+ */
+ protected String getOutputDirectory()
+ {
+ return outputDirectory.getAbsolutePath();
+ }
+
+ /**
+ * @see org.apache.maven.reporting.AbstractMavenReport#getSiteRenderer()
+ */
+ protected SiteRenderer getSiteRenderer()
+ {
+ return siteRenderer;
+ }
+
+ /**
+ * @see org.apache.maven.reporting.MavenReport#getDescription(java.util.Locale)
+ */
+ public String getDescription( Locale locale )
+ {
+ return "Generated Changelog report from SCM";
+ }
+
+ /**
+ * @see org.apache.maven.reporting.MavenReport#getName(java.util.Locale)
+ */
+ public String getName( Locale locale )
+ {
+ return "changelog";
+ }
+
+ /**
+ * @see org.apache.maven.reporting.MavenReport#getOutputName()
+ */
+ public String getOutputName()
+ {
+ return "changelog";
+ }
+
+ /**
+ * @see org.apache.maven.reporting.MavenReport#getOutputName()
+ */
+ protected ResourceBundle getBundle( Locale locale )
+ {
+ return ResourceBundle.getBundle( "scm-activity", locale, this.getClass().getClassLoader() );
+ }
+
+ public boolean canGenerateReport()
+ {
+ if ( offline && !outputXML.exists() )
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+}
Propchange: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLogReport.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/ChangeLogReport.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/DeveloperActivityReport.java
URL: http://svn.apache.org/viewcvs/maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/DeveloperActivityReport.java?rev=387745&view=auto
==============================================================================
--- maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/DeveloperActivityReport.java (added)
+++ maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/DeveloperActivityReport.java Tue Mar 21 22:02:52 2006
@@ -0,0 +1,393 @@
+package org.apache.maven.changelog;
+
+/*
+* Copyright 2001-2006 The Apache Software Foundation.
+*
+* Licensed 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 org.apache.maven.model.Developer;
+import org.apache.maven.scm.ChangeFile;
+import org.apache.maven.scm.ChangeSet;
+import org.apache.maven.scm.command.changelog.ChangeLogSet;
+import org.codehaus.doxia.sink.Sink;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+
+/**
+ * @goal dev-activity
+ * @description A Maven 2.0 developer activity report plugin
+ */
+public class DeveloperActivityReport
+ extends ChangeLogReport
+{
+ /**
+ * List of developers to be shown on the report.
+ *
+ * @parameter expression="${project.developers}"
+ */
+ private List developers;
+
+ /**
+ * Used to hold data while creating the report
+ */
+ private HashMap commits;
+
+ private HashMap files;
+
+ /**
+ * @see org.apache.maven.reporting.MavenReport#getDescription(java.util.Locale)
+ */
+ public String getDescription( Locale locale )
+ {
+ return "Generated developer activity report from SCM";
+ }
+
+ /**
+ * @see org.apache.maven.reporting.MavenReport#getName(java.util.Locale)
+ */
+ public String getName( Locale locale )
+ {
+ return "dev-activity";
+ }
+
+ /**
+ * @see org.apache.maven.reporting.MavenReport#getOutputName()
+ */
+ public String getOutputName()
+ {
+ return "dev-activity";
+ }
+
+ /**
+ * generates an empty report in case there are no sources to generate a report with
+ *
+ * @param bundle the resource bundle to retrieve report phrases from
+ * @param sink the report formatting tool
+ */
+ protected void doGenerateEmptyReport( ResourceBundle bundle, Sink sink )
+ {
+ sink.head();
+ sink.title();
+ sink.text( bundle.getString( "report.dev-activity.header" ) );
+ sink.title_();
+ sink.head_();
+
+ sink.body();
+ sink.section1();
+
+ sink.sectionTitle1();
+ sink.text( bundle.getString( "report.dev-activity.mainTitle" ) );
+ sink.sectionTitle1_();
+
+ sink.paragraph();
+ sink.text( "No sources found to create a report." );
+ sink.paragraph_();
+
+ sink.section1_();
+
+ sink.body_();
+ sink.flush();
+ sink.close();
+ }
+
+ /**
+ * method that generates the report for this mojo.
+ *
+ * @param changeLogSets changed sets to generate the report from
+ * @param bundle the resource bundle to retrieve report phrases from
+ * @param sink the report formatting tool
+ */
+ protected void doGenerateReport( ChangeLogSet changeLogSets, ResourceBundle bundle, Sink sink )
+ {
+ sink.head();
+ sink.title();
+ sink.text( bundle.getString( "report.dev-activity.header" ) );
+ sink.title_();
+ sink.head_();
+
+ sink.body();
+ sink.section1();
+ sink.sectionTitle1();
+ sink.text( bundle.getString( "report.dev-activity.mainTitle" ) );
+ sink.sectionTitle1_();
+
+ doChangedSets( changeLogSets, bundle, sink );
+
+ sink.section1_();
+ sink.body_();
+ sink.flush();
+ sink.table_();
+ }
+
+ /**
+ * generates a section of the report referring to a changeset
+ *
+ * @param set the current ChangeSet to generate this section of the report
+ * @param bundle the resource bundle to retrieve report phrases from
+ * @param sink the report formatting tool
+ */
+ private void doChangedSets( ChangeLogSet set, ResourceBundle bundle, Sink sink )
+ {
+ sink.section2();
+ sink.sectionTitle2();
+ if ( set.getStartDate() == null )
+ {
+ sink.text( bundle.getString( "report.SetRangeUnknown" ) );
+ }
+ else if ( set.getEndDate() == null )
+ {
+ sink.text( bundle.getString( "report.SetRangeSince" ) );
+ }
+ else
+ {
+ sink.text( " " + set.getStartDate() + " " + bundle.getString( "report.To" ) + " " + set.getEndDate() );
+ sink.sectionTitle2_();
+ }
+ doSummary( set, bundle, sink );
+
+ sink.table();
+
+ sink.tableRow();
+ sink.tableHeaderCell();
+ sink.text( bundle.getString( "report.dev-activity.developer" ) );
+ sink.tableHeaderCell_();
+ sink.tableHeaderCell();
+ sink.text( bundle.getString( "report.TotalCommits" ) );
+ sink.tableHeaderCell_();
+ sink.tableHeaderCell();
+ sink.text( bundle.getString( "report.dev-activity.filesChanged" ) );
+ sink.tableHeaderCell_();
+ sink.tableRow_();
+
+ doDeveloperRows( set, sink );
+
+ sink.table_();
+
+ sink.section2_();
+ }
+
+ /**
+ * generates the report summary section of the report
+ *
+ * @param set changed set to generate the report from
+ * @param bundle the resource bundle to retrieve report phrases from
+ * @param sink the report formatting tool
+ */
+ private void doSummary( ChangeLogSet set, ResourceBundle bundle, Sink sink )
+ {
+ sink.paragraph();
+
+ sink.text( bundle.getString( "report.dev-activity.range" ) );
+ sink.text( ": " + set.getStartDate() + " " + bundle.getString( "report.To" ) + " " + set.getEndDate() );
+
+ sink.text( ", " + bundle.getString( "report.TotalCommits" ) );
+ sink.text( ":" + set.getChangeSets().size() );
+
+ sink.text( ", " + bundle.getString( "report.dev-activity.filesChanged" ) );
+ sink.text( ":" + countFilesChanged( set.getChangeSets() ) );
+
+ sink.paragraph_();
+ }
+
+ /**
+ * counts the total commits made to the given sets
+ *
+ * @param sets collection of sets to count all the commits
+ * @return total number of commits for the given sets
+ */
+ private long getCommits( Collection sets )
+ {
+ long commits = 0;
+
+ for ( Iterator i = sets.iterator(); i.hasNext(); )
+ {
+ ChangeLogSet set = (ChangeLogSet) i.next();
+
+ commits += set.getChangeSets().size();
+ }
+
+ return commits;
+ }
+
+ /**
+ * counts the total number of files changed
+ *
+ * @param sets collection of sets to count all the files changed
+ * @return total number of files changed
+ */
+ private long getFilesChanged( Collection sets )
+ {
+ long count = 0;
+
+ for ( Iterator i = sets.iterator(); i.hasNext(); )
+ {
+ ChangeLogSet set = (ChangeLogSet) i.next();
+
+ count += countFilesChanged( set.getChangeSets() );
+ }
+
+ return count;
+ }
+
+ /**
+ * generates the report section table of the developers
+ *
+ * @param set change log set generate the developer activity
+ * @param sink the report formatting tool
+ */
+ private void doDeveloperRows( ChangeLogSet set, Sink sink )
+ {
+ initDeveloperDetails( set );
+
+ //for( Iterator i=commits.keySet().iterator(); i.hasNext(); )
+ for ( Iterator i = developers.iterator(); i.hasNext(); )
+ {
+ Developer developer = (Developer) i.next();
+
+ String name = developer.getName();
+
+ String id = developer.getId();
+
+ LinkedList devCommits;
+ HashMap devFiles;
+
+ if ( !commits.containsKey( name ) )
+ {
+ if ( !commits.containsKey( id ) )
+ {
+ continue;
+ }
+ else
+ {
+ devCommits = (LinkedList) commits.get( id );
+
+ devFiles = (HashMap) files.get( id );
+ }
+ }
+ else
+ {
+ devCommits = (LinkedList) commits.get( name );
+
+ devFiles = (HashMap) files.get( name );
+ }
+
+ sink.tableRow();
+
+ sink.tableCell();
+ sink.link( "team-list.html#" + developer.getId() );
+ sink.text( name );
+ sink.link_();
+ sink.tableCell_();
+
+ sink.tableCell();
+ sink.text( "" + devCommits.size() );
+ sink.tableCell_();
+
+ sink.tableCell();
+ sink.text( "" + devFiles.size() );
+ sink.tableCell_();
+
+ sink.tableRow_();
+ }
+ }
+
+ /**
+ * counts the number of commits and files changed for each developer
+ *
+ * @param set the change log set to generate the developer details from
+ */
+ private void initDeveloperDetails( ChangeLogSet set )
+ {
+ commits = new HashMap();
+
+ files = new HashMap();
+
+ countDevCommits( set.getChangeSets() );
+
+ countDevFiles( set.getChangeSets() );
+ }
+
+ /**
+ * counts the number of commits of each developer
+ *
+ * @param entries the change log entries used to search and count developer commits
+ */
+ private void countDevCommits( Collection entries )
+ {
+ for ( Iterator i = entries.iterator(); i.hasNext(); )
+ {
+ ChangeSet entry = (ChangeSet) i.next();
+
+ String developer = entry.getAuthor();
+
+ LinkedList list;
+
+ if ( commits.containsKey( developer ) )
+ {
+ list = (LinkedList) commits.get( developer );
+ }
+ else
+ {
+ list = new LinkedList();
+ }
+
+ list.add( entry );
+
+ commits.put( developer, list );
+ }
+ }
+
+ /**
+ * counts the number of files changed by each developer
+ *
+ * @param entries the change log entries used to search and count file changes
+ */
+ private void countDevFiles( Collection entries )
+ {
+ for ( Iterator i2 = entries.iterator(); i2.hasNext(); )
+ {
+ ChangeSet entry = (ChangeSet) i2.next();
+
+ String developer = entry.getAuthor();
+
+ HashMap filesMap;
+
+ if ( files.containsKey( developer ) )
+ {
+ filesMap = (HashMap) files.get( developer );
+ }
+ else
+ {
+ filesMap = new HashMap();
+ }
+
+ for ( Iterator i3 = entry.getFiles().iterator(); i3.hasNext(); )
+ {
+ ChangeFile file = (ChangeFile) i3.next();
+
+ filesMap.put( file.getName(), file );
+ }
+
+ files.put( developer, filesMap );
+ }
+ }
+}
Propchange: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/DeveloperActivityReport.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/DeveloperActivityReport.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/FileActivityComparator.java
URL: http://svn.apache.org/viewcvs/maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/FileActivityComparator.java?rev=387745&view=auto
==============================================================================
--- maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/FileActivityComparator.java (added)
+++ maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/FileActivityComparator.java Tue Mar 21 22:02:52 2006
@@ -0,0 +1,145 @@
+package org.apache.maven.changelog;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.maven.scm.ChangeFile;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+
+/**
+ * Object used to sort the file-activity report into descending order
+ */
+public class FileActivityComparator
+ implements Comparator
+{
+ /**
+ * @see java.util.Comparator#compare(Object,Object)
+ */
+ public int compare( Object o1, Object o2 )
+ throws ClassCastException
+ {
+ int returnValue;
+
+ LinkedList list1 = (LinkedList) o1;
+
+ LinkedList list2 = (LinkedList) o2;
+
+ returnValue = sortByCommits( list1, list2 );
+
+ if ( returnValue != 0 )
+ {
+ return returnValue;
+ }
+
+ returnValue = sortByRevision( list1, list2 );
+
+ if ( returnValue != 0 )
+ {
+ return returnValue;
+ }
+
+ returnValue = sortByName( list1, list2 );
+
+ return returnValue;
+ }
+
+ /**
+ * compares list1 and list2 by the number of commits
+ *
+ * @param list1 the first object in a compare statement
+ * @param list2 the object to compare list1 against
+ * @return an integer describing the order comparison of list1 and list2
+ */
+ private int sortByCommits( List list1, List list2 )
+ {
+ if ( list1.size() > list2.size() )
+ {
+ return -1;
+ }
+
+ if ( list1.size() < list2.size() )
+ {
+ return 1;
+ }
+
+ return 0;
+ }
+
+ /**
+ * compares list1 and list2 by comparing their revision code
+ *
+ * @param list1 the first object in a compare statement
+ * @param list2 the object to compare list1 against
+ * @return an integer describing the order comparison of list1 and list2
+ */
+ private int sortByRevision( List list1, List list2 )
+ {
+ String revision1 = getLatestRevision( list1 );
+
+ String revision2 = getLatestRevision( list2 );
+
+ return revision1.compareTo( revision2 );
+ }
+
+ /**
+ * retrieves the latest revision from the commits made from the SCM
+ *
+ * @param list The list of revisions from the file
+ * @return the latest revision code
+ */
+ private String getLatestRevision( List list )
+ {
+ String latest = "";
+
+ for ( Iterator i = list.iterator(); i.hasNext(); )
+ {
+ ChangeFile file = (ChangeFile) i.next();
+
+ if ( latest.length() == 0 )
+ {
+ latest = file.getRevision();
+ }
+ else if ( latest.compareTo( file.getRevision() ) > 0 )
+ {
+ latest = file.getRevision();
+ }
+ }
+
+ return latest;
+ }
+
+ /**
+ * compares list1 and list2 by comparing their filenames. Least priority sorting when both number of commits and
+ * and revision are the same
+ *
+ * @param list1 the first object in a compare statement
+ * @param list2 the object to compare list1 against
+ * @return an integer describing the order comparison of list1 and list2
+ */
+ private int sortByName( List list1, List list2 )
+ {
+ ChangeFile file1 = (ChangeFile) list1.get( 0 );
+
+ ChangeFile file2 = (ChangeFile) list2.get( 0 );
+
+ return file1.getName().compareTo( file2.getName() );
+ }
+}
\ No newline at end of file
Propchange: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/FileActivityComparator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/FileActivityComparator.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/FileActivityReport.java
URL: http://svn.apache.org/viewcvs/maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/FileActivityReport.java?rev=387745&view=auto
==============================================================================
--- maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/FileActivityReport.java (added)
+++ maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/FileActivityReport.java Tue Mar 21 22:02:52 2006
@@ -0,0 +1,279 @@
+package org.apache.maven.changelog;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.maven.scm.ChangeFile;
+import org.apache.maven.scm.ChangeSet;
+import org.apache.maven.scm.command.changelog.ChangeLogSet;
+import org.codehaus.doxia.sink.Sink;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+/**
+ * @goal file-activity
+ * @description A Maven 2.0 file activity report plugin
+ */
+public class FileActivityReport
+ extends ChangeLogReport
+{
+ /**
+ * @see org.apache.maven.reporting.MavenReport#getDescription(java.util.Locale)
+ */
+ public String getDescription( Locale locale )
+ {
+ return "Generate file activity report from SCM";
+ }
+
+ /**
+ * @see org.apache.maven.reporting.MavenReport#getName(java.util.Locale)
+ */
+ public String getName( Locale locale )
+ {
+ return "file-activity";
+ }
+
+ /**
+ * @see org.apache.maven.reporting.MavenReport#getOutputName()
+ */
+ public String getOutputName()
+ {
+ return "file-activity";
+ }
+
+ /**
+ * generates an empty report in case there are no sources to generate a report with
+ *
+ * @param bundle the resource bundle to retrieve report phrases from
+ * @param sink the report formatting tool
+ */
+ protected void doGenerateEmptyReport( ResourceBundle bundle, Sink sink )
+ {
+ sink.head();
+ sink.title();
+ sink.text( bundle.getString( "report.file-activity.header" ) );
+ sink.title_();
+ sink.head_();
+
+ sink.body();
+ sink.section1();
+
+ sink.sectionTitle1();
+ sink.text( bundle.getString( "report.file-activity.mainTitle" ) );
+ sink.sectionTitle1_();
+
+ sink.paragraph();
+ sink.text( "No sources found to create a report." );
+ sink.paragraph_();
+
+ sink.section1_();
+
+ sink.body_();
+ sink.flush();
+ sink.close();
+ }
+
+ /**
+ * method that generates the report for this mojo.
+ *
+ * @param changeLogSets changed sets to generate the report from
+ * @param bundle the resource bundle to retrieve report phrases from
+ * @param sink the report formatting tool
+ */
+ protected void doGenerateReport( ChangeLogSet changeLogSets, ResourceBundle bundle, Sink sink )
+ {
+ sink.head();
+ sink.title();
+ sink.text( bundle.getString( "report.file-activity.header" ) );
+ sink.title_();
+ sink.head_();
+
+ sink.body();
+ sink.section1();
+ sink.sectionTitle1();
+ sink.text( bundle.getString( "report.file-activity.mainTitle" ) );
+ sink.sectionTitle1_();
+
+ doChangedSets( changeLogSets, bundle, sink );
+
+ sink.section1_();
+ sink.body_();
+
+ sink.table_();
+ }
+
+ /**
+ * generates a section of the report referring to a changeset
+ *
+ * @param set the current ChangeSet to generate this section of the report
+ * @param bundle the resource bundle to retrieve report phrases from
+ * @param sink the report formatting tool
+ */
+ private void doChangedSets( ChangeLogSet set, ResourceBundle bundle, Sink sink )
+ {
+ sink.section2();
+ sink.sectionTitle2();
+ if ( set.getStartDate() == null )
+ {
+ sink.text( bundle.getString( "report.SetRangeUnknown" ) );
+ }
+ else if ( set.getEndDate() == null )
+ {
+ sink.text( bundle.getString( "report.SetRangeSince" ) );
+ }
+ else
+ {
+ sink.text( bundle.getString( "report.SetRangeBetween" ) );
+ sink.text( " " + set.getStartDate() + " " + bundle.getString( "report.To" ) + " " + set.getEndDate() );
+ }
+ sink.sectionTitle2_();
+
+ doSummary( set, bundle, sink );
+
+ sink.table();
+
+ sink.tableRow();
+ sink.tableHeaderCell();
+ sink.text( bundle.getString( "report.file-activity.filename" ) );
+ sink.tableHeaderCell_();
+ sink.tableHeaderCell();
+ sink.text( bundle.getString( "report.file-activity.timesChanged" ) );
+ sink.tableHeaderCell_();
+ sink.tableRow_();
+
+ doRows( set, sink );
+
+ sink.table_();
+
+ sink.section2_();
+ }
+
+ /**
+ * generates the report summary section of the report
+ *
+ * @param set changed set to generate the report from
+ * @param bundle the resource bundle to retrieve report phrases from
+ * @param sink the report formatting tool
+ */
+ private void doSummary( ChangeLogSet set, ResourceBundle bundle, Sink sink )
+ {
+ sink.paragraph();
+
+ sink.text( bundle.getString( "report.file-activity.range" ) );
+ sink.text( ": " + set.getStartDate() + " " + bundle.getString( "report.To" ) + " " + set.getEndDate() );
+
+ sink.text( ", " + bundle.getString( "report.TotalCommits" ) );
+ sink.text( ":" + set.getChangeSets().size() );
+
+ sink.text( ", " + bundle.getString( "report.file-activity.filesChanged" ) );
+ sink.text( ":" + countFilesChanged( set.getChangeSets() ) );
+
+ sink.paragraph_();
+ }
+
+ /**
+ * generates the row details for the file activity report
+ *
+ * @param set the changelog set to generate a report with
+ * @param sink the report formatting tool
+ */
+ private void doRows( ChangeLogSet set, Sink sink )
+ {
+ List list = getOrderedFileList( set.getChangeSets() );
+
+ initReportUrls();
+
+ for ( Iterator i = list.iterator(); i.hasNext(); )
+ {
+ List revision = (List) i.next();
+ ChangeFile file = (ChangeFile) revision.get( 0 );
+
+ sink.tableRow();
+ sink.tableCell();
+
+ try
+ {
+ generateLinks( getConnection(), file.getName(), sink );
+ }
+ catch ( Exception e )
+ {
+ e.printStackTrace();
+
+ sink.text( file.getName() );
+ }
+ sink.tableCell_();
+
+ sink.tableCell();
+ sink.text( "" + revision.size() );
+
+ sink.tableCell_();
+ sink.tableRow_();
+ }
+ }
+
+ /**
+ * reads the change log entries and generates a list of files changed order by the number of times edited. This
+ * used the FileActivityComparator Object to sort the list
+ *
+ * @param entries the changelog entries to generate the report
+ * @return list of changed files within the SCM with the number of times changed in descending order
+ */
+ private List getOrderedFileList( Collection entries )
+ {
+ List list = new LinkedList();
+
+ Map map = new HashMap();
+
+ for ( Iterator i = entries.iterator(); i.hasNext(); )
+ {
+ ChangeSet entry = (ChangeSet) i.next();
+
+ for ( Iterator j = entry.getFiles().iterator(); j.hasNext(); )
+ {
+ ChangeFile file = (ChangeFile) j.next();
+
+ List revisions;
+
+ if ( map.containsKey( file.getName() ) )
+ {
+ revisions = (List) map.get( file.getName() );
+ }
+ else
+ {
+ revisions = new LinkedList();
+ }
+
+ revisions.add( file );
+
+ map.put( file.getName(), revisions );
+ }
+ }
+
+ list.addAll( map.values() );
+
+ Collections.sort( list, new FileActivityComparator() );
+
+ return list;
+ }
+}
Propchange: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/FileActivityReport.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/sandbox/plugins/changelog-maven-plugin/src/main/java/org/apache/maven/changelog/FileActivityReport.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: maven/sandbox/plugins/changelog-maven-plugin/src/main/resources/scm-activity.properties
URL: http://svn.apache.org/viewcvs/maven/sandbox/plugins/changelog-maven-plugin/src/main/resources/scm-activity.properties?rev=387745&view=auto
==============================================================================
--- maven/sandbox/plugins/changelog-maven-plugin/src/main/resources/scm-activity.properties (added)
+++ maven/sandbox/plugins/changelog-maven-plugin/src/main/resources/scm-activity.properties Tue Mar 21 22:02:52 2006
@@ -0,0 +1,31 @@
+#Commons
+report.SetRangeUnknown=Changes from an unknown range
+report.SetRangeSince=Changes since
+report.SetRangeBetween=Changes between
+report.To=to
+report.TotalCommits=Total commits
+
+#Changelog
+report.changelog.header=Change Log Report
+report.changelog.mainTitle=Change Log Report
+report.changelog.ChangedSetsTotal=Total number of changed sets
+report.changelog.FilesChanged=Total number of files changed
+report.changelog.timestamp=Timestamp
+report.changelog.author=Author
+report.changelog.details=Details
+report.changelog.revision=Revision
+
+#Developer Activity
+report.dev-activity.header=Developer Activity Report
+report.dev-activity.mainTitle=Developer Activity Report
+report.dev-activity.range=Range
+report.dev-activity.filesChanged=Total Number of Files Changed
+report.dev-activity.developer=Developer
+
+#File Activity
+report.file-activity.header=File Activity Report
+report.file-activity.mainTitle=File Activity Report
+report.file-activity.range=Range
+report.file-activity.filesChanged=Total Number of Files Changed
+report.file-activity.timesChanged=Number of Times Changed
+report.file-activity.filename=Filename
\ No newline at end of file
Propchange: maven/sandbox/plugins/changelog-maven-plugin/src/main/resources/scm-activity.properties
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/sandbox/plugins/changelog-maven-plugin/src/main/resources/scm-activity.properties
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"