Jalopy source code formatting - fix a bunch of pmd and checkstyle warnings
git-svn-id: https://svn.apache.org/repos/asf/maven/maven-1/plugins/trunk@370221 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
1 parent
6328abca7c
commit
b8079e792e
32 files changed
+2352
-1903
No files matched your search
@@ -19,22 +19,26 @@ package org.apache.maven.changelog;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
// maven imports
|
||||
import org.apache.maven.util.AsyncStreamReader;
|
||||
// commons imports
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
// maven imports
|
||||
import org.apache.maven.util.AsyncStreamReader;
|
||||
import org.apache.tools.ant.taskdefs.Execute;
|
||||
|
||||
// ant imports
|
||||
import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
|
||||
import org.apache.tools.ant.taskdefs.Execute;
|
||||
import org.apache.tools.ant.types.Commandline;
|
||||
|
||||
/**
|
||||
@@ -48,413 +52,447 @@ import org.apache.tools.ant.types.Commandline;
|
||||
* @author <a href="mailto:bodewig@apache.org">Stefan Bodewig</a>
|
||||
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
|
||||
* @author <a href="mailto:pete-apache-dev@kazmier.com">Pete Kazmier</a>
|
||||
* @version
|
||||
* @version
|
||||
* $Id$
|
||||
*/
|
||||
public abstract class AbstractChangeLogGenerator implements ChangeLogGenerator, ExecuteStreamHandler
|
||||
public abstract class AbstractChangeLogGenerator implements ChangeLogGenerator,
|
||||
ExecuteStreamHandler
|
||||
{
|
||||
/**
|
||||
* The working directory.
|
||||
*/
|
||||
protected File base;
|
||||
/** Log */
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog( AbstractChangeLogGenerator.class );
|
||||
|
||||
/**
|
||||
* Reference to the enclosing ChangeLog instance - used to obtain
|
||||
* any necessary configuration information.
|
||||
*/
|
||||
protected ChangeLog changeLogExecutor;
|
||||
/**
|
||||
* The working directory.
|
||||
*/
|
||||
protected File base;
|
||||
|
||||
/**
|
||||
* The parser that takes the log output and transforms it into a
|
||||
* collection of ChangeLogEntry's.
|
||||
*/
|
||||
protected ChangeLogParser clParser;
|
||||
/**
|
||||
* Reference to the enclosing ChangeLog instance - used to obtain
|
||||
* any necessary configuration information.
|
||||
*/
|
||||
protected ChangeLog changeLogExecutor;
|
||||
|
||||
/** The connection string from the project */
|
||||
private String connection;
|
||||
|
||||
/** The log type (range, date, or tag). */
|
||||
protected String type;
|
||||
/**
|
||||
* The parser that takes the log output and transforms it into a
|
||||
* collection of ChangeLogEntry's.
|
||||
*/
|
||||
protected ChangeLogParser clParser;
|
||||
|
||||
/**
|
||||
* The date range command line argument.
|
||||
*/
|
||||
protected String dateRange;
|
||||
|
||||
/** The tag command line argument. */
|
||||
protected String tag;
|
||||
|
||||
/** Represents when this log starts (for the report). */
|
||||
protected String logStart = "";
|
||||
|
||||
/** Represents when this log ends (for the report). */
|
||||
protected String logEnd = "";
|
||||
/** The connection string from the project */
|
||||
private String connection;
|
||||
|
||||
/**
|
||||
* The collection of ChangeLogEntry's returned from clParser.
|
||||
*/
|
||||
protected Collection entries;
|
||||
/** The log type (range, date, or tag). */
|
||||
protected String type;
|
||||
|
||||
/**
|
||||
* Stderr stream eater.
|
||||
*/
|
||||
protected AsyncStreamReader errorReader;
|
||||
/**
|
||||
* The date range command line argument.
|
||||
*/
|
||||
protected String dateRange;
|
||||
|
||||
/**
|
||||
* The scm process input stream.
|
||||
*/
|
||||
protected InputStream in;
|
||||
/** The tag command line argument. */
|
||||
protected String tag;
|
||||
|
||||
/**
|
||||
* The comment format string used in interrogating the RCS.
|
||||
*/
|
||||
protected String commentFormat;
|
||||
/** Represents when this log starts (for the report). */
|
||||
protected String logStart = "";
|
||||
|
||||
/** Log */
|
||||
private static final Log LOG = LogFactory.getLog(AbstractChangeLogGenerator.class);
|
||||
/** Represents when this log ends (for the report). */
|
||||
protected String logEnd = "";
|
||||
|
||||
/**
|
||||
* Initialize the generator from the changelog controller.
|
||||
*
|
||||
* @param changeLog The invoking controller (useful for logging)
|
||||
* @see ChangeLogGenerator#init(ChangeLog)
|
||||
*/
|
||||
public void init(ChangeLog changeLog)
|
||||
{
|
||||
changeLogExecutor = changeLog;
|
||||
/**
|
||||
* The collection of ChangeLogEntry's returned from clParser.
|
||||
*/
|
||||
protected Collection entries;
|
||||
|
||||
base = changeLogExecutor.getBasedir();
|
||||
|
||||
type = changeLogExecutor.getType();
|
||||
|
||||
if (type.equalsIgnoreCase("tag"))
|
||||
/**
|
||||
* Stderr stream eater.
|
||||
*/
|
||||
protected AsyncStreamReader errorReader;
|
||||
|
||||
/**
|
||||
* The scm process input stream.
|
||||
*/
|
||||
protected InputStream in;
|
||||
|
||||
/**
|
||||
* The comment format string used in interrogating the RCS.
|
||||
*/
|
||||
protected String commentFormat;
|
||||
|
||||
/**
|
||||
* Initialize the generator from the changelog controller.
|
||||
*
|
||||
* @param changeLog The invoking controller (useful for logging)
|
||||
* @see ChangeLogGenerator#init(ChangeLog)
|
||||
*/
|
||||
public void init( ChangeLog changeLog )
|
||||
{
|
||||
tag = getScmTagArgument(changeLogExecutor.getMarkerStart(), changeLogExecutor.getMarkerEnd());
|
||||
logStart = changeLogExecutor.getMarkerStart();
|
||||
logEnd = (changeLogExecutor.getMarkerEnd() == null) ? "" : changeLogExecutor.getMarkerEnd();
|
||||
}
|
||||
else if (type.equalsIgnoreCase("date"))
|
||||
{
|
||||
setDateRangeFromAbsoluteDate(changeLogExecutor.getMarkerStart(), changeLogExecutor.getMarkerEnd());
|
||||
}
|
||||
else // type == "range" (the default)
|
||||
{
|
||||
// This lets the user 'not' set a limit on the log command. We
|
||||
// need this cuz Subversion doesn't currently support date
|
||||
// commands on web-based repositories, so it would be nice to
|
||||
// let the user still use the changelog plugin.
|
||||
if (changeLogExecutor.getRange() != null && changeLogExecutor.getRange().length() != 0)
|
||||
changeLogExecutor = changeLog;
|
||||
|
||||
base = changeLogExecutor.getBasedir();
|
||||
|
||||
type = changeLogExecutor.getType();
|
||||
|
||||
if ( type.equalsIgnoreCase( "tag" ) )
|
||||
{
|
||||
setDateRange(changeLogExecutor.getRange());
|
||||
tag = getScmTagArgument( changeLogExecutor.getMarkerStart(),
|
||||
changeLogExecutor.getMarkerEnd() );
|
||||
logStart = changeLogExecutor.getMarkerStart();
|
||||
logEnd =
|
||||
( changeLogExecutor.getMarkerEnd() == null ) ? ""
|
||||
: changeLogExecutor
|
||||
.getMarkerEnd();
|
||||
}
|
||||
else if ( type.equalsIgnoreCase( "date" ) )
|
||||
{
|
||||
setDateRangeFromAbsoluteDate( changeLogExecutor.getMarkerStart(),
|
||||
changeLogExecutor.getMarkerEnd() );
|
||||
}
|
||||
else // type == "range" (the default)
|
||||
{
|
||||
// This lets the user 'not' set a limit on the log command. We
|
||||
// need this cuz Subversion doesn't currently support date
|
||||
// commands on web-based repositories, so it would be nice to
|
||||
// let the user still use the changelog plugin.
|
||||
if ( ( changeLogExecutor.getRange() != null )
|
||||
&& ( changeLogExecutor.getRange().length() != 0 ) )
|
||||
{
|
||||
setDateRange( changeLogExecutor.getRange() );
|
||||
}
|
||||
}
|
||||
|
||||
setConnection( changeLogExecutor.getRepositoryConnection() );
|
||||
|
||||
// set the comment query string for the RCS.
|
||||
setCommentFormat( changeLogExecutor.getCommentFormat() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dateRange member based on the number of days obtained
|
||||
* from the ChangeLog.
|
||||
*
|
||||
* @param numDaysString The number of days of log output to
|
||||
* generate.
|
||||
*/
|
||||
protected void setDateRange( String numDaysString )
|
||||
{
|
||||
int days = Integer.parseInt( numDaysString );
|
||||
|
||||
Date before =
|
||||
new Date( System.currentTimeMillis()
|
||||
- ( (long) days * 24 * 60 * 60 * 1000 ) );
|
||||
Date to =
|
||||
new Date( System.currentTimeMillis()
|
||||
+ ( (long) 1 * 24 * 60 * 60 * 1000 ) );
|
||||
|
||||
dateRange = getScmDateArgument( before, to );
|
||||
setLogStart( before );
|
||||
setLogEnd( to );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dateRange member based on an absolute date.
|
||||
* @param startDate The start date for the range.
|
||||
* @param endDate The end date for the range, or <code>null</code> to use the present time.
|
||||
*/
|
||||
protected void setDateRangeFromAbsoluteDate( String startDate,
|
||||
String endDate )
|
||||
{
|
||||
String dateFormat = changeLogExecutor.getDateFormat();
|
||||
SimpleDateFormat format =
|
||||
( dateFormat == null ) ? new SimpleDateFormat( "yyyy-MM-dd" )
|
||||
: new SimpleDateFormat( dateFormat );
|
||||
|
||||
Date before;
|
||||
|
||||
try
|
||||
{
|
||||
before = format.parse( startDate );
|
||||
}
|
||||
catch ( ParseException ex )
|
||||
{
|
||||
throw new IllegalArgumentException( "Unable to parse start date "
|
||||
+ startDate + ": " + ex.getLocalizedMessage() );
|
||||
}
|
||||
|
||||
Date to;
|
||||
|
||||
try
|
||||
{
|
||||
to = ( endDate != null ) ? format.parse( endDate )
|
||||
: new Date( System.currentTimeMillis()
|
||||
+ ( (long) 1 * 24 * 60 * 60 * 1000 ) );
|
||||
}
|
||||
catch ( ParseException ex )
|
||||
{
|
||||
throw new IllegalArgumentException( "Unable to parse end date "
|
||||
+ endDate + ": " + ex.getLocalizedMessage() );
|
||||
}
|
||||
|
||||
dateRange = getScmDateArgument( before, to );
|
||||
setLogStart( before );
|
||||
setLogEnd( to );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the log start string based on the given date.
|
||||
* This uses the date format supplied in the plugin properties.
|
||||
*
|
||||
* @param start date the log started.
|
||||
*/
|
||||
protected void setLogStart( Date start )
|
||||
{
|
||||
String dateFormat = changeLogExecutor.getDateFormat();
|
||||
SimpleDateFormat format =
|
||||
( dateFormat == null ) ? new SimpleDateFormat( "yyyy-MM-dd" )
|
||||
: new SimpleDateFormat( dateFormat );
|
||||
|
||||
logStart = format.format( start );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the log end string based on the given date.
|
||||
* This uses the date format supplied in the plugin properties.
|
||||
*
|
||||
* @param end date the log ended.
|
||||
*/
|
||||
protected void setLogEnd( Date end )
|
||||
{
|
||||
String dateFormat = changeLogExecutor.getDateFormat();
|
||||
SimpleDateFormat format =
|
||||
( dateFormat == null ) ? new SimpleDateFormat( "yyyy-MM-dd" )
|
||||
: new SimpleDateFormat( dateFormat );
|
||||
|
||||
logEnd = format.format( end );
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute scm client driving the given parser.
|
||||
*
|
||||
* @param parser A {@link ChangeLogParser parser} to process the scm
|
||||
* output.
|
||||
* @return A collection of {@link ChangeLogEntry entries} parsed from
|
||||
* the scm output.
|
||||
* @throws IOException When there are issues executing scm.
|
||||
* @see ChangeLogGenerator#getEntries(ChangeLogParser)
|
||||
*/
|
||||
public Collection getEntries( ChangeLogParser parser )
|
||||
throws IOException
|
||||
{
|
||||
if ( parser == null )
|
||||
{
|
||||
throw new NullPointerException( "parser cannot be null" );
|
||||
}
|
||||
|
||||
if ( base == null )
|
||||
{
|
||||
throw new NullPointerException( "basedir must be set" );
|
||||
}
|
||||
|
||||
if ( !base.exists() )
|
||||
{
|
||||
throw new FileNotFoundException( "Cannot find base dir "
|
||||
+ base.getAbsolutePath() );
|
||||
}
|
||||
|
||||
clParser = parser;
|
||||
|
||||
try
|
||||
{
|
||||
Execute exe = new Execute( this );
|
||||
|
||||
exe.setCommandline( getScmLogCommand().getCommandline() );
|
||||
exe.setWorkingDirectory( base );
|
||||
logExecute( exe, base );
|
||||
|
||||
exe.execute();
|
||||
|
||||
// log messages from stderr
|
||||
String errors = errorReader.toString().trim();
|
||||
|
||||
if ( errors.length() > 0 )
|
||||
{
|
||||
LOG.error( errors );
|
||||
}
|
||||
}
|
||||
catch ( IOException ioe )
|
||||
{
|
||||
handleParserException( ioe );
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle ChangeLogParser IOExceptions. The default implementation
|
||||
* just throws the exception again.
|
||||
*
|
||||
* @param ioe The IOException thrown.
|
||||
* @throws IOException If the handler doesn't wish to handle the
|
||||
* exception (the default behavior).
|
||||
*/
|
||||
protected void handleParserException( IOException ioe )
|
||||
throws IOException
|
||||
{
|
||||
throw ioe;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ChangeLogGenerator#getLogStart()
|
||||
*/
|
||||
public String getLogStart()
|
||||
{
|
||||
return logStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ChangeLogGenerator#getLogEnd()
|
||||
*/
|
||||
public String getLogEnd()
|
||||
{
|
||||
// TODO: Auto-generated method stub
|
||||
return logEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up any generated resources for this run.
|
||||
*
|
||||
* @see ChangeLogGenerator#cleanup()
|
||||
*/
|
||||
public void cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the appropriate command line to execute the scm's
|
||||
* log command. This method must be implemented by subclasses.
|
||||
*
|
||||
* @return The command line to be executed.
|
||||
*/
|
||||
protected abstract Commandline getScmLogCommand();
|
||||
|
||||
/**
|
||||
* Construct the command-line argument that is passed to the scm
|
||||
* client to specify the appropriate date range.
|
||||
*
|
||||
* @param before The starting point.
|
||||
* @param to The ending point.
|
||||
* @return A string that can be used to specify a date to a scm
|
||||
* system.
|
||||
*/
|
||||
protected abstract String getScmDateArgument( Date before, Date to );
|
||||
|
||||
/**
|
||||
* Construct the command-line argument that is passed to the scm
|
||||
* client to specify the appropriate tag.
|
||||
*
|
||||
* @param tagStart The tag name for the start of the log (log shouldn't actually contain the tag).
|
||||
* @param tagEnd The tag name for the end of the log (the log can contain this tag), or <code>null</code> to
|
||||
* log all changes since <code>tagStart</code>.
|
||||
* @return A string that can be used to specify the tag range to a scm system.
|
||||
*/
|
||||
protected abstract String getScmTagArgument( String tagStart, String tagEnd );
|
||||
|
||||
/**
|
||||
* Stop the process - currently unimplemented
|
||||
*/
|
||||
public void stop()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the input stream for the scm process.
|
||||
* @param os An {@link java.io.OutputStream}
|
||||
*/
|
||||
public void setProcessInputStream( OutputStream os )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the error stream for reading from scm log. This stream will
|
||||
* be read on a separate thread.
|
||||
*
|
||||
* @param is An {@link java.io.InputStream}
|
||||
*/
|
||||
public void setProcessErrorStream( InputStream is )
|
||||
{
|
||||
errorReader = new AsyncStreamReader( is );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the input stream used to read from scm log.
|
||||
*
|
||||
* @param is A stream of scm log output to be read from
|
||||
*/
|
||||
public void setProcessOutputStream( InputStream is )
|
||||
{
|
||||
in = is;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start read from the scm log.
|
||||
*
|
||||
* @throws IOException When there are errors reading from the
|
||||
* streams previously provided
|
||||
*/
|
||||
public void start() throws IOException
|
||||
{
|
||||
errorReader.start();
|
||||
entries = clParser.parse( in );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the connection.
|
||||
* @return String
|
||||
*/
|
||||
public String getConnection()
|
||||
{
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the connection.
|
||||
* @param connection The connection to set
|
||||
*/
|
||||
public void setConnection( String connection )
|
||||
{
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the commentFormat used to interrogate the RCS.
|
||||
* @return String
|
||||
*/
|
||||
public String getCommentFormat()
|
||||
{
|
||||
return commentFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the commentFormat.
|
||||
* @param commentFormat The commentFormat to set
|
||||
*/
|
||||
public void setCommentFormat( String commentFormat )
|
||||
{
|
||||
this.commentFormat = commentFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the pertinent details to the logging system (info level)
|
||||
* @param exe The object to log
|
||||
* @param base The working directory
|
||||
*/
|
||||
public static void logExecute( Execute exe, File base )
|
||||
{
|
||||
String[] c = exe.getCommandline();
|
||||
|
||||
LOG.info( "SCM Working Directory: " + base );
|
||||
|
||||
for ( int i = 0; i < c.length; i++ )
|
||||
{
|
||||
String string = c[i];
|
||||
|
||||
LOG.info( "SCM Command Line[" + i + "]: " + string );
|
||||
}
|
||||
}
|
||||
|
||||
setConnection(changeLogExecutor.getRepositoryConnection());
|
||||
|
||||
// set the comment query string for the RCS.
|
||||
setCommentFormat(changeLogExecutor.getCommentFormat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dateRange member based on the number of days obtained
|
||||
* from the ChangeLog.
|
||||
*
|
||||
* @param numDaysString The number of days of log output to
|
||||
* generate.
|
||||
*/
|
||||
protected void setDateRange(String numDaysString)
|
||||
{
|
||||
int days = Integer.parseInt(numDaysString);
|
||||
|
||||
Date before = new Date(System.currentTimeMillis() - (long) days * 24 * 60 * 60 * 1000);
|
||||
Date to = new Date(System.currentTimeMillis() + (long) 1 * 24 * 60 * 60 * 1000);
|
||||
|
||||
dateRange = getScmDateArgument(before, to);
|
||||
setLogStart(before);
|
||||
setLogEnd(to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dateRange member based on an absolute date.
|
||||
* @param startDate The start date for the range.
|
||||
* @param endDate The end date for the range, or <code>null</code> to use the present time.
|
||||
*/
|
||||
protected void setDateRangeFromAbsoluteDate(String startDate, String endDate)
|
||||
{
|
||||
String dateFormat = changeLogExecutor.getDateFormat();
|
||||
SimpleDateFormat format = dateFormat == null ? new SimpleDateFormat("yyyy-MM-dd") : new SimpleDateFormat(dateFormat);
|
||||
|
||||
Date before;
|
||||
try
|
||||
{
|
||||
before = format.parse(startDate);
|
||||
}
|
||||
catch (ParseException ex)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to parse start date " + startDate + ": " + ex.getLocalizedMessage());
|
||||
}
|
||||
Date to;
|
||||
try
|
||||
{
|
||||
to = (endDate != null) ? format.parse(endDate) : new Date(System.currentTimeMillis() + (long) 1 * 24 * 60 * 60 * 1000);
|
||||
}
|
||||
catch (ParseException ex)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to parse end date " + endDate + ": " + ex.getLocalizedMessage());
|
||||
}
|
||||
|
||||
dateRange = getScmDateArgument(before, to);
|
||||
setLogStart(before);
|
||||
setLogEnd(to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the log start string based on the given date.
|
||||
* This uses the date format supplied in the plugin properties.
|
||||
*
|
||||
* @param start date the log started.
|
||||
*/
|
||||
protected void setLogStart(Date start)
|
||||
{
|
||||
String dateFormat = changeLogExecutor.getDateFormat();
|
||||
SimpleDateFormat format = dateFormat == null ? new SimpleDateFormat("yyyy-MM-dd") : new SimpleDateFormat(dateFormat);
|
||||
|
||||
logStart = format.format(start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the log end string based on the given date.
|
||||
* This uses the date format supplied in the plugin properties.
|
||||
*
|
||||
* @param end date the log ended.
|
||||
*/
|
||||
protected void setLogEnd(Date end)
|
||||
{
|
||||
String dateFormat = changeLogExecutor.getDateFormat();
|
||||
SimpleDateFormat format = dateFormat == null ? new SimpleDateFormat("yyyy-MM-dd") : new SimpleDateFormat(dateFormat);
|
||||
|
||||
logEnd = format.format(end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute scm client driving the given parser.
|
||||
*
|
||||
* @param parser A {@link ChangeLogParser parser} to process the scm
|
||||
* output.
|
||||
* @return A collection of {@link ChangeLogEntry entries} parsed from
|
||||
* the scm output.
|
||||
* @throws IOException When there are issues executing scm.
|
||||
* @see ChangeLogGenerator#getEntries(ChangeLogParser)
|
||||
*/
|
||||
public Collection getEntries(ChangeLogParser parser) throws IOException
|
||||
{
|
||||
if (parser == null)
|
||||
{
|
||||
throw new NullPointerException("parser cannot be null");
|
||||
}
|
||||
|
||||
if (base == null)
|
||||
{
|
||||
throw new NullPointerException("basedir must be set");
|
||||
}
|
||||
|
||||
if (!base.exists())
|
||||
{
|
||||
throw new FileNotFoundException("Cannot find base dir " + base.getAbsolutePath());
|
||||
}
|
||||
|
||||
clParser = parser;
|
||||
try
|
||||
{
|
||||
Execute exe = new Execute(this);
|
||||
exe.setCommandline(getScmLogCommand().getCommandline());
|
||||
exe.setWorkingDirectory(base);
|
||||
logExecute(exe, base);
|
||||
|
||||
exe.execute();
|
||||
|
||||
// log messages from stderr
|
||||
String errors = errorReader.toString().trim();
|
||||
if (errors.length() > 0)
|
||||
{
|
||||
LOG.error(errors);
|
||||
}
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
handleParserException(ioe);
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle ChangeLogParser IOExceptions. The default implementation
|
||||
* just throws the exception again.
|
||||
*
|
||||
* @param ioe The IOException thrown.
|
||||
* @throws IOException If the handler doesn't wish to handle the
|
||||
* exception (the default behavior).
|
||||
*/
|
||||
protected void handleParserException(IOException ioe) throws IOException
|
||||
{
|
||||
throw ioe;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ChangeLogGenerator#getLogStart()
|
||||
*/
|
||||
public String getLogStart()
|
||||
{
|
||||
return logStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ChangeLogGenerator#getLogEnd()
|
||||
*/
|
||||
public String getLogEnd()
|
||||
{
|
||||
// TODO: Auto-generated method stub
|
||||
return logEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up any generated resources for this run.
|
||||
*
|
||||
* @see ChangeLogGenerator#cleanup()
|
||||
*/
|
||||
public void cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the appropriate command line to execute the scm's
|
||||
* log command. This method must be implemented by subclasses.
|
||||
*
|
||||
* @return The command line to be executed.
|
||||
*/
|
||||
protected abstract Commandline getScmLogCommand();
|
||||
|
||||
/**
|
||||
* Construct the command-line argument that is passed to the scm
|
||||
* client to specify the appropriate date range.
|
||||
*
|
||||
* @param before The starting point.
|
||||
* @param to The ending point.
|
||||
* @return A string that can be used to specify a date to a scm
|
||||
* system.
|
||||
*/
|
||||
protected abstract String getScmDateArgument(Date before, Date to);
|
||||
|
||||
/**
|
||||
* Construct the command-line argument that is passed to the scm
|
||||
* client to specify the appropriate tag.
|
||||
*
|
||||
* @param tagStart The tag name for the start of the log (log shouldn't actually contain the tag).
|
||||
* @param tagEnd The tag name for the end of the log (the log can contain this tag), or <code>null</code> to
|
||||
* log all changes since <code>tagStart</code>.
|
||||
* @return A string that can be used to specify the tag range to a scm system.
|
||||
*/
|
||||
protected abstract String getScmTagArgument(String tagStart, String tagEnd);
|
||||
|
||||
/**
|
||||
* Stop the process - currently unimplemented
|
||||
*/
|
||||
public void stop()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the input stream for the scm process.
|
||||
* @param os An {@link java.io.OutputStream}
|
||||
*/
|
||||
public void setProcessInputStream(OutputStream os)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the error stream for reading from scm log. This stream will
|
||||
* be read on a separate thread.
|
||||
*
|
||||
* @param is An {@link java.io.InputStream}
|
||||
*/
|
||||
public void setProcessErrorStream(InputStream is)
|
||||
{
|
||||
errorReader = new AsyncStreamReader(is);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the input stream used to read from scm log.
|
||||
*
|
||||
* @param is A stream of scm log output to be read from
|
||||
*/
|
||||
public void setProcessOutputStream(InputStream is)
|
||||
{
|
||||
in = is;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start read from the scm log.
|
||||
*
|
||||
* @throws IOException When there are errors reading from the
|
||||
* streams previously provided
|
||||
*/
|
||||
public void start() throws IOException
|
||||
{
|
||||
errorReader.start();
|
||||
entries = clParser.parse(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the connection.
|
||||
* @return String
|
||||
*/
|
||||
public String getConnection()
|
||||
{
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the connection.
|
||||
* @param connection The connection to set
|
||||
*/
|
||||
public void setConnection(String connection)
|
||||
{
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the commentFormat used to interrogate the RCS.
|
||||
* @return String
|
||||
*/
|
||||
public String getCommentFormat()
|
||||
{
|
||||
return commentFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the commentFormat.
|
||||
* @param commentFormat The commentFormat to set
|
||||
*/
|
||||
public void setCommentFormat(String commentFormat)
|
||||
{
|
||||
this.commentFormat = commentFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the pertinent details to the logging system (info level)
|
||||
* @param exe The object to log
|
||||
* @param base The working directory
|
||||
*/
|
||||
public static void logExecute(Execute exe, File base)
|
||||
{
|
||||
String c[] = exe.getCommandline();
|
||||
LOG.info("SCM Working Directory: " + base);
|
||||
for (int i = 0; i < c.length; i++)
|
||||
{
|
||||
String string = c[i];
|
||||
LOG.info("SCM Command Line[" + i + "]: " + string);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -55,34 +56,52 @@ import org.apache.maven.project.Developer;
|
||||
*/
|
||||
public class ChangeLog
|
||||
{
|
||||
private static final Map FACTORIES = new HashMap();
|
||||
|
||||
/** Log */
|
||||
private static final Log LOG = LogFactory.getLog( ChangeLog.class );
|
||||
|
||||
static
|
||||
{
|
||||
FACTORIES.put( "cvs", "org.apache.maven.cvslib.CvsChangeLogFactory" );
|
||||
FACTORIES.put( "svn", "org.apache.maven.svnlib.SvnChangeLogFactory" );
|
||||
FACTORIES.put( "clearcase",
|
||||
"org.apache.maven.clearcaselib.ClearcaseChangeLogFactory" );
|
||||
FACTORIES.put( "perforce",
|
||||
"org.apache.maven.perforcelib.PerforceChangeLogFactory" );
|
||||
FACTORIES.put( "starteam",
|
||||
"org.apache.maven.starteamlib.StarteamChangeLogFactory" );
|
||||
FACTORIES.put( "vss", "org.apache.maven.vsslib.VssChangeLogFactory" );
|
||||
}
|
||||
|
||||
/** Used to specify whether to build the log from a range, absolute date, or tag. */
|
||||
private String type;
|
||||
|
||||
|
||||
/**
|
||||
* Used to specify the range of log entries to retrieve.
|
||||
*/
|
||||
private String range;
|
||||
|
||||
|
||||
/** Used to specify the absolute date (or list of dates) to start log entries from. */
|
||||
private String date;
|
||||
|
||||
|
||||
/** Used to specify the tag (or list of tags) to start log entries from. */
|
||||
private String tag;
|
||||
|
||||
|
||||
/** This will contain the date/tag for the start of the current change set. */
|
||||
private String markerStart;
|
||||
|
||||
|
||||
/** This will contain the date/tag for the end of the current change set. */
|
||||
private String markerEnd;
|
||||
|
||||
/**
|
||||
* Used to specify the date format of log entries to retrieve.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used to specify the date format of log entries to retrieve.
|
||||
*/
|
||||
private String dateFormat;
|
||||
|
||||
/**
|
||||
* Specifies whether to quote date argument (used by CvsChangeLogGenerator).
|
||||
*/
|
||||
/**
|
||||
* Specifies whether to quote date argument (used by CvsChangeLogGenerator).
|
||||
*/
|
||||
private boolean quoteDate;
|
||||
|
||||
/**
|
||||
@@ -96,38 +115,23 @@ public class ChangeLog
|
||||
*/
|
||||
private String clFactoryClass = null;
|
||||
|
||||
private static final Map FACTORIES = new HashMap();
|
||||
|
||||
/** the connection string used to access the SCM */
|
||||
private String connection;
|
||||
|
||||
|
||||
/** the list of developers on the project */
|
||||
private List developers;
|
||||
|
||||
|
||||
/** change log sets parsed (sets of entries) */
|
||||
private Collection sets;
|
||||
|
||||
/** Log */
|
||||
private static final Log LOG = LogFactory.getLog(ChangeLog.class);
|
||||
|
||||
/**
|
||||
* Output file for xml document
|
||||
*/
|
||||
private File output;
|
||||
|
||||
|
||||
/** output encoding for the xml document */
|
||||
private String outputEncoding;
|
||||
|
||||
static
|
||||
{
|
||||
FACTORIES.put( "cvs", "org.apache.maven.cvslib.CvsChangeLogFactory" );
|
||||
FACTORIES.put( "svn", "org.apache.maven.svnlib.SvnChangeLogFactory" );
|
||||
FACTORIES.put( "clearcase", "org.apache.maven.clearcaselib.ClearcaseChangeLogFactory" );
|
||||
FACTORIES.put( "perforce", "org.apache.maven.perforcelib.PerforceChangeLogFactory" );
|
||||
FACTORIES.put( "starteam", "org.apache.maven.starteamlib.StarteamChangeLogFactory" );
|
||||
FACTORIES.put( "vss", "org.apache.maven.vsslib.VssChangeLogFactory" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Comment format string used for interrogating
|
||||
* the revision control system.
|
||||
@@ -141,24 +145,24 @@ public class ChangeLog
|
||||
*
|
||||
* @param factoryClassName the fully qualified factory class name
|
||||
*/
|
||||
public void setFactory(String factoryClassName)
|
||||
public void setFactory( String factoryClassName )
|
||||
{
|
||||
clFactoryClass = factoryClassName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the type of log to generate (range, date, or tag).
|
||||
*
|
||||
*
|
||||
* @param type one of "range", "date", or "tag".
|
||||
*/
|
||||
public void setType(String type)
|
||||
public void setType( String type )
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the type of log to generate (range, date, or tag).
|
||||
*
|
||||
*
|
||||
* @return the basis for the log.
|
||||
*/
|
||||
public String getType()
|
||||
@@ -167,10 +171,10 @@ public class ChangeLog
|
||||
{
|
||||
type = "range";
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the range of log entries to process; the interpretation of this
|
||||
* parameter depends on the generator.
|
||||
@@ -178,7 +182,7 @@ public class ChangeLog
|
||||
*
|
||||
* @param range the range of log entries.
|
||||
*/
|
||||
public void setRange(String range)
|
||||
public void setRange( String range )
|
||||
{
|
||||
this.range = range;
|
||||
}
|
||||
@@ -193,45 +197,43 @@ public class ChangeLog
|
||||
{
|
||||
return range;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the date to start the log from.
|
||||
* This is only used if the type is "date".
|
||||
* The format is that given by the dateFormat property, if present. Otherwise, the format is "yyyy-MM-dd".
|
||||
*
|
||||
*
|
||||
* @param date the date to use.
|
||||
*/
|
||||
public void setDate(String date)
|
||||
public void setDate( String date )
|
||||
{
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the date to start the log from.
|
||||
*
|
||||
*
|
||||
* @return the start date.
|
||||
*/
|
||||
public String getDate()
|
||||
{
|
||||
return date;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the tag to start the log from.
|
||||
* This is only used if the type is "tag".
|
||||
*
|
||||
*
|
||||
* @param tag the tag to use.
|
||||
*/
|
||||
public void setTag(String tag)
|
||||
public void setTag( String tag )
|
||||
{
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the tag to start the log from.
|
||||
*
|
||||
*
|
||||
* @return the tag.
|
||||
*/
|
||||
public String getTag()
|
||||
@@ -239,22 +241,21 @@ public class ChangeLog
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the marker (date or tag) for the start of the current change set.
|
||||
* (This is only set internally, but also by test code.)
|
||||
*
|
||||
*
|
||||
* @param marker start marker to use.
|
||||
*/
|
||||
public void setMarkerStart(String marker)
|
||||
public void setMarkerStart( String marker )
|
||||
{
|
||||
markerStart = marker;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the marker (date or tag) for the start of the current change set.
|
||||
* Whether it's a date or tag depends on {@link #getType}.
|
||||
*
|
||||
*
|
||||
* @return the marker (date or tag) for the start of the current change set.
|
||||
*/
|
||||
public String getMarkerStart()
|
||||
@@ -265,18 +266,18 @@ public class ChangeLog
|
||||
/**
|
||||
* Sets the marker (date or tag) for the end of the current change set.
|
||||
* (This is only set internally, but also by test code.)
|
||||
*
|
||||
*
|
||||
* @param marker end marker to use, or <code>null</code> to specify all changes since the start.
|
||||
*/
|
||||
public void setMarkerEnd(String marker)
|
||||
public void setMarkerEnd( String marker )
|
||||
{
|
||||
markerEnd = marker;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the marker (date or tag) for the end of the current change set.
|
||||
* Whether it's a date or tag depends on {@link #getType}.
|
||||
*
|
||||
*
|
||||
* @return the marker (date or tag) for the end of the current change set, or <code>null</code> if there is no
|
||||
* end (meaning the change set should show all changes from the start to the present time).
|
||||
*/
|
||||
@@ -285,14 +286,13 @@ public class ChangeLog
|
||||
return markerEnd;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the date format of log entries to process; the
|
||||
* interpretation of this parameter depends on the generator.
|
||||
*
|
||||
* @param dateFormat the dateFormat of log entries.
|
||||
*/
|
||||
public void setDateFormat(String dateFormat)
|
||||
public void setDateFormat( String dateFormat )
|
||||
{
|
||||
this.dateFormat = dateFormat;
|
||||
}
|
||||
@@ -312,7 +312,7 @@ public class ChangeLog
|
||||
* Set the quoteDate property.
|
||||
* @param newQuoteDate the quoteDate property to set.
|
||||
*/
|
||||
public void setQuoteDate(boolean newQuoteDate)
|
||||
public void setQuoteDate( boolean newQuoteDate )
|
||||
{
|
||||
this.quoteDate = newQuoteDate;
|
||||
}
|
||||
@@ -331,7 +331,7 @@ public class ChangeLog
|
||||
* Set the base directory for the change log generator.
|
||||
* @param base the base directory
|
||||
*/
|
||||
public void setBasedir(File base)
|
||||
public void setBasedir( File base )
|
||||
{
|
||||
this.base = base;
|
||||
}
|
||||
@@ -350,7 +350,7 @@ public class ChangeLog
|
||||
* Set the output file for the log.
|
||||
* @param output the output file
|
||||
*/
|
||||
public void setOutput(File output)
|
||||
public void setOutput( File output )
|
||||
{
|
||||
this.output = output;
|
||||
}
|
||||
@@ -369,11 +369,11 @@ public class ChangeLog
|
||||
* @param aString a string containing the project's repository
|
||||
* connection
|
||||
*/
|
||||
public void setRepositoryConnection(String aString)
|
||||
public void setRepositoryConnection( String aString )
|
||||
{
|
||||
connection = aString;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute task.
|
||||
* @throws FileNotFoundException if the base diretory
|
||||
@@ -382,34 +382,36 @@ public class ChangeLog
|
||||
* @throws UnsupportedEncodingException if the underlying platform doesn't
|
||||
* support ISO-8859-1 encoding
|
||||
*/
|
||||
public void doExecute() throws FileNotFoundException, IOException,
|
||||
UnsupportedEncodingException
|
||||
public void doExecute()
|
||||
throws FileNotFoundException, IOException, UnsupportedEncodingException
|
||||
{
|
||||
if (output == null)
|
||||
if ( output == null )
|
||||
{
|
||||
throw new NullPointerException("output must be set");
|
||||
throw new NullPointerException( "output must be set" );
|
||||
}
|
||||
|
||||
generateSets();
|
||||
replaceAuthorIdWithName();
|
||||
createDocument();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the change log entries.
|
||||
* @throws IOException if there is a problem creating the change log
|
||||
* entries.
|
||||
*/
|
||||
private void generateSets() throws IOException
|
||||
private void generateSets()
|
||||
throws IOException
|
||||
{
|
||||
ChangeLogFactory factory = createFactory();
|
||||
|
||||
|
||||
String markers = "";
|
||||
if (getType().equalsIgnoreCase("tag"))
|
||||
|
||||
if ( getType().equalsIgnoreCase( "tag" ) )
|
||||
{
|
||||
markers = getTag();
|
||||
}
|
||||
else if (getType().equalsIgnoreCase("date"))
|
||||
else if ( getType().equalsIgnoreCase( "date" ) )
|
||||
{
|
||||
markers = getDate();
|
||||
}
|
||||
@@ -417,39 +419,49 @@ public class ChangeLog
|
||||
{
|
||||
markers = getRange();
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
StringTokenizer tokens = new StringTokenizer(markers, ",");
|
||||
sets = new ArrayList(tokens.countTokens());
|
||||
StringTokenizer tokens = new StringTokenizer( markers, "," );
|
||||
|
||||
sets = new ArrayList( tokens.countTokens() );
|
||||
|
||||
String end = tokens.nextToken();
|
||||
|
||||
do
|
||||
{
|
||||
String start = end;
|
||||
end = (tokens.hasMoreTokens()) ? tokens.nextToken() : null;
|
||||
setMarkerStart(start);
|
||||
setMarkerEnd(end);
|
||||
|
||||
end = ( tokens.hasMoreTokens() ) ? tokens.nextToken() : null;
|
||||
setMarkerStart( start );
|
||||
setMarkerEnd( end );
|
||||
|
||||
ChangeLogParser parser = factory.createParser();
|
||||
if (getDateFormat() != null)
|
||||
|
||||
if ( getDateFormat() != null )
|
||||
{
|
||||
parser.setDateFormatInFile(getDateFormat());
|
||||
parser.setDateFormatInFile( getDateFormat() );
|
||||
}
|
||||
parser.init(this);
|
||||
|
||||
parser.init( this );
|
||||
|
||||
ChangeLogGenerator generator = factory.createGenerator();
|
||||
generator.init(this);
|
||||
|
||||
|
||||
generator.init( this );
|
||||
|
||||
Collection entries;
|
||||
String logStart;
|
||||
String logEnd;
|
||||
|
||||
try
|
||||
{
|
||||
entries = generator.getEntries(parser);
|
||||
entries = generator.getEntries( parser );
|
||||
logStart = generator.getLogStart();
|
||||
logEnd = generator.getLogEnd();
|
||||
} catch (IOException e) {
|
||||
LOG.warn(e.getLocalizedMessage(), e);
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
LOG.warn( e.getLocalizedMessage(), e );
|
||||
throw e;
|
||||
}
|
||||
finally
|
||||
@@ -463,12 +475,15 @@ public class ChangeLog
|
||||
entries = Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
sets.add(new ChangeLogSet(entries, logStart, logEnd));
|
||||
if (LOG.isInfoEnabled()) {
|
||||
LOG.info("ChangeSet between " + logStart + " and " + logEnd + ": "
|
||||
+ entries.size() + " entries");
|
||||
sets.add( new ChangeLogSet( entries, logStart, logEnd ) );
|
||||
|
||||
if ( LOG.isInfoEnabled() )
|
||||
{
|
||||
LOG.info( "ChangeSet between " + logStart + " and "
|
||||
+ logEnd + ": " + entries.size() + " entries" );
|
||||
}
|
||||
} while (end != null);
|
||||
}
|
||||
while ( end != null );
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -482,48 +497,54 @@ public class ChangeLog
|
||||
* @return the new ChangeLogFactory instance
|
||||
* @throws IOException if there is a problem creating the instance.
|
||||
*/
|
||||
private ChangeLogFactory createFactory() throws IOException
|
||||
private ChangeLogFactory createFactory()
|
||||
throws IOException
|
||||
{
|
||||
if ( clFactoryClass == null )
|
||||
{
|
||||
if ( connection == null || connection.length() < 7 || !connection.startsWith( "scm:" ) )
|
||||
if ( ( connection == null ) || ( connection.length() < 7 )
|
||||
|| !connection.startsWith( "scm:" ) )
|
||||
{
|
||||
LOG.warn( "Connection does not appear valid" );
|
||||
}
|
||||
else
|
||||
{
|
||||
clFactoryClass = (String) FACTORIES.get( connection.substring( 4, 7 ) );
|
||||
clFactoryClass =
|
||||
(String) FACTORIES.get( connection.substring( 4, 7 ) );
|
||||
}
|
||||
|
||||
if ( clFactoryClass == null )
|
||||
{
|
||||
LOG.warn( "Could not derive factory from connection: using CVS (valid factories are: " + FACTORIES.keySet() + ")" );
|
||||
LOG.warn(
|
||||
"Could not derive factory from connection: using CVS (valid factories are: "
|
||||
+ FACTORIES.keySet() + ")" );
|
||||
clFactoryClass = "org.apache.maven.cvslib.CvsChangeLogFactory";
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Class clazz = Class.forName(clFactoryClass);
|
||||
Class clazz = Class.forName( clFactoryClass );
|
||||
|
||||
return (ChangeLogFactory) clazz.newInstance();
|
||||
}
|
||||
catch (ClassNotFoundException cnfe)
|
||||
catch ( ClassNotFoundException cnfe )
|
||||
{
|
||||
throw new IOException("Cannot find class " + clFactoryClass
|
||||
+ " " + cnfe.toString());
|
||||
throw new IOException( "Cannot find class " + clFactoryClass + " "
|
||||
+ cnfe.toString() );
|
||||
}
|
||||
catch (IllegalAccessException iae)
|
||||
catch ( IllegalAccessException iae )
|
||||
{
|
||||
throw new IOException("Cannot access class " + clFactoryClass
|
||||
+ " " + iae.toString());
|
||||
throw new IOException( "Cannot access class " + clFactoryClass
|
||||
+ " " + iae.toString() );
|
||||
}
|
||||
catch (InstantiationException ie)
|
||||
catch ( InstantiationException ie )
|
||||
{
|
||||
throw new IOException("Cannot instantiate class " + clFactoryClass
|
||||
+ " " + ie.toString());
|
||||
throw new IOException( "Cannot instantiate class " + clFactoryClass
|
||||
+ " " + ie.toString() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set up list of developers mapping id to name.
|
||||
* @task This should be a facility on the maven project itself
|
||||
@@ -532,14 +553,15 @@ public class ChangeLog
|
||||
private Properties getUserList()
|
||||
{
|
||||
Properties userList = new Properties();
|
||||
|
||||
|
||||
Developer developer = null;
|
||||
for (Iterator i = getDevelopers().iterator(); i.hasNext();)
|
||||
|
||||
for ( Iterator i = getDevelopers().iterator(); i.hasNext(); )
|
||||
{
|
||||
developer = (Developer) i.next();
|
||||
userList.put(developer.getId(), developer.getName());
|
||||
userList.put( developer.getId(), developer.getName() );
|
||||
}
|
||||
|
||||
|
||||
return userList;
|
||||
}
|
||||
|
||||
@@ -550,21 +572,25 @@ public class ChangeLog
|
||||
{
|
||||
Properties userList = getUserList();
|
||||
ChangeLogEntry entry = null;
|
||||
|
||||
for (final Iterator iSets = getChangeSets().iterator() ; iSets.hasNext() ;)
|
||||
|
||||
for ( Iterator iSets = getChangeSets().iterator();
|
||||
iSets.hasNext(); )
|
||||
{
|
||||
final ChangeLogSet set = (ChangeLogSet)iSets.next();
|
||||
for (Iterator iEntries = set.getEntries().iterator(); iEntries.hasNext();)
|
||||
final ChangeLogSet set = (ChangeLogSet) iSets.next();
|
||||
|
||||
for ( Iterator iEntries = set.getEntries().iterator();
|
||||
iEntries.hasNext(); )
|
||||
{
|
||||
entry = (ChangeLogEntry) iEntries.next();
|
||||
if (userList.containsKey(entry.getAuthor()))
|
||||
|
||||
if ( userList.containsKey( entry.getAuthor() ) )
|
||||
{
|
||||
entry.setAuthor(userList.getProperty(entry.getAuthor()));
|
||||
entry.setAuthor( userList.getProperty( entry.getAuthor() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the XML document from the currently available details
|
||||
* @throws FileNotFoundException when the output file previously provided
|
||||
@@ -572,64 +598,69 @@ public class ChangeLog
|
||||
* @throws UnsupportedEncodingException when the platform doesn't support
|
||||
* ISO-8859-1 encoding
|
||||
*/
|
||||
private void createDocument() throws FileNotFoundException,
|
||||
UnsupportedEncodingException
|
||||
private void createDocument()
|
||||
throws FileNotFoundException, UnsupportedEncodingException
|
||||
{
|
||||
File dir = output.getParentFile();
|
||||
if (dir != null) {
|
||||
|
||||
if ( dir != null )
|
||||
{
|
||||
dir.mkdirs();
|
||||
}
|
||||
PrintWriter out = new PrintWriter(new OutputStreamWriter(
|
||||
new FileOutputStream(output), getOutputEncoding()));
|
||||
out.println(toXML());
|
||||
|
||||
PrintWriter out =
|
||||
new PrintWriter( new OutputStreamWriter(
|
||||
new FileOutputStream( output ), getOutputEncoding() ) );
|
||||
|
||||
out.println( toXML() );
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return an XML document representing this change log and it's entries
|
||||
* @return an XML document representing this change log and it's entries
|
||||
*/
|
||||
private String toXML()
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("<?xml version=\"1.0\" encoding=\"")
|
||||
.append(getOutputEncoding())
|
||||
.append("\" ?>\n")
|
||||
.append("<changelog>\n");
|
||||
|
||||
for (Iterator i = getChangeSets().iterator(); i.hasNext();)
|
||||
|
||||
buffer.append( "<?xml version=\"1.0\" encoding=\"" )
|
||||
.append( getOutputEncoding() ).append( "\" ?>\n" ).append( "<changelog>\n" );
|
||||
|
||||
for ( Iterator i = getChangeSets().iterator(); i.hasNext(); )
|
||||
{
|
||||
buffer.append(((ChangeLogSet) i.next()).toXML());
|
||||
buffer.append( ( (ChangeLogSet) i.next() ).toXML() );
|
||||
}
|
||||
|
||||
buffer.append("</changelog>\n");
|
||||
|
||||
buffer.append( "</changelog>\n" );
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the collection of change sets.
|
||||
*
|
||||
*
|
||||
* @return collection of {@link ChangeLogSet} objects.
|
||||
*/
|
||||
public Collection getChangeSets()
|
||||
{
|
||||
if (sets == null)
|
||||
if ( sets == null )
|
||||
{
|
||||
sets = Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
return sets;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Sets the collection of change sets.
|
||||
* @param sets New value of property sets.
|
||||
*/
|
||||
public void setChangeSets(Collection sets)
|
||||
public void setChangeSets( Collection sets )
|
||||
{
|
||||
this.sets = sets;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the developers.
|
||||
* @return List
|
||||
@@ -643,7 +674,7 @@ public class ChangeLog
|
||||
* Sets the developers.
|
||||
* @param developers The developers to set
|
||||
*/
|
||||
public void setDevelopers(List developers)
|
||||
public void setDevelopers( List developers )
|
||||
{
|
||||
this.developers = developers;
|
||||
}
|
||||
@@ -661,7 +692,7 @@ public class ChangeLog
|
||||
* Sets the outputEncoding.
|
||||
* @param outputEncoding The outputEncoding to set
|
||||
*/
|
||||
public void setOutputEncoding(String outputEncoding)
|
||||
public void setOutputEncoding( String outputEncoding )
|
||||
{
|
||||
this.outputEncoding = outputEncoding;
|
||||
}
|
||||
@@ -679,9 +710,9 @@ public class ChangeLog
|
||||
* Sets the commentFormat.
|
||||
* @param commentFormat The commentFormat to set
|
||||
*/
|
||||
public void setCommentFormat(String commentFormat)
|
||||
public void setCommentFormat( String commentFormat )
|
||||
{
|
||||
this.commentFormat = commentFormat;
|
||||
}
|
||||
|
||||
} // end of ChangeLog
|
||||
}
|
||||
// end of ChangeLog
|
||||
@@ -18,6 +18,7 @@ package org.apache.maven.changelog;
|
||||
*/
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
@@ -36,76 +37,75 @@ public class ChangeLogEntry
|
||||
* Escaped <code><</code> entity
|
||||
*/
|
||||
public static final String LESS_THAN_ENTITY = "<";
|
||||
|
||||
|
||||
/**
|
||||
* Escaped <code>></code> entity
|
||||
*/
|
||||
public static final String GREATER_THAN_ENTITY = ">";
|
||||
|
||||
|
||||
/**
|
||||
* Escaped <code>&</code> entity
|
||||
*/
|
||||
public static final String AMPERSAND_ENTITY = "&";
|
||||
|
||||
|
||||
/**
|
||||
* Escaped <code>'</code> entity
|
||||
*/
|
||||
public static final String APOSTROPHE_ENTITY = "'";
|
||||
|
||||
|
||||
/**
|
||||
* Escaped <code>"</code> entity
|
||||
*/
|
||||
public static final String QUOTE_ENTITY = """;
|
||||
|
||||
|
||||
/**
|
||||
* Formatter used by the getDateFormatted method.
|
||||
*/
|
||||
private static final SimpleDateFormat DATE_FORMAT =
|
||||
new SimpleDateFormat("yyyy-MM-dd");
|
||||
private static final SimpleDateFormat DATE_FORMAT =
|
||||
new SimpleDateFormat( "yyyy-MM-dd" );
|
||||
|
||||
/**
|
||||
* Formatter used by the getTimeFormatted method.
|
||||
*/
|
||||
private static final SimpleDateFormat TIME_FORMAT =
|
||||
new SimpleDateFormat("HH:mm:ss");
|
||||
private static final SimpleDateFormat TIME_FORMAT =
|
||||
new SimpleDateFormat( "HH:mm:ss" );
|
||||
|
||||
|
||||
/** Date the changes were committed */
|
||||
private Date date;
|
||||
|
||||
|
||||
/** User who made changes */
|
||||
private String author;
|
||||
|
||||
|
||||
/** comment provided at commit time */
|
||||
private String comment = "";
|
||||
|
||||
|
||||
/** ChangeLogFiles committed on the date, by the author, with comment*/
|
||||
private Vector files = new Vector();
|
||||
|
||||
|
||||
/**
|
||||
* Constructor used when attributes aren't available until later
|
||||
*/
|
||||
public ChangeLogEntry()
|
||||
public ChangeLogEntry()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a file to the list for this entry
|
||||
* @param file a {@link ChangeLogFile}
|
||||
*/
|
||||
public void addFile(ChangeLogFile file)
|
||||
public void addFile( ChangeLogFile file )
|
||||
{
|
||||
files.addElement(file);
|
||||
files.addElement( file );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Adds a feature to the File attribute of the Entry object.
|
||||
* @param file the file name committed
|
||||
* @param revision the revision of the latest change
|
||||
*/
|
||||
public void addFile(String file, String revision)
|
||||
public void addFile( String file, String revision )
|
||||
{
|
||||
files.addElement(new ChangeLogFile(file, revision));
|
||||
files.addElement( new ChangeLogFile( file, revision ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,7 +118,7 @@ public class ChangeLogEntry
|
||||
|
||||
/**
|
||||
* Provide the changelog entry as an XML snippet.
|
||||
*
|
||||
*
|
||||
* @task make sure comment doesn't contain CDATA tags - MAVEN114
|
||||
* @return a changelog-entry in xml format
|
||||
*/
|
||||
@@ -126,37 +126,30 @@ public class ChangeLogEntry
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
buffer.append("\t<changelog-entry>\n")
|
||||
.append("\t\t<date>")
|
||||
.append(getDateFormatted())
|
||||
.append("</date>\n")
|
||||
.append("\t\t<time>")
|
||||
.append(getTimeFormatted())
|
||||
.append("</time>\n")
|
||||
.append("\t\t<author><![CDATA[")
|
||||
.append(author)
|
||||
.append("]]></author>\n");
|
||||
|
||||
for (Enumeration e = files.elements(); e.hasMoreElements();)
|
||||
buffer.append( "\t<changelog-entry>\n" ).append( "\t\t<date>" )
|
||||
.append( getDateFormatted() ).append( "</date>\n" )
|
||||
.append( "\t\t<time>" ).append( getTimeFormatted() )
|
||||
.append( "</time>\n" ).append( "\t\t<author><![CDATA[" )
|
||||
.append( author ).append( "]]></author>\n" );
|
||||
|
||||
for ( Enumeration e = files.elements(); e.hasMoreElements(); )
|
||||
{
|
||||
ChangeLogFile file = (ChangeLogFile) e.nextElement();
|
||||
buffer.append("\t\t<file>\n")
|
||||
.append("\t\t\t<name>")
|
||||
.append(escapeValue(file.getName()))
|
||||
.append("</name>\n")
|
||||
.append("\t\t\t<revision>")
|
||||
.append(file.getRevision())
|
||||
.append("</revision>\n");
|
||||
buffer.append("\t\t</file>\n");
|
||||
|
||||
buffer.append( "\t\t<file>\n" ).append( "\t\t\t<name>" )
|
||||
.append( escapeValue( file.getName() ) ).append( "</name>\n" )
|
||||
.append( "\t\t\t<revision>" ).append( file.getRevision() )
|
||||
.append( "</revision>\n" );
|
||||
buffer.append( "\t\t</file>\n" );
|
||||
}
|
||||
buffer.append("\t\t<msg><![CDATA[")
|
||||
.append(removeCDataEnd(comment))
|
||||
.append("]]></msg>\n");
|
||||
buffer.append("\t</changelog-entry>\n");
|
||||
|
||||
|
||||
buffer.append( "\t\t<msg><![CDATA[" ).append( removeCDataEnd( comment ) )
|
||||
.append( "]]></msg>\n" );
|
||||
buffer.append( "\t</changelog-entry>\n" );
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for property author.
|
||||
* @return Value of property author.
|
||||
@@ -165,16 +158,16 @@ public class ChangeLogEntry
|
||||
{
|
||||
return author;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for property author.
|
||||
* @param author New value of property author.
|
||||
*/
|
||||
public void setAuthor(String author)
|
||||
public void setAuthor( String author )
|
||||
{
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for property comment.
|
||||
* @return Value of property comment.
|
||||
@@ -183,16 +176,16 @@ public class ChangeLogEntry
|
||||
{
|
||||
return comment;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for property comment.
|
||||
* @param comment New value of property comment.
|
||||
*/
|
||||
public void setComment(String comment)
|
||||
public void setComment( String comment )
|
||||
{
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for property date.
|
||||
* @return Value of property date.
|
||||
@@ -201,14 +194,14 @@ public class ChangeLogEntry
|
||||
{
|
||||
return (Date) date.clone();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for property date.
|
||||
* @param date New value of property date.
|
||||
*/
|
||||
public void setDate(Date date)
|
||||
public void setDate( Date date )
|
||||
{
|
||||
this.date = new Date(date.getTime());
|
||||
this.date = new Date( date.getTime() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,73 +209,92 @@ public class ChangeLogEntry
|
||||
*/
|
||||
public String getDateFormatted()
|
||||
{
|
||||
return DATE_FORMAT.format(getDate());
|
||||
return DATE_FORMAT.format( getDate() );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return time in HH:mm:ss format
|
||||
*/
|
||||
public String getTimeFormatted()
|
||||
{
|
||||
return TIME_FORMAT.format(getDate());
|
||||
return TIME_FORMAT.format( getDate() );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* remove a <code>]]></code> from comments (replace it with <code>] ] ></code>).
|
||||
* @param message
|
||||
* @return
|
||||
*/
|
||||
private String removeCDataEnd(String message)
|
||||
private String removeCDataEnd( String message )
|
||||
{
|
||||
// check for invalid sequence ]]>
|
||||
int endCdata;
|
||||
while (message != null && (endCdata = message.indexOf("]]>")) > -1)
|
||||
|
||||
while ( ( message != null )
|
||||
&& ( ( endCdata = message.indexOf( "]]>" ) ) > -1 ) )
|
||||
{
|
||||
message = message.substring(0, endCdata) + "] ] >" + message.substring(endCdata + 3, message.length());
|
||||
message =
|
||||
message.substring( 0, endCdata ) + "] ] >"
|
||||
+ message.substring( endCdata + 3, message.length() );
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Escape the <code>toString</code> of the given object.
|
||||
* For use in an attribute value.</p>
|
||||
*
|
||||
* swiped from jakarta-commons/betwixt -- XMLUtils.java
|
||||
*
|
||||
* @param value escape <code>value.toString()</code>
|
||||
* @return text with characters restricted (for use in attributes) escaped
|
||||
*/
|
||||
public static final String escapeValue(Object value) {
|
||||
StringBuffer buffer = new StringBuffer(value.toString());
|
||||
for (int i=0, size = buffer.length(); i <size; i++) {
|
||||
switch (buffer.charAt(i)) {
|
||||
case '<':
|
||||
buffer.replace(i, i+1, LESS_THAN_ENTITY);
|
||||
size += 3;
|
||||
i+=3;
|
||||
break;
|
||||
case '>':
|
||||
buffer.replace(i, i+1, GREATER_THAN_ENTITY);
|
||||
size += 3;
|
||||
i += 3;
|
||||
break;
|
||||
case '&':
|
||||
buffer.replace(i, i+1, AMPERSAND_ENTITY);
|
||||
size += 4;
|
||||
i += 4;
|
||||
break;
|
||||
case '\'':
|
||||
buffer.replace(i, i+1, APOSTROPHE_ENTITY);
|
||||
size += 4;
|
||||
i += 4;
|
||||
break;
|
||||
case '\"':
|
||||
buffer.replace(i, i+1, QUOTE_ENTITY);
|
||||
size += 5;
|
||||
i += 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
|
||||
/**
|
||||
* <p>Escape the <code>toString</code> of the given object.
|
||||
* For use in an attribute value.</p>
|
||||
*
|
||||
* swiped from jakarta-commons/betwixt -- XMLUtils.java
|
||||
*
|
||||
* @param value escape <code>value.toString()</code>
|
||||
* @return text with characters restricted (for use in attributes) escaped
|
||||
*/
|
||||
public static final String escapeValue( Object value )
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer( value.toString() );
|
||||
|
||||
for ( int i = 0, size = buffer.length(); i < size; i++ )
|
||||
{
|
||||
switch ( buffer.charAt( i ) )
|
||||
{
|
||||
case '<' :
|
||||
buffer.replace( i, i + 1, LESS_THAN_ENTITY );
|
||||
size += 3;
|
||||
i += 3;
|
||||
|
||||
break;
|
||||
|
||||
case '>' :
|
||||
buffer.replace( i, i + 1, GREATER_THAN_ENTITY );
|
||||
size += 3;
|
||||
i += 3;
|
||||
|
||||
break;
|
||||
|
||||
case '&' :
|
||||
buffer.replace( i, i + 1, AMPERSAND_ENTITY );
|
||||
size += 4;
|
||||
i += 4;
|
||||
|
||||
break;
|
||||
|
||||
case '\'' :
|
||||
buffer.replace( i, i + 1, APOSTROPHE_ENTITY );
|
||||
size += 4;
|
||||
i += 4;
|
||||
|
||||
break;
|
||||
|
||||
case '\"' :
|
||||
buffer.replace( i, i + 1, QUOTE_ENTITY );
|
||||
size += 5;
|
||||
i += 5;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ public class ChangeLogFile
|
||||
{
|
||||
/** the name of the file relative to the project directory. */
|
||||
private String name;
|
||||
|
||||
/** the latest revision of the file. */
|
||||
private String revision;
|
||||
|
||||
@@ -35,21 +36,21 @@ public class ChangeLogFile
|
||||
* Constructor for the ChangeLogFile object without all details available
|
||||
* @param name file name
|
||||
*/
|
||||
public ChangeLogFile(String name)
|
||||
public ChangeLogFile( String name )
|
||||
{
|
||||
setName(name);
|
||||
setName( name );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for the ChangeLogFile object
|
||||
*
|
||||
* @param name file name
|
||||
* @param rev latest revision of the file
|
||||
*/
|
||||
public ChangeLogFile(String name, String rev)
|
||||
public ChangeLogFile( String name, String rev )
|
||||
{
|
||||
setName(name);
|
||||
setRevision(rev);
|
||||
setName( name );
|
||||
setRevision( rev );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,16 +75,16 @@ public class ChangeLogFile
|
||||
* Setter for property name.
|
||||
* @param name New value of property name.
|
||||
*/
|
||||
public void setName(String name)
|
||||
public void setName( String name )
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for property revision.
|
||||
* @param revision New value of property revision.
|
||||
*/
|
||||
public void setRevision(String revision)
|
||||
public void setRevision( String revision )
|
||||
{
|
||||
this.revision = revision;
|
||||
}
|
||||
@@ -92,15 +93,16 @@ public class ChangeLogFile
|
||||
* Provide a version of the object as a string for debugging purposes
|
||||
* @return a {@link String} made up of the properties of the object
|
||||
*/
|
||||
public String toString()
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer(getName());
|
||||
if (getRevision() != null)
|
||||
StringBuffer buffer = new StringBuffer( getName() );
|
||||
|
||||
if ( getRevision() != null )
|
||||
{
|
||||
buffer.append(", ").append(getRevision());
|
||||
buffer.append( ", " ).append( getRevision() );
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
} // end of ChangeLogFile
|
||||
|
||||
}
|
||||
// end of ChangeLogFile
|
||||
@@ -18,13 +18,14 @@ package org.apache.maven.changelog;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Instances of <code>ChangeLogGenerator</code> are intended to provide an
|
||||
* {@link java.io.InputStream} for a {@link ChangeLogParser} to parse into
|
||||
* {@link java.io.InputStream} for a {@link ChangeLogParser} to parse into
|
||||
* individual {@link ChangeLogEntry} objects.
|
||||
*
|
||||
*
|
||||
* @author Glenn McAllister
|
||||
* @author dion
|
||||
* @version $Id$
|
||||
@@ -34,12 +35,12 @@ public interface ChangeLogGenerator
|
||||
/**
|
||||
* Initialize the ChangeLogGenerator instance with in the controlling
|
||||
* {@link ChangeLog} instance. Any configuration required for the generator
|
||||
* should be obtained from the <code>changeLog</code>. This method is
|
||||
* should be obtained from the <code>changeLog</code>. This method is
|
||||
* guaranteed to be called before {@link #getEntries}.
|
||||
*
|
||||
* @param changeLog the controlling ChangeLog instance
|
||||
*/
|
||||
void init(ChangeLog changeLog);
|
||||
void init( ChangeLog changeLog );
|
||||
|
||||
/**
|
||||
* Return a Collection of ChangeLogEntry objects. This method should
|
||||
@@ -57,24 +58,25 @@ public interface ChangeLogGenerator
|
||||
* @throws IOException if there is an error while creating the
|
||||
* ChangeLogEntry objects
|
||||
*/
|
||||
Collection getEntries(ChangeLogParser parser) throws IOException;
|
||||
Collection getEntries( ChangeLogParser parser )
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Return a string indicating the start of the entries.
|
||||
* This will usually be a date or a tag.
|
||||
*
|
||||
*
|
||||
* @return a string indicating the start of the entries.
|
||||
*/
|
||||
String getLogStart();
|
||||
|
||||
|
||||
/**
|
||||
* Return a string indicating the end of the entries.
|
||||
* This will usually be a date or a tag.
|
||||
*
|
||||
*
|
||||
* @return a string indicating the end of the entries.
|
||||
*/
|
||||
String getLogEnd();
|
||||
|
||||
|
||||
/**
|
||||
* Provides the opportunity for the generator to do any required cleanup.
|
||||
* This method is guaranteed to be called after the getEntries method even
|
||||
|
||||
@@ -17,8 +17,9 @@ package org.apache.maven.changelog;
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
@@ -39,7 +40,7 @@ public interface ChangeLogParser
|
||||
*
|
||||
* @param changeLog the controlling ChangeLog instance
|
||||
*/
|
||||
void init(ChangeLog changeLog);
|
||||
void init( ChangeLog changeLog );
|
||||
|
||||
/**
|
||||
* Returns a {@link java.util.Collection} of ChangeLogEntry objects, parsed
|
||||
@@ -52,7 +53,8 @@ public interface ChangeLogParser
|
||||
* @return a Collection of ChangeLogEntry objects
|
||||
* @throws IOException if there is an error while parsing the input stream
|
||||
*/
|
||||
Collection parse(InputStream in) throws IOException;
|
||||
Collection parse( InputStream in )
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Provides the opportunity for the parser to do any required cleanup.
|
||||
|
||||
@@ -17,11 +17,9 @@ package org.apache.maven.changelog;
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
import java.io.Writer;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
/**
|
||||
* Change Log Set - holds details about a set of change log entries.
|
||||
*
|
||||
@@ -33,76 +31,68 @@ public class ChangeLogSet
|
||||
private final Collection entries;
|
||||
private final String start;
|
||||
private final String end;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initializes a new instance of this class.
|
||||
*
|
||||
*
|
||||
* @param entries collection of {@link ChangeLogEntry} objects for this set.
|
||||
* @param start the start date/tag for this set.
|
||||
* @param end the end date/tag for this set, or <code>null</code> if this set goes to the present time.
|
||||
*/
|
||||
public ChangeLogSet(Collection entries, String start, String end)
|
||||
public ChangeLogSet( Collection entries, String start, String end )
|
||||
{
|
||||
this.entries = entries;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the collection of entries for this set.
|
||||
*
|
||||
*
|
||||
* @return the collection of {@link ChangeLogEntry} objects for this set.
|
||||
*/
|
||||
public Collection getEntries()
|
||||
{
|
||||
return entries;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the start date/tag for this set.
|
||||
*
|
||||
*
|
||||
* @return the start date/tag for this set.
|
||||
*/
|
||||
public String getStart()
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the end date/tag for this set.
|
||||
*
|
||||
*
|
||||
* @return the end date/tag for this set, or <code>null</code> if this set goes to the present time.
|
||||
*/
|
||||
public String getEnd()
|
||||
{
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates an XML representation of this change log set.
|
||||
*/
|
||||
public String toXML()
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
buffer.append("<changeset start=\"")
|
||||
.append(start)
|
||||
.append("\" end=\"")
|
||||
.append(end)
|
||||
.append("\">\n");
|
||||
|
||||
|
||||
buffer.append( "<changeset start=\"" ).append( start )
|
||||
.append( "\" end=\"" ).append( end ).append( "\">\n" );
|
||||
|
||||
// Write out the entries
|
||||
for (Iterator i = getEntries().iterator(); i.hasNext();)
|
||||
for ( Iterator i = getEntries().iterator(); i.hasNext(); )
|
||||
{
|
||||
buffer.append(((ChangeLogEntry) i.next()).toXML());
|
||||
buffer.append( ( (ChangeLogEntry) i.next() ).toXML() );
|
||||
}
|
||||
|
||||
buffer.append("</changeset>\n");
|
||||
|
||||
buffer.append( "</changeset>\n" );
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@@ -21,14 +21,15 @@ import org.apache.maven.changelog.ChangeLogFactory;
|
||||
import org.apache.maven.changelog.ChangeLogGenerator;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
|
||||
|
||||
/**
|
||||
* Provides Clearcase specific instances of the ChangeLogGenerator and
|
||||
* ChangeLogParser interfaces.
|
||||
*
|
||||
* @author <a href="mailto:aldarion@virgilio.it">Simone Zorzetti</a>
|
||||
*/
|
||||
public class ClearcaseChangeLogFactory implements ChangeLogFactory {
|
||||
|
||||
public class ClearcaseChangeLogFactory implements ChangeLogFactory
|
||||
{
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.maven.changelog.ChangeLogFactory#createGenerator()
|
||||
*/
|
||||
@@ -42,7 +43,6 @@ public class ClearcaseChangeLogFactory implements ChangeLogFactory {
|
||||
*/
|
||||
public ChangeLogParser createParser()
|
||||
{
|
||||
return new ClearcaseChangeLogParser();
|
||||
return new ClearcaseChangeLogParser();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,103 +18,108 @@ package org.apache.maven.clearcaselib;
|
||||
*/
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
// commons imports
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.maven.changelog.AbstractChangeLogGenerator;
|
||||
|
||||
// ant imports
|
||||
import org.apache.tools.ant.types.Commandline;
|
||||
|
||||
import org.apache.maven.changelog.AbstractChangeLogGenerator;
|
||||
|
||||
|
||||
/**
|
||||
* A Clearcase implementation of the {@link org.apache.maven.changelog.ChangeLogGenerator}
|
||||
* interface realized extending the {@link org.apache.maven.changelog.AbstractChangeLogGenerator}.
|
||||
*
|
||||
*
|
||||
* The command line build by this class uses the <code>lshistory</code> clearcase command
|
||||
* and formats the output in a way the ClearcaseChangeLogParser can understand. Due to this
|
||||
* fact this implementations works only if used within a clearcase view.
|
||||
*
|
||||
*
|
||||
* The command looks like this: <p>
|
||||
* cleartool lshistory -recurse -nco -since SAMEDATE
|
||||
* cleartool lshistory -recurse -nco -since SAMEDATE
|
||||
* -fmt "NAME:%En\\nDATE:%Nd\\nCOMM:%-12.12o - %o - %c - Activity: %[activity]p\\nUSER:%-8.8u\\n"
|
||||
*
|
||||
* @author <a href="mailto:aldarion@virgilio.it">Simone Zorzetti</a>
|
||||
*/
|
||||
public class ClearcaseChangeLogGenerator extends AbstractChangeLogGenerator {
|
||||
|
||||
public class ClearcaseChangeLogGenerator extends AbstractChangeLogGenerator
|
||||
{
|
||||
/** Log */
|
||||
private static final Log LOG = LogFactory.getLog(
|
||||
ClearcaseChangeLogGenerator.class);
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog( ClearcaseChangeLogGenerator.class );
|
||||
|
||||
/**
|
||||
* Constructs the appropriate command line to execute the scm's
|
||||
* log command. For Clearcase it's lshistory.
|
||||
*
|
||||
*
|
||||
* @see org.apache.maven.changelog.AbstractChangeLogGenerator#getScmLogCommand()
|
||||
* @return The command line to be executed.
|
||||
*/
|
||||
protected Commandline getScmLogCommand()
|
||||
{
|
||||
Commandline command = new Commandline();
|
||||
command.setExecutable("cleartool");
|
||||
command.createArgument().setValue("lshistory");
|
||||
|
||||
command.setExecutable( "cleartool" );
|
||||
command.createArgument().setValue( "lshistory" );
|
||||
|
||||
StringBuffer format = new StringBuffer();
|
||||
format.append("NAME:%En\\n");
|
||||
format.append("DATE:%Nd\\n");
|
||||
format.append("COMM:%-12.12o - ");
|
||||
|
||||
format.append( "NAME:%En\\n" );
|
||||
format.append( "DATE:%Nd\\n" );
|
||||
format.append( "COMM:%-12.12o - " );
|
||||
|
||||
String commentFormat = getCommentFormat();
|
||||
if (commentFormat == null)
|
||||
|
||||
if ( commentFormat == null )
|
||||
{
|
||||
format.append("%Sn - %c - Activity: %[activity]p\\n");
|
||||
format.append( "%Sn - %c - Activity: %[activity]p\\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
format.append(commentFormat);
|
||||
format.append( commentFormat );
|
||||
}
|
||||
|
||||
format.append("USER:%-8.8u\\n");
|
||||
|
||||
command.createArgument().setValue("-fmt");
|
||||
command.createArgument().setValue(format.toString());
|
||||
command.createArgument().setValue("-recurse");
|
||||
command.createArgument().setValue("-nco");
|
||||
command.createArgument().setValue("-since");
|
||||
command.createArgument().setValue(dateRange);
|
||||
format.append( "USER:%-8.8u\\n" );
|
||||
|
||||
return command;
|
||||
command.createArgument().setValue( "-fmt" );
|
||||
command.createArgument().setValue( format.toString() );
|
||||
command.createArgument().setValue( "-recurse" );
|
||||
command.createArgument().setValue( "-nco" );
|
||||
command.createArgument().setValue( "-since" );
|
||||
command.createArgument().setValue( dateRange );
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Construct the command-line argument that is passed to the scm
|
||||
* client to specify the appropriate date range.
|
||||
*
|
||||
*
|
||||
* @param before The starting point.
|
||||
* @param to The ending point.
|
||||
* @return A string that can be used to specify a date to a scm
|
||||
* system.
|
||||
*
|
||||
* @see org.apache.maven.changelog.AbstractChangeLogGenerator#getScmDateArgument(java.util.Date, java.util.Date)
|
||||
*
|
||||
* @see org.apache.maven.changelog.AbstractChangeLogGenerator#getScmDateArgument(java.util.Date, java.util.Date)
|
||||
*/
|
||||
protected String getScmDateArgument(Date before, Date to)
|
||||
protected String getScmDateArgument( Date before, Date to )
|
||||
{
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy", Locale.ENGLISH);
|
||||
String argument = sdf.format(before);
|
||||
|
||||
SimpleDateFormat sdf =
|
||||
new SimpleDateFormat( "dd-MMM-yyyy", Locale.ENGLISH );
|
||||
String argument = sdf.format( before );
|
||||
|
||||
return argument;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AbstractChangeLogGenerator#getScmTagArgument(String, String)
|
||||
*/
|
||||
protected String getScmTagArgument(String tagStart, String tagEnd)
|
||||
protected String getScmTagArgument( String tagStart, String tagEnd )
|
||||
{
|
||||
throw new UnsupportedOperationException("This plugin currently does not support generating logs from tags with Clearcase.");
|
||||
throw new UnsupportedOperationException(
|
||||
"This plugin currently does not support generating logs from tags with Clearcase." );
|
||||
}
|
||||
}
|
||||
@@ -18,80 +18,83 @@ package org.apache.maven.clearcaselib;
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
||||
// commons imports
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.apache.maven.changelog.ChangeLog;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
import org.apache.maven.changelog.ChangeLogEntry;
|
||||
import org.apache.maven.changelog.ChangeLogFile;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
|
||||
|
||||
/**
|
||||
* Clearcase specific implementation of ChangeLogParser interface.
|
||||
*
|
||||
* Clearcase specific implementation of ChangeLogParser interface.
|
||||
*
|
||||
* @author <a href="mailto:aldarion@virgilio.it">Simone Zorzetti</a>
|
||||
*/
|
||||
public class ClearcaseChangeLogParser implements ChangeLogParser {
|
||||
|
||||
public class ClearcaseChangeLogParser implements ChangeLogParser
|
||||
{
|
||||
/** Log */
|
||||
private static final Log LOG = LogFactory.getLog(
|
||||
ClearcaseChangeLogParser.class);
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog( ClearcaseChangeLogParser.class );
|
||||
|
||||
/**
|
||||
* Formatter used to parse Clearcase date/timestamp.
|
||||
*/
|
||||
private static final SimpleDateFormat CLEARCASE_TIMESTAMP_FORMAT =
|
||||
new SimpleDateFormat("yyyyMMdd.HHmmss");
|
||||
|
||||
new SimpleDateFormat( "yyyyMMdd.HHmmss" );
|
||||
private static final String NAME_TAG = "NAME:";
|
||||
private static final String USER_TAG = "USER:";
|
||||
private static final String DATE_TAG = "DATE:";
|
||||
private static final String COMMENT_TAG = "COMM:";
|
||||
|
||||
|
||||
/**
|
||||
* Custom date/time formatter. Rounds ChangeLogEntry times to the nearest
|
||||
* minute.
|
||||
*/
|
||||
private static final SimpleDateFormat ENTRY_KEY_TIMESTAMP_FORMAT =
|
||||
new SimpleDateFormat("yyyyMMddHHmm");
|
||||
private static final SimpleDateFormat ENTRY_KEY_TIMESTAMP_FORMAT =
|
||||
new SimpleDateFormat( "yyyyMMddHHmm" );
|
||||
|
||||
/**
|
||||
* Custom date/time formatter. Rounds ChangeLogEntry to date
|
||||
*/
|
||||
private static final SimpleDateFormat GROUPED_ENTRY_KEY_TIMESTAMP_FORMAT =
|
||||
new SimpleDateFormat("yyyyMMdd");
|
||||
|
||||
/**
|
||||
* rcs entries, in reverse (date, time, author, comment) order
|
||||
*/
|
||||
private Map entries = new TreeMap(Collections.reverseOrder());
|
||||
private static final SimpleDateFormat GROUPED_ENTRY_KEY_TIMESTAMP_FORMAT =
|
||||
new SimpleDateFormat( "yyyyMMdd" );
|
||||
|
||||
// state machine constants for reading clearcase lshistory command output
|
||||
|
||||
/** expecting file information */
|
||||
private static final int GET_FILE = 1;
|
||||
|
||||
/** expecting date */
|
||||
private static final int GET_DATE = 2;
|
||||
|
||||
/** expecting comments */
|
||||
private static final int GET_COMMENT = 3;
|
||||
|
||||
/**
|
||||
* rcs entries, in reverse (date, time, author, comment) order
|
||||
*/
|
||||
private Map entries = new TreeMap( Collections.reverseOrder() );
|
||||
|
||||
/** current status of the parser */
|
||||
private int status = GET_FILE;
|
||||
|
||||
|
||||
/** the current log entry being processed by the parser*/
|
||||
private ChangeLogEntry currentLogEntry = null;
|
||||
|
||||
|
||||
/** the current file being processed by the parser */
|
||||
private ChangeLogFile currentFile = null;
|
||||
|
||||
@@ -106,29 +109,30 @@ public class ClearcaseChangeLogParser implements ChangeLogParser {
|
||||
* initialize the parser from the change log
|
||||
* @param changeLog the controlling task
|
||||
* @see ChangeLogParser#init(ChangeLog)
|
||||
*/
|
||||
public void init(ChangeLog changeLog)
|
||||
*/
|
||||
public void init( ChangeLog changeLog )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up any parser resources
|
||||
* @see ChangeLogParser#cleanup()
|
||||
*/
|
||||
*/
|
||||
public void cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the input stream into a collection.
|
||||
* @param anInputStream an input stream containing clearcase log output
|
||||
* @return a collection of ChangeLogEntry's
|
||||
* @throws IOException when there are errors reading the provided stream
|
||||
*/
|
||||
public Collection parse(InputStream anInputStream) throws IOException
|
||||
public Collection parse( InputStream anInputStream )
|
||||
throws IOException
|
||||
{
|
||||
BufferedReader stream = new BufferedReader(
|
||||
new InputStreamReader(anInputStream));
|
||||
BufferedReader stream =
|
||||
new BufferedReader( new InputStreamReader( anInputStream ) );
|
||||
|
||||
// Read the tags in the order they are produced by the command setup
|
||||
// by ClearcaseChangeLogGenerator
|
||||
@@ -137,28 +141,34 @@ public class ClearcaseChangeLogParser implements ChangeLogParser {
|
||||
// Comment
|
||||
// User Name (author)
|
||||
String line = null;
|
||||
|
||||
while ((line = stream.readLine()) != null)
|
||||
|
||||
while ( ( line = stream.readLine() ) != null )
|
||||
{
|
||||
switch (getStatus())
|
||||
switch ( getStatus() )
|
||||
{
|
||||
case GET_FILE:
|
||||
processGetFile(line);
|
||||
break;
|
||||
case GET_DATE:
|
||||
processGetDate(line);
|
||||
break;
|
||||
case GET_COMMENT:
|
||||
processGetCommentAndUser(line);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown state: " + status);
|
||||
case GET_FILE :
|
||||
processGetFile( line );
|
||||
|
||||
break;
|
||||
|
||||
case GET_DATE :
|
||||
processGetDate( line );
|
||||
|
||||
break;
|
||||
|
||||
case GET_COMMENT :
|
||||
processGetCommentAndUser( line );
|
||||
|
||||
break;
|
||||
|
||||
default :
|
||||
throw new IllegalStateException( "Unknown state: " + status );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return entries.values();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a change log entry to the list (if it's not already there)
|
||||
* with the given file.
|
||||
@@ -167,101 +177,106 @@ public class ClearcaseChangeLogParser implements ChangeLogParser {
|
||||
* is null, the entry wont be added
|
||||
* @param file a {@link ChangeLogFile} to be added to the entry
|
||||
*/
|
||||
private void addEntry(ChangeLogEntry entry, ChangeLogFile file)
|
||||
private void addEntry( ChangeLogEntry entry, ChangeLogFile file )
|
||||
{
|
||||
|
||||
// do not add if entry is not populated
|
||||
if (entry.getAuthor() == null)
|
||||
if ( entry.getAuthor() == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
// do not add if the operation is not checkin
|
||||
if (entry.getComment().indexOf("checkin ") == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String key = ENTRY_KEY_TIMESTAMP_FORMAT.format(entry.getDate())
|
||||
+ entry.getAuthor() + entry.getComment();
|
||||
|
||||
|
||||
file.setRevision("");
|
||||
|
||||
if (!entries.containsKey(key))
|
||||
// do not add if the operation is not checkin
|
||||
if ( entry.getComment().indexOf( "checkin " ) == -1 )
|
||||
{
|
||||
entry.addFile(file);
|
||||
entries.put(key, entry);
|
||||
return;
|
||||
}
|
||||
|
||||
String key =
|
||||
ENTRY_KEY_TIMESTAMP_FORMAT.format( entry.getDate() )
|
||||
+ entry.getAuthor() + entry.getComment();
|
||||
|
||||
file.setRevision( "" );
|
||||
|
||||
if ( !entries.containsKey( key ) )
|
||||
{
|
||||
entry.addFile( file );
|
||||
entries.put( key, entry );
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeLogEntry existingEntry = (ChangeLogEntry) entries.get(key);
|
||||
existingEntry.addFile(file);
|
||||
ChangeLogEntry existingEntry = (ChangeLogEntry) entries.get( key );
|
||||
|
||||
existingEntry.addFile( file );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the current input line in the Get File state.
|
||||
* @param line a line of text from the clearcase log output
|
||||
*/
|
||||
private void processGetFile(String line)
|
||||
private void processGetFile( String line )
|
||||
{
|
||||
if (line.startsWith(NAME_TAG))
|
||||
if ( line.startsWith( NAME_TAG ) )
|
||||
{
|
||||
setCurrentLogEntry(new ChangeLogEntry());
|
||||
setCurrentFile(new ChangeLogFile(line.substring(NAME_TAG.length(),
|
||||
line.length())));
|
||||
setStatus(GET_DATE);
|
||||
setCurrentLogEntry( new ChangeLogEntry() );
|
||||
setCurrentFile( new ChangeLogFile( line.substring(
|
||||
NAME_TAG.length(), line.length() ) ) );
|
||||
setStatus( GET_DATE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the current input line in the Get Date state.
|
||||
* @param line a line of text from the clearcase log output
|
||||
*/
|
||||
private void processGetDate(String line)
|
||||
private void processGetDate( String line )
|
||||
{
|
||||
if (line.startsWith(DATE_TAG))
|
||||
if ( line.startsWith( DATE_TAG ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
getCurrentLogEntry().setDate(CLEARCASE_TIMESTAMP_FORMAT.parse(line.substring(DATE_TAG.length())));
|
||||
getCurrentLogEntry().setDate( CLEARCASE_TIMESTAMP_FORMAT
|
||||
.parse( line.substring( DATE_TAG.length() ) ) );
|
||||
}
|
||||
catch (ParseException e)
|
||||
catch ( ParseException e )
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
setStatus(GET_COMMENT);
|
||||
|
||||
setStatus( GET_COMMENT );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the current input line in the Get Comment state.
|
||||
* @param line a line of text from the clearcase log output
|
||||
*/
|
||||
private void processGetCommentAndUser(String line)
|
||||
private void processGetCommentAndUser( String line )
|
||||
{
|
||||
if (line.startsWith(COMMENT_TAG))
|
||||
if ( line.startsWith( COMMENT_TAG ) )
|
||||
{
|
||||
String comm = line.substring(COMMENT_TAG.length());
|
||||
getCurrentLogEntry().setComment(
|
||||
getCurrentLogEntry().getComment() + comm + "\n");
|
||||
|
||||
String comm = line.substring( COMMENT_TAG.length() );
|
||||
|
||||
getCurrentLogEntry().setComment( getCurrentLogEntry()
|
||||
.getComment() + comm
|
||||
+ "\n" );
|
||||
}
|
||||
else if (line.startsWith(USER_TAG))
|
||||
else if ( line.startsWith( USER_TAG ) )
|
||||
{
|
||||
getCurrentLogEntry().setAuthor(line.substring(USER_TAG.length()).trim());
|
||||
getCurrentLogEntry().setAuthor( line.substring(
|
||||
USER_TAG.length() ).trim() );
|
||||
|
||||
// add entry, and set state to get file
|
||||
addEntry(getCurrentLogEntry(), getCurrentFile());
|
||||
setStatus(GET_FILE);
|
||||
addEntry( getCurrentLogEntry(), getCurrentFile() );
|
||||
setStatus( GET_FILE );
|
||||
}
|
||||
else
|
||||
{
|
||||
// keep gathering comments
|
||||
getCurrentLogEntry().setComment(
|
||||
getCurrentLogEntry().getComment() + line + "\n");
|
||||
getCurrentLogEntry().setComment( getCurrentLogEntry()
|
||||
.getComment() + line
|
||||
+ "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,16 +288,16 @@ public class ClearcaseChangeLogParser implements ChangeLogParser {
|
||||
{
|
||||
return currentFile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for property currentFile.
|
||||
* @param currentFile New value of property currentFile.
|
||||
*/
|
||||
private void setCurrentFile(ChangeLogFile currentFile)
|
||||
private void setCurrentFile( ChangeLogFile currentFile )
|
||||
{
|
||||
this.currentFile = currentFile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for property currentLogEntry.
|
||||
* @return Value of property currentLogEntry.
|
||||
@@ -291,16 +306,16 @@ public class ClearcaseChangeLogParser implements ChangeLogParser {
|
||||
{
|
||||
return currentLogEntry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for property currentLogEntry.
|
||||
* @param currentLogEntry New value of property currentLogEntry.
|
||||
*/
|
||||
private void setCurrentLogEntry(ChangeLogEntry currentLogEntry)
|
||||
private void setCurrentLogEntry( ChangeLogEntry currentLogEntry )
|
||||
{
|
||||
this.currentLogEntry = currentLogEntry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for property status.
|
||||
* @return Value of property status.
|
||||
@@ -309,12 +324,12 @@ public class ClearcaseChangeLogParser implements ChangeLogParser {
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for property status.
|
||||
* @param status New value of property status.
|
||||
*/
|
||||
private void setStatus(int status)
|
||||
private void setStatus( int status )
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.apache.maven.changelog.ChangeLogFactory;
|
||||
import org.apache.maven.changelog.ChangeLogGenerator;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
|
||||
|
||||
/**
|
||||
* Provides CVS specific instances of the ChangeLogGenerator and
|
||||
* ChangeLogParser interfaces.
|
||||
@@ -36,7 +37,7 @@ public class CvsChangeLogFactory implements ChangeLogFactory
|
||||
public CvsChangeLogFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a CVS specific ChangeLogGenerator.
|
||||
*
|
||||
|
||||
@@ -16,12 +16,13 @@ package org.apache.maven.cvslib;
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
@@ -34,10 +35,11 @@ import org.apache.maven.util.AsyncStreamReader;
|
||||
import org.apache.maven.util.RepositoryUtils;
|
||||
import org.apache.tools.ant.types.Commandline;
|
||||
|
||||
|
||||
/**
|
||||
* A CVS implementation of the {@link org.apache.maven.changelog.ChangeLog}
|
||||
* interface.
|
||||
*
|
||||
*
|
||||
* @author Glenn McAllister
|
||||
* @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
|
||||
* @author <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a>
|
||||
@@ -53,23 +55,20 @@ class CvsChangeLogGenerator extends AbstractChangeLogGenerator
|
||||
{
|
||||
/** Log */
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog(CvsChangeLogGenerator.class);
|
||||
|
||||
private boolean quoteDate;
|
||||
|
||||
LogFactory.getLog( CvsChangeLogGenerator.class );
|
||||
public static final int POS_SCM = 0;
|
||||
public static final int POS_SCM_TYPE = 1;
|
||||
public static final int POS_SCM_SUBTYPE = 2;
|
||||
public static final int POS_SCM_USERHOST = 3;
|
||||
public static final int POS_SCM_PATH = 4;
|
||||
public static final int POS_SCM_MODULE = 5;
|
||||
|
||||
private boolean quoteDate;
|
||||
|
||||
/**
|
||||
* Set the quoteDate property.
|
||||
* @param newQuoteDate the quoteDate property to set.
|
||||
*/
|
||||
public void setQuoteDate(boolean newQuoteDate)
|
||||
public void setQuoteDate( boolean newQuoteDate )
|
||||
{
|
||||
this.quoteDate = newQuoteDate;
|
||||
}
|
||||
@@ -84,99 +83,98 @@ class CvsChangeLogGenerator extends AbstractChangeLogGenerator
|
||||
return quoteDate;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the generator from the changelog controller.
|
||||
*
|
||||
* @param changeLog The invoking controller (useful for logging)
|
||||
* @see ChangeLogGenerator#init(ChangeLog)
|
||||
*/
|
||||
public void init(ChangeLog changeLog)
|
||||
public void init( ChangeLog changeLog )
|
||||
{
|
||||
setQuoteDate(changeLog.getQuoteDate());
|
||||
super.init(changeLog);
|
||||
setQuoteDate( changeLog.getQuoteDate() );
|
||||
super.init( changeLog );
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute cvslib client driving the given parser. @todo Currently the
|
||||
* output from the logListener is a String, which is then converted to an
|
||||
* InputStream. The output of logListener really should be an input stream.
|
||||
*
|
||||
* @param parser A {@link ChangeLogParser parser}to process the scm
|
||||
* output.
|
||||
* @return A collection of {@link ChangeLogEntry entries}parsed from the
|
||||
* scm output.
|
||||
* @throws IOException When there are issues executing scm.
|
||||
* @see ChangeLogGenerator#getEntries(ChangeLogParser)
|
||||
*/
|
||||
public Collection getEntries(ChangeLogParser parser) throws IOException
|
||||
* Execute cvslib client driving the given parser. @todo Currently the
|
||||
* output from the logListener is a String, which is then converted to an
|
||||
* InputStream. The output of logListener really should be an input stream.
|
||||
*
|
||||
* @param parser A {@link ChangeLogParser parser}to process the scm
|
||||
* output.
|
||||
* @return A collection of {@link ChangeLogEntry entries}parsed from the
|
||||
* scm output.
|
||||
* @throws IOException When there are issues executing scm.
|
||||
* @see ChangeLogGenerator#getEntries(ChangeLogParser)
|
||||
*/
|
||||
public Collection getEntries( ChangeLogParser parser )
|
||||
throws IOException
|
||||
{
|
||||
if (parser == null)
|
||||
if ( parser == null )
|
||||
{
|
||||
throw new NullPointerException("parser cannot be null");
|
||||
throw new NullPointerException( "parser cannot be null" );
|
||||
}
|
||||
|
||||
if (base == null)
|
||||
if ( base == null )
|
||||
{
|
||||
throw new NullPointerException("basedir must be set");
|
||||
throw new NullPointerException( "basedir must be set" );
|
||||
}
|
||||
|
||||
if (!base.exists())
|
||||
if ( !base.exists() )
|
||||
{
|
||||
throw new FileNotFoundException(
|
||||
"Cannot find base dir " + base.getAbsolutePath());
|
||||
throw new FileNotFoundException( "Cannot find base dir "
|
||||
+ base.getAbsolutePath() );
|
||||
}
|
||||
|
||||
clParser = parser;
|
||||
|
||||
String[] args = getScmLogCommand().getArguments();
|
||||
CvsLogListener logListener = new CvsLogListener();
|
||||
|
||||
try
|
||||
{
|
||||
CvsConnection.processCommand(
|
||||
args,
|
||||
this.changeLogExecutor.getBasedir().toString(),
|
||||
logListener);
|
||||
CvsConnection.processCommand( args,
|
||||
this.changeLogExecutor.getBasedir().toString(), logListener );
|
||||
entries =
|
||||
clParser.parse(
|
||||
new ByteArrayInputStream(
|
||||
logListener.getStdout().toString().getBytes()));
|
||||
clParser.parse( new ByteArrayInputStream(
|
||||
logListener.getStdout().toString().getBytes() ) );
|
||||
}
|
||||
catch (IllegalArgumentException iae)
|
||||
catch ( IllegalArgumentException iae )
|
||||
{
|
||||
entries = super.getEntries(parser);
|
||||
entries = super.getEntries( parser );
|
||||
}
|
||||
catch (Exception e){
|
||||
LOG.error("Error processing command", e);
|
||||
catch ( Exception e )
|
||||
{
|
||||
LOG.error( "Error processing command", e );
|
||||
}
|
||||
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cvs command line to be executed.
|
||||
*/
|
||||
* @return the cvs command line to be executed.
|
||||
*/
|
||||
protected Commandline getScmLogCommand()
|
||||
{
|
||||
String tokens[] = RepositoryUtils.splitSCMConnection(getConnection());
|
||||
String[] tokens =
|
||||
RepositoryUtils.splitSCMConnection( getConnection() );
|
||||
|
||||
if (!tokens[POS_SCM_TYPE].equals("cvs"))
|
||||
if ( !tokens[POS_SCM_TYPE].equals( "cvs" ) )
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"repository connection string"
|
||||
+ " does not specify 'cvs' as the scm"
|
||||
+ System.getProperty("line.separator")
|
||||
+ "If using another scm, maven.changelog.factory"
|
||||
+ " must be set."
|
||||
+ System.getProperty("line.separator")
|
||||
+ "See the maven changelog plugin documentation"
|
||||
+ " for correct settings." );
|
||||
throw new IllegalArgumentException( "repository connection string"
|
||||
+ " does not specify 'cvs' as the scm"
|
||||
+ System.getProperty( "line.separator" )
|
||||
+ "If using another scm, maven.changelog.factory"
|
||||
+ " must be set." + System.getProperty( "line.separator" )
|
||||
+ "See the maven changelog plugin documentation"
|
||||
+ " for correct settings." );
|
||||
}
|
||||
|
||||
Commandline command = new Commandline();
|
||||
|
||||
command.setExecutable("cvs");
|
||||
command.createArgument().setValue("-d");
|
||||
command.setExecutable( "cvs" );
|
||||
command.createArgument().setValue( "-d" );
|
||||
|
||||
// from format:
|
||||
// scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:jakarta-turbine-maven/src/plugins-build/changelog/
|
||||
// to format:
|
||||
@@ -184,12 +182,12 @@ class CvsChangeLogGenerator extends AbstractChangeLogGenerator
|
||||
// use tokens 3+4+5
|
||||
String connectionBuffer = "";
|
||||
|
||||
if (tokens[POS_SCM_SUBTYPE].equalsIgnoreCase("local"))
|
||||
if ( tokens[POS_SCM_SUBTYPE].equalsIgnoreCase( "local" ) )
|
||||
{
|
||||
// use the local repository directory eg. '/home/cvspublic'
|
||||
connectionBuffer = tokens[POS_SCM_PATH];
|
||||
}
|
||||
else if (tokens[POS_SCM_SUBTYPE].equalsIgnoreCase("lserver"))
|
||||
else if ( tokens[POS_SCM_SUBTYPE].equalsIgnoreCase( "lserver" ) )
|
||||
{
|
||||
//create the cvsroot as the local socket cvsroot
|
||||
connectionBuffer =
|
||||
@@ -199,71 +197,71 @@ class CvsChangeLogGenerator extends AbstractChangeLogGenerator
|
||||
{
|
||||
//create the cvsroot as the remote cvsroot
|
||||
connectionBuffer =
|
||||
":"
|
||||
+ tokens[POS_SCM_SUBTYPE]
|
||||
+ ":"
|
||||
+ tokens[POS_SCM_USERHOST]
|
||||
+ ":"
|
||||
+ tokens[POS_SCM_PATH];
|
||||
":" + tokens[POS_SCM_SUBTYPE] + ":" + tokens[POS_SCM_USERHOST]
|
||||
+ ":" + tokens[POS_SCM_PATH];
|
||||
}
|
||||
|
||||
command.createArgument().setValue(connectionBuffer.toString());
|
||||
command.createArgument().setValue("log");
|
||||
command.createArgument().setValue( connectionBuffer.toString() );
|
||||
command.createArgument().setValue( "log" );
|
||||
|
||||
if (dateRange != null)
|
||||
if ( dateRange != null )
|
||||
{
|
||||
command.createArgument().setValue(dateRange);
|
||||
command.createArgument().setValue( dateRange );
|
||||
}
|
||||
else if (tag != null)
|
||||
else if ( tag != null )
|
||||
{
|
||||
command.createArgument().setValue(tag);
|
||||
command.createArgument().setValue( tag );
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the CVS command-line argument that is used to specify the
|
||||
* appropriate date range.
|
||||
*
|
||||
* @param before The starting point.
|
||||
* @param to The ending point.
|
||||
* @return A string that can be used to specify a date to a scm system.
|
||||
*/
|
||||
protected String getScmDateArgument(Date before, Date to)
|
||||
* Construct the CVS command-line argument that is used to specify the
|
||||
* appropriate date range.
|
||||
*
|
||||
* @param before The starting point.
|
||||
* @param to The ending point.
|
||||
* @return A string that can be used to specify a date to a scm system.
|
||||
*/
|
||||
protected String getScmDateArgument( Date before, Date to )
|
||||
{
|
||||
SimpleDateFormat outputDate = new SimpleDateFormat("yyyy-MM-dd");
|
||||
String cmd = outputDate.format(before) + "<" + outputDate.format(to);
|
||||
SimpleDateFormat outputDate = new SimpleDateFormat( "yyyy-MM-dd" );
|
||||
String cmd =
|
||||
outputDate.format( before ) + "<" + outputDate.format( to );
|
||||
|
||||
if ( getQuoteDate() )
|
||||
{
|
||||
cmd = "\"" + cmd + "\"";
|
||||
}
|
||||
|
||||
return "-d " + cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AbstractChangeLogGenerator#getScmTagArgument(String, String)
|
||||
*/
|
||||
protected String getScmTagArgument(String tagStart, String tagEnd)
|
||||
{
|
||||
return "-r" + tagStart + "::" + (tagEnd != null ? tagEnd : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle ChangeLogParser IOExceptions.
|
||||
*
|
||||
* @param ioe The IOException thrown.
|
||||
* @throws IOException If the handler doesn't wish to handle the exception.
|
||||
*/
|
||||
protected void handleParserException(IOException ioe) throws IOException
|
||||
* @see AbstractChangeLogGenerator#getScmTagArgument(String, String)
|
||||
*/
|
||||
protected String getScmTagArgument( String tagStart, String tagEnd )
|
||||
{
|
||||
if (ioe.getMessage().indexOf("CreateProcess") != -1
|
||||
|| ioe.getMessage().indexOf("cvs: not found") != -1)
|
||||
return "-r" + tagStart + "::" + ( ( tagEnd != null ) ? tagEnd : "" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle ChangeLogParser IOExceptions.
|
||||
*
|
||||
* @param ioe The IOException thrown.
|
||||
* @throws IOException If the handler doesn't wish to handle the exception.
|
||||
*/
|
||||
protected void handleParserException( IOException ioe )
|
||||
throws IOException
|
||||
{
|
||||
if ( ( ioe.getMessage().indexOf( "CreateProcess" ) != -1 )
|
||||
|| ( ioe.getMessage().indexOf( "cvs: not found" ) != -1 ) )
|
||||
{
|
||||
// can't find CVS on Win32 or Linux...
|
||||
if (LOG.isWarnEnabled())
|
||||
if ( LOG.isWarnEnabled() )
|
||||
{
|
||||
LOG.warn(
|
||||
LOG.warn(
|
||||
"Unable to find cvs executable. Please check that it is in your path, and avoid using spaces in the path name. Changelog will be empty" );
|
||||
}
|
||||
}
|
||||
@@ -274,43 +272,43 @@ class CvsChangeLogGenerator extends AbstractChangeLogGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the error stream for reading from cvs log. This stream will be read
|
||||
* on a separate thread.
|
||||
*
|
||||
* @param is - an {@link java.io.InputStream}
|
||||
*/
|
||||
public void setProcessErrorStream(InputStream is)
|
||||
* Set the error stream for reading from cvs log. This stream will be read
|
||||
* on a separate thread.
|
||||
*
|
||||
* @param is - an {@link java.io.InputStream}
|
||||
*/
|
||||
public void setProcessErrorStream( InputStream is )
|
||||
{
|
||||
errorReader = new CvsAsyncErrorReader(is);
|
||||
errorReader = new CvsAsyncErrorReader( is );
|
||||
}
|
||||
|
||||
/**
|
||||
* A private AsyncStreamReader class that "swallows" the "cvs server:
|
||||
* Logging" lines.
|
||||
*/
|
||||
* A private AsyncStreamReader class that "swallows" the "cvs server:
|
||||
* Logging" lines.
|
||||
*/
|
||||
private static class CvsAsyncErrorReader extends AsyncStreamReader
|
||||
{
|
||||
/**
|
||||
* The obvious constructor.
|
||||
*
|
||||
* @param anInputStream the input stream to consume
|
||||
*/
|
||||
public CvsAsyncErrorReader(InputStream anInputStream)
|
||||
* The obvious constructor.
|
||||
*
|
||||
* @param anInputStream the input stream to consume
|
||||
*/
|
||||
public CvsAsyncErrorReader( InputStream anInputStream )
|
||||
{
|
||||
super(anInputStream);
|
||||
super( anInputStream );
|
||||
}
|
||||
|
||||
/**
|
||||
* If the line does not start with "cvs server: Logging", it's ok to
|
||||
* consume it.
|
||||
*
|
||||
* @param line the line to check
|
||||
* @return <code>true</code> if the line does not start with "cvs
|
||||
* server: Logging"
|
||||
*/
|
||||
protected boolean okToConsume(String line)
|
||||
* If the line does not start with "cvs server: Logging", it's ok to
|
||||
* consume it.
|
||||
*
|
||||
* @param line the line to check
|
||||
* @return <code>true</code> if the line does not start with "cvs
|
||||
* server: Logging"
|
||||
*/
|
||||
protected boolean okToConsume( String line )
|
||||
{
|
||||
return !line.startsWith("cvs server: Logging");
|
||||
return !line.startsWith( "cvs server: Logging" );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,11 +18,13 @@ package org.apache.maven.cvslib;
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
@@ -31,9 +33,10 @@ import java.util.StringTokenizer;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.maven.changelog.ChangeLog;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
import org.apache.maven.changelog.ChangeLogEntry;
|
||||
import org.apache.maven.changelog.ChangeLogFile;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
|
||||
|
||||
/**
|
||||
* A class to parse cvs log output
|
||||
@@ -43,58 +46,67 @@ import org.apache.maven.changelog.ChangeLogFile;
|
||||
*/
|
||||
class CvsChangeLogParser implements ChangeLogParser
|
||||
{
|
||||
|
||||
/**
|
||||
* Old formatter used to parse CVS date/timestamp.
|
||||
*/
|
||||
private static final SimpleDateFormat OLD_CVS_TIMESTAMP_FORMAT =
|
||||
new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
||||
|
||||
new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" );
|
||||
|
||||
/**
|
||||
* New formatter used to parse CVS date/timestamp.
|
||||
*/
|
||||
private static final SimpleDateFormat NEW_CVS_TIMESTAMP_FORMAT =
|
||||
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
|
||||
|
||||
new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss Z" );
|
||||
|
||||
/**
|
||||
* Custom date/time formatter. Rounds ChangeLogEntry times to the nearest
|
||||
* minute.
|
||||
*/
|
||||
private static final SimpleDateFormat ENTRY_KEY_TIMESTAMP_FORMAT =
|
||||
new SimpleDateFormat("yyyyMMddHHmm");
|
||||
|
||||
/**
|
||||
* rcs entries, in reverse (date, time, author, comment) order
|
||||
*/
|
||||
private Map entries = new TreeMap(Collections.reverseOrder());
|
||||
private static final SimpleDateFormat ENTRY_KEY_TIMESTAMP_FORMAT =
|
||||
new SimpleDateFormat( "yyyyMMddHHmm" );
|
||||
|
||||
// state machine constants for reading cvs output
|
||||
|
||||
/** expecting file information */
|
||||
private static final int GET_FILE = 1;
|
||||
|
||||
/** expecting date */
|
||||
private static final int GET_DATE = 2;
|
||||
|
||||
/** expecting comments */
|
||||
private static final int GET_COMMENT = 3;
|
||||
|
||||
/** expecting revision */
|
||||
private static final int GET_REVISION = 4;
|
||||
|
||||
/** Marks start of file data*/
|
||||
private static final String START_FILE = "Working file: ";
|
||||
|
||||
/** Marks end of file */
|
||||
private static final String END_FILE = "==================================="
|
||||
private static final String END_FILE =
|
||||
"==================================="
|
||||
+ "==========================================";
|
||||
|
||||
/** Marks start of revision */
|
||||
private static final String START_REVISION = "----------------------------";
|
||||
|
||||
/** Marks revision data */
|
||||
private static final String REVISION_TAG = "revision ";
|
||||
|
||||
/** Marks date data */
|
||||
private static final String DATE_TAG = "date: ";
|
||||
|
||||
/**
|
||||
* rcs entries, in reverse (date, time, author, comment) order
|
||||
*/
|
||||
private Map entries = new TreeMap( Collections.reverseOrder() );
|
||||
|
||||
/** current status of the parser */
|
||||
private int status = GET_FILE;
|
||||
|
||||
|
||||
/** the current log entry being processed by the parser*/
|
||||
private ChangeLogEntry currentLogEntry = null;
|
||||
|
||||
|
||||
/** the current file being processed by the parser */
|
||||
private ChangeLogFile currentFile = null;
|
||||
|
||||
@@ -109,29 +121,30 @@ class CvsChangeLogParser implements ChangeLogParser
|
||||
* initialize the parser from the change log
|
||||
* @param changeLog the controlling task
|
||||
* @see ChangeLogParser#init(ChangeLog)
|
||||
*/
|
||||
public void init(ChangeLog changeLog)
|
||||
*/
|
||||
public void init( ChangeLog changeLog )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up any parser resources
|
||||
* @see ChangeLogParser#cleanup()
|
||||
*/
|
||||
*/
|
||||
public void cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the input stream into a collection.
|
||||
* @param anInputStream an input stream containing cvs log output
|
||||
* @return a collection of ChangeLogEntry's
|
||||
* @throws IOException when there are errors reading the provided stream
|
||||
*/
|
||||
public Collection parse(InputStream anInputStream) throws IOException
|
||||
public Collection parse( InputStream anInputStream )
|
||||
throws IOException
|
||||
{
|
||||
BufferedReader stream = new BufferedReader(
|
||||
new InputStreamReader(anInputStream));
|
||||
BufferedReader stream =
|
||||
new BufferedReader( new InputStreamReader( anInputStream ) );
|
||||
|
||||
// current state transitions in the state machine - starts with Get File
|
||||
// Get File -> Get Revision
|
||||
@@ -139,30 +152,39 @@ class CvsChangeLogParser implements ChangeLogParser
|
||||
// Get Date -> Get Comment
|
||||
// Get Comment -> Get Comment or Get Revision
|
||||
String line = null;
|
||||
while ((line = stream.readLine()) != null)
|
||||
|
||||
while ( ( line = stream.readLine() ) != null )
|
||||
{
|
||||
switch (getStatus())
|
||||
switch ( getStatus() )
|
||||
{
|
||||
case GET_FILE:
|
||||
processGetFile(line);
|
||||
break;
|
||||
case GET_REVISION:
|
||||
processGetRevision(line);
|
||||
break;
|
||||
case GET_DATE:
|
||||
processGetDate(line);
|
||||
break;
|
||||
case GET_COMMENT:
|
||||
processGetComment(line);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown state: " + status);
|
||||
case GET_FILE :
|
||||
processGetFile( line );
|
||||
|
||||
break;
|
||||
|
||||
case GET_REVISION :
|
||||
processGetRevision( line );
|
||||
|
||||
break;
|
||||
|
||||
case GET_DATE :
|
||||
processGetDate( line );
|
||||
|
||||
break;
|
||||
|
||||
case GET_COMMENT :
|
||||
processGetComment( line );
|
||||
|
||||
break;
|
||||
|
||||
default :
|
||||
throw new IllegalStateException( "Unknown state: " + status );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return entries.values();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a change log entry to the list (if it's not already there)
|
||||
* with the given file.
|
||||
@@ -171,41 +193,43 @@ class CvsChangeLogParser implements ChangeLogParser
|
||||
* is null, the entry wont be added
|
||||
* @param file a {@link ChangeLogFile} to be added to the entry
|
||||
*/
|
||||
private void addEntry(ChangeLogEntry entry, ChangeLogFile file)
|
||||
private void addEntry( ChangeLogEntry entry, ChangeLogFile file )
|
||||
{
|
||||
// do not add if entry is not populated
|
||||
if (entry.getAuthor() == null)
|
||||
if ( entry.getAuthor() == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String key = ENTRY_KEY_TIMESTAMP_FORMAT.format(entry.getDate())
|
||||
|
||||
String key =
|
||||
ENTRY_KEY_TIMESTAMP_FORMAT.format( entry.getDate() )
|
||||
+ entry.getAuthor() + entry.getComment();
|
||||
|
||||
if (!entries.containsKey(key))
|
||||
|
||||
if ( !entries.containsKey( key ) )
|
||||
{
|
||||
entry.addFile(file);
|
||||
entries.put(key, entry);
|
||||
entry.addFile( file );
|
||||
entries.put( key, entry );
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeLogEntry existingEntry = (ChangeLogEntry) entries.get(key);
|
||||
existingEntry.addFile(file);
|
||||
ChangeLogEntry existingEntry = (ChangeLogEntry) entries.get( key );
|
||||
|
||||
existingEntry.addFile( file );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the current input line in the Get File state.
|
||||
* @param line a line of text from the cvs log output
|
||||
*/
|
||||
private void processGetFile(String line)
|
||||
private void processGetFile( String line )
|
||||
{
|
||||
if (line.startsWith(START_FILE))
|
||||
if ( line.startsWith( START_FILE ) )
|
||||
{
|
||||
setCurrentLogEntry(new ChangeLogEntry());
|
||||
setCurrentFile(new ChangeLogFile(line.substring(START_FILE.length(),
|
||||
line.length())));
|
||||
setStatus(GET_REVISION);
|
||||
setCurrentLogEntry( new ChangeLogEntry() );
|
||||
setCurrentFile( new ChangeLogFile( line.substring(
|
||||
START_FILE.length(), line.length() ) ) );
|
||||
setStatus( GET_REVISION );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,20 +237,21 @@ class CvsChangeLogParser implements ChangeLogParser
|
||||
* Process the current input line in the Get Revision state.
|
||||
* @param line a line of text from the cvs log output
|
||||
*/
|
||||
private void processGetRevision(String line)
|
||||
private void processGetRevision( String line )
|
||||
{
|
||||
if (line.startsWith(REVISION_TAG))
|
||||
if ( line.startsWith( REVISION_TAG ) )
|
||||
{
|
||||
getCurrentFile().setRevision(line.substring(REVISION_TAG.length()));
|
||||
setStatus(GET_DATE);
|
||||
getCurrentFile().setRevision( line.substring(
|
||||
REVISION_TAG.length() ) );
|
||||
setStatus( GET_DATE );
|
||||
}
|
||||
else if (line.startsWith(END_FILE))
|
||||
else if ( line.startsWith( END_FILE ) )
|
||||
{
|
||||
// If we encounter an end of file line, it means there
|
||||
// are no more revisions for the current file.
|
||||
// there could also be a file still being processed.
|
||||
setStatus(GET_FILE);
|
||||
addEntry(getCurrentLogEntry(), getCurrentFile());
|
||||
setStatus( GET_FILE );
|
||||
addEntry( getCurrentLogEntry(), getCurrentFile() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,50 +259,57 @@ class CvsChangeLogParser implements ChangeLogParser
|
||||
* Process the current input line in the Get Date state.
|
||||
* @param line a line of text from the cvs log output
|
||||
*/
|
||||
private void processGetDate(String line)
|
||||
private void processGetDate( String line )
|
||||
{
|
||||
if (line.startsWith(DATE_TAG))
|
||||
if ( line.startsWith( DATE_TAG ) )
|
||||
{
|
||||
//date: YYYY/mm/dd HH:mm:ss; author: name
|
||||
//or date: YYYY-mm-dd HH:mm:ss Z; author: name
|
||||
StringTokenizer tokenizer = new StringTokenizer(line, ";");
|
||||
StringTokenizer tokenizer = new StringTokenizer( line, ";" );
|
||||
String dateToken = tokenizer.nextToken();
|
||||
String dateString =
|
||||
dateToken.trim().substring("date: ".length()).trim();
|
||||
getCurrentLogEntry().setDate(parseDate(dateString));
|
||||
String dateString =
|
||||
dateToken.trim().substring( "date: ".length() ).trim();
|
||||
|
||||
getCurrentLogEntry().setDate( parseDate( dateString ) );
|
||||
|
||||
String authorToken = tokenizer.nextToken();
|
||||
String author =
|
||||
authorToken.trim().substring("author: ".length()).trim();
|
||||
getCurrentLogEntry().setAuthor(author);
|
||||
setStatus(GET_COMMENT);
|
||||
String author =
|
||||
authorToken.trim().substring( "author: ".length() ).trim();
|
||||
|
||||
getCurrentLogEntry().setAuthor( author );
|
||||
setStatus( GET_COMMENT );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to parse the given String according to all known CVS timeformats.
|
||||
*
|
||||
*
|
||||
* @param dateString String to parse
|
||||
* @return <code>java.util.Date</code> representing the time.
|
||||
* @throws IllegalArgumentException if it's not possible to parse the date.
|
||||
*/
|
||||
private Date parseDate(String dateString)
|
||||
private Date parseDate( String dateString )
|
||||
{
|
||||
Date date;
|
||||
|
||||
try
|
||||
{
|
||||
date = OLD_CVS_TIMESTAMP_FORMAT.parse(dateString);
|
||||
date = OLD_CVS_TIMESTAMP_FORMAT.parse( dateString );
|
||||
}
|
||||
catch (ParseException e)
|
||||
catch ( ParseException e )
|
||||
{
|
||||
//try other format
|
||||
try {
|
||||
date = NEW_CVS_TIMESTAMP_FORMAT.parse(dateString);
|
||||
} catch (ParseException e1) {
|
||||
throw new IllegalArgumentException("I don't understand this date: "
|
||||
+ dateString);
|
||||
try
|
||||
{
|
||||
date = NEW_CVS_TIMESTAMP_FORMAT.parse( dateString );
|
||||
}
|
||||
catch ( ParseException e1 )
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"I don't understand this date: " + dateString );
|
||||
}
|
||||
}
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
@@ -285,28 +317,31 @@ class CvsChangeLogParser implements ChangeLogParser
|
||||
* Process the current input line in the Get Comment state.
|
||||
* @param line a line of text from the cvs log output
|
||||
*/
|
||||
private void processGetComment(String line)
|
||||
private void processGetComment( String line )
|
||||
{
|
||||
if (line.startsWith(START_REVISION))
|
||||
if ( line.startsWith( START_REVISION ) )
|
||||
{
|
||||
// add entry, and set state to get revision
|
||||
addEntry(getCurrentLogEntry(), getCurrentFile());
|
||||
addEntry( getCurrentLogEntry(), getCurrentFile() );
|
||||
|
||||
// new change log entry
|
||||
setCurrentLogEntry(new ChangeLogEntry());
|
||||
setCurrentLogEntry( new ChangeLogEntry() );
|
||||
|
||||
// same file name, but different rev
|
||||
setCurrentFile(new ChangeLogFile(getCurrentFile().getName()));
|
||||
setStatus(GET_REVISION);
|
||||
setCurrentFile( new ChangeLogFile( getCurrentFile().getName() ) );
|
||||
setStatus( GET_REVISION );
|
||||
}
|
||||
else if (line.startsWith(END_FILE))
|
||||
else if ( line.startsWith( END_FILE ) )
|
||||
{
|
||||
addEntry(getCurrentLogEntry(), getCurrentFile());
|
||||
setStatus(GET_FILE);
|
||||
addEntry( getCurrentLogEntry(), getCurrentFile() );
|
||||
setStatus( GET_FILE );
|
||||
}
|
||||
else
|
||||
{
|
||||
// keep gathering comments
|
||||
getCurrentLogEntry().setComment(
|
||||
getCurrentLogEntry().getComment() + line + "\n");
|
||||
getCurrentLogEntry().setComment( getCurrentLogEntry()
|
||||
.getComment() + line
|
||||
+ "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,16 +353,16 @@ class CvsChangeLogParser implements ChangeLogParser
|
||||
{
|
||||
return currentFile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for property currentFile.
|
||||
* @param currentFile New value of property currentFile.
|
||||
*/
|
||||
private void setCurrentFile(ChangeLogFile currentFile)
|
||||
private void setCurrentFile( ChangeLogFile currentFile )
|
||||
{
|
||||
this.currentFile = currentFile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for property currentLogEntry.
|
||||
* @return Value of property currentLogEntry.
|
||||
@@ -336,16 +371,16 @@ class CvsChangeLogParser implements ChangeLogParser
|
||||
{
|
||||
return currentLogEntry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for property currentLogEntry.
|
||||
* @param currentLogEntry New value of property currentLogEntry.
|
||||
*/
|
||||
private void setCurrentLogEntry(ChangeLogEntry currentLogEntry)
|
||||
private void setCurrentLogEntry( ChangeLogEntry currentLogEntry )
|
||||
{
|
||||
this.currentLogEntry = currentLogEntry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for property status.
|
||||
* @return Value of property status.
|
||||
@@ -354,12 +389,12 @@ class CvsChangeLogParser implements ChangeLogParser
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for property status.
|
||||
* @param status New value of property status.
|
||||
*/
|
||||
private void setStatus(int status)
|
||||
private void setStatus( int status )
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -42,16 +43,17 @@ import org.netbeans.lib.cvsclient.connection.PServerConnection;
|
||||
import org.netbeans.lib.cvsclient.connection.StandardScrambler;
|
||||
import org.netbeans.lib.cvsclient.event.CVSListener;
|
||||
|
||||
|
||||
/**
|
||||
* A Cvs connection that simulates a command line interface.
|
||||
*
|
||||
*
|
||||
* @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
|
||||
*/
|
||||
public class CvsConnection
|
||||
{
|
||||
|
||||
/** Log */
|
||||
private static final Log LOG = LogFactory.getLog(CvsConnection.class);
|
||||
private static final Log LOG = LogFactory.getLog( CvsConnection.class );
|
||||
|
||||
/**
|
||||
* The path to the repository on the server
|
||||
*/
|
||||
@@ -80,27 +82,27 @@ public class CvsConnection
|
||||
|
||||
/**
|
||||
* Execute a configured CVS command
|
||||
*
|
||||
*
|
||||
* @param command the command to execute
|
||||
* @throws CommandException if there is an error running the command
|
||||
*/
|
||||
public void executeCommand(Command command)
|
||||
public void executeCommand( Command command )
|
||||
throws CommandException, AuthenticationException
|
||||
{
|
||||
client.executeCommand(command, globalOptions);
|
||||
client.executeCommand( command, globalOptions );
|
||||
}
|
||||
|
||||
public void setRepository(String repository)
|
||||
public void setRepository( String repository )
|
||||
{
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public void setLocalPath(String localPath)
|
||||
public void setLocalPath( String localPath )
|
||||
{
|
||||
this.localPath = localPath;
|
||||
}
|
||||
|
||||
public void setGlobalOptions(GlobalOptions globalOptions)
|
||||
public void setGlobalOptions( GlobalOptions globalOptions )
|
||||
{
|
||||
this.globalOptions = globalOptions;
|
||||
}
|
||||
@@ -108,54 +110,60 @@ public class CvsConnection
|
||||
/**
|
||||
* Creates the connection and the client and connects.
|
||||
*/
|
||||
private void connect(CVSRoot root, String password)
|
||||
throws IllegalArgumentException, AuthenticationException, CommandAbortedException
|
||||
private void connect( CVSRoot root, String password )
|
||||
throws IllegalArgumentException, AuthenticationException,
|
||||
CommandAbortedException
|
||||
{
|
||||
connection = ConnectionFactory.getConnection(root);
|
||||
if (CVSRoot.METHOD_PSERVER.equals(root.getMethod()))
|
||||
connection = ConnectionFactory.getConnection( root );
|
||||
|
||||
if ( CVSRoot.METHOD_PSERVER.equals( root.getMethod() ) )
|
||||
{
|
||||
((PServerConnection) connection).setEncodedPassword(password);
|
||||
( (PServerConnection) connection ).setEncodedPassword( password );
|
||||
}
|
||||
|
||||
connection.open();
|
||||
|
||||
client = new Client(connection, new StandardAdminHandler());
|
||||
client.setLocalPath(localPath);
|
||||
client = new Client( connection, new StandardAdminHandler() );
|
||||
client.setLocalPath( localPath );
|
||||
}
|
||||
|
||||
private void addListener(CVSListener listener)
|
||||
private void addListener( CVSListener listener )
|
||||
{
|
||||
if (client != null)
|
||||
if ( client != null )
|
||||
{
|
||||
// add a listener to the client
|
||||
client.getEventManager().addCVSListener(listener);
|
||||
client.getEventManager().addCVSListener( listener );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the CVS root, either from the -D option cvs.root or from the CVS
|
||||
* directory
|
||||
*
|
||||
*
|
||||
* @return the CVSRoot string
|
||||
*/
|
||||
private static String getCVSRoot(String workingDir)
|
||||
private static String getCVSRoot( String workingDir )
|
||||
{
|
||||
String root = null;
|
||||
BufferedReader r = null;
|
||||
if (workingDir == null)
|
||||
|
||||
if ( workingDir == null )
|
||||
{
|
||||
workingDir = System.getProperty("user.dir");
|
||||
workingDir = System.getProperty( "user.dir" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File f = new File(workingDir);
|
||||
File rootFile = new File(f, "CVS/Root");
|
||||
if (rootFile.exists())
|
||||
File f = new File( workingDir );
|
||||
File rootFile = new File( f, "CVS/Root" );
|
||||
|
||||
if ( rootFile.exists() )
|
||||
{
|
||||
r = new BufferedReader(new FileReader(rootFile));
|
||||
r = new BufferedReader( new FileReader( rootFile ) );
|
||||
root = r.readLine();
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
catch ( IOException e )
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
@@ -163,46 +171,51 @@ public class CvsConnection
|
||||
{
|
||||
try
|
||||
{
|
||||
if (r != null)
|
||||
if ( r != null )
|
||||
{
|
||||
r.close();
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
catch ( IOException e )
|
||||
{
|
||||
System.err.println("Warning: could not close CVS/Root file!");
|
||||
System.err.println( "Warning: could not close CVS/Root file!" );
|
||||
}
|
||||
}
|
||||
if (root == null)
|
||||
|
||||
if ( root == null )
|
||||
{
|
||||
root = System.getProperty("cvs.root");
|
||||
root = System.getProperty( "cvs.root" );
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process global options passed into the application
|
||||
*
|
||||
*
|
||||
* @param args the argument list, complete
|
||||
* @param globalOptions the global options structure that will be passed to
|
||||
* the command
|
||||
*/
|
||||
private static int processGlobalOptions(
|
||||
String[] args,
|
||||
GlobalOptions globalOptions)
|
||||
private static int processGlobalOptions( String[] args,
|
||||
GlobalOptions globalOptions )
|
||||
{
|
||||
final String getOptString = globalOptions.getOptString();
|
||||
GetOpt go = new GetOpt(args, getOptString);
|
||||
GetOpt go = new GetOpt( args, getOptString );
|
||||
int ch = -1;
|
||||
while ((ch = go.getopt()) != GetOpt.optEOF)
|
||||
|
||||
while ( ( ch = go.getopt() ) != GetOpt.optEOF )
|
||||
{
|
||||
//System.out.println("Global option '"+((char) ch)+"',
|
||||
// '"+go.optArgGet()+"'");
|
||||
String arg = go.optArgGet();
|
||||
boolean success =
|
||||
globalOptions.setCVSCommand((char) ch, arg);
|
||||
if (!success)
|
||||
throw new IllegalArgumentException( "Failed to set CVS Command: -" + ch + " = " + arg );
|
||||
boolean success = globalOptions.setCVSCommand( (char) ch, arg );
|
||||
|
||||
if ( !success )
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Failed to set CVS Command: -" + ch + " = " + arg );
|
||||
}
|
||||
}
|
||||
|
||||
return go.optIndexGet();
|
||||
@@ -211,135 +224,151 @@ public class CvsConnection
|
||||
/**
|
||||
* Lookup the password in the .cvspass file. This file is looked for in the
|
||||
* user.home directory if the option cvs.passfile is not set
|
||||
*
|
||||
*
|
||||
* @param cvsRoot the CVS root for which the password is being searched
|
||||
* @return the password, scrambled
|
||||
*/
|
||||
private static String lookupPassword(String cvsRoot)
|
||||
private static String lookupPassword( String cvsRoot )
|
||||
{
|
||||
File passFile =
|
||||
new File(
|
||||
System.getProperty(
|
||||
"cvs.passfile",
|
||||
System.getProperty("user.home") + "/.cvspass"));
|
||||
new File( System.getProperty( "cvs.passfile",
|
||||
System.getProperty( "user.home" ) + "/.cvspass" ) );
|
||||
|
||||
BufferedReader reader = null;
|
||||
String password = null;
|
||||
|
||||
try
|
||||
{
|
||||
reader = new BufferedReader(new FileReader(passFile));
|
||||
password = processCvspass(cvsRoot, reader);
|
||||
reader = new BufferedReader( new FileReader( passFile ) );
|
||||
password = processCvspass( cvsRoot, reader );
|
||||
}
|
||||
catch (IOException e)
|
||||
catch ( IOException e )
|
||||
{
|
||||
LOG.warn("Could not read password for '" + cvsRoot + "' from '" + passFile + "'", e);
|
||||
LOG.warn( "Could not read password for '" + cvsRoot + "' from '"
|
||||
+ passFile + "'", e );
|
||||
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (reader != null)
|
||||
if ( reader != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
reader.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
catch ( IOException e )
|
||||
{
|
||||
LOG.error("Warning: could not close password file.");
|
||||
LOG.error( "Warning: could not close password file." );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (password == null)
|
||||
|
||||
if ( password == null )
|
||||
{
|
||||
LOG.error("Didn't find password for CVSROOT '" + cvsRoot + "'.");
|
||||
LOG.error( "Didn't find password for CVSROOT '" + cvsRoot + "'." );
|
||||
}
|
||||
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read in a list of return delimited lines from .cvspass and retreive
|
||||
* the password. Return null if the cvsRoot can't be found.
|
||||
*
|
||||
* @param cvsRoot the CVS root for which the password is being searched
|
||||
* @param reader A buffered reader of lines of cvspass information
|
||||
* @return The password, or null if it can't be found.
|
||||
* @throws IOException
|
||||
*/
|
||||
static String processCvspass(String cvsRoot, BufferedReader reader) throws IOException {
|
||||
String line;
|
||||
String password = null;
|
||||
while ((line = reader.readLine()) != null)
|
||||
{
|
||||
if (line.startsWith("/"))
|
||||
{
|
||||
Vector cvspass = StringUtils.split(line, ' ');
|
||||
String cvspassRoot = (String)cvspass.get(1);
|
||||
if (compareCvsRoot(cvsRoot, cvspassRoot)) {
|
||||
int index = line.indexOf(cvspassRoot) + cvspassRoot.length()+1;
|
||||
password = line.substring(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (line.startsWith(cvsRoot))
|
||||
{
|
||||
password = line.substring(cvsRoot.length() + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return password;
|
||||
}
|
||||
|
||||
static boolean compareCvsRoot(String cvsRoot, String target)
|
||||
*
|
||||
* @param cvsRoot the CVS root for which the password is being searched
|
||||
* @param reader A buffered reader of lines of cvspass information
|
||||
* @return The password, or null if it can't be found.
|
||||
* @throws IOException
|
||||
*/
|
||||
static String processCvspass( String cvsRoot, BufferedReader reader )
|
||||
throws IOException
|
||||
{
|
||||
String s1 = completeCvsRootPort(cvsRoot);
|
||||
String s2 = completeCvsRootPort(target);
|
||||
if (s1 != null && s1.equals(s2))
|
||||
String line;
|
||||
String password = null;
|
||||
|
||||
while ( ( line = reader.readLine() ) != null )
|
||||
{
|
||||
if ( line.startsWith( "/" ) )
|
||||
{
|
||||
Vector cvspass = StringUtils.split( line, ' ' );
|
||||
String cvspassRoot = (String) cvspass.get( 1 );
|
||||
|
||||
if ( compareCvsRoot( cvsRoot, cvspassRoot ) )
|
||||
{
|
||||
int index =
|
||||
line.indexOf( cvspassRoot ) + cvspassRoot.length()
|
||||
+ 1;
|
||||
|
||||
password = line.substring( index );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( line.startsWith( cvsRoot ) )
|
||||
{
|
||||
password = line.substring( cvsRoot.length() + 1 );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return password;
|
||||
}
|
||||
|
||||
static boolean compareCvsRoot( String cvsRoot, String target )
|
||||
{
|
||||
String s1 = completeCvsRootPort( cvsRoot );
|
||||
String s2 = completeCvsRootPort( target );
|
||||
|
||||
if ( ( s1 != null ) && s1.equals( s2 ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
private static String completeCvsRootPort(String cvsRoot)
|
||||
|
||||
private static String completeCvsRootPort( String cvsRoot )
|
||||
{
|
||||
String result = cvsRoot;
|
||||
int idx = cvsRoot.indexOf(':');
|
||||
for (int i=0; i < 2 && idx != -1; i++)
|
||||
int idx = cvsRoot.indexOf( ':' );
|
||||
|
||||
for ( int i = 0; ( i < 2 ) && ( idx != -1 ); i++ )
|
||||
{
|
||||
idx = cvsRoot.indexOf(':', idx+1);
|
||||
idx = cvsRoot.indexOf( ':', idx + 1 );
|
||||
}
|
||||
if (idx != -1 && cvsRoot.charAt(idx+1) == '/')
|
||||
|
||||
if ( ( idx != -1 ) && ( cvsRoot.charAt( idx + 1 ) == '/' ) )
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(cvsRoot.substring(0, idx+1));
|
||||
sb.append("2401");
|
||||
sb.append(cvsRoot.substring(idx+1));
|
||||
|
||||
sb.append( cvsRoot.substring( 0, idx + 1 ) );
|
||||
sb.append( "2401" );
|
||||
sb.append( cvsRoot.substring( idx + 1 ) );
|
||||
result = sb.toString();
|
||||
}
|
||||
return result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the CVS command passed in args[] array with all necessary
|
||||
* options. The only difference from main() method is, that this method
|
||||
* does not exit the JVM and provides command output.
|
||||
*
|
||||
*
|
||||
* @param args The command with options
|
||||
*/
|
||||
public static boolean processCommand(
|
||||
String[] args,
|
||||
String localPath,
|
||||
CVSListener listener) throws Exception
|
||||
public static boolean processCommand( String[] args, String localPath,
|
||||
CVSListener listener )
|
||||
throws Exception
|
||||
{
|
||||
|
||||
// Set up the CVSRoot. Note that it might still be null after this
|
||||
// call if the user has decided to set it with the -d command line
|
||||
// global option
|
||||
GlobalOptions globalOptions = new GlobalOptions();
|
||||
globalOptions.setCVSRoot(getCVSRoot(localPath));
|
||||
|
||||
globalOptions.setCVSRoot( getCVSRoot( localPath ) );
|
||||
|
||||
// Set up any global options specified. These occur before the
|
||||
// name of the command to run
|
||||
@@ -347,37 +376,39 @@ public class CvsConnection
|
||||
|
||||
try
|
||||
{
|
||||
commandIndex = processGlobalOptions(args, globalOptions);
|
||||
commandIndex = processGlobalOptions( args, globalOptions );
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
catch ( IllegalArgumentException e )
|
||||
{
|
||||
LOG.error("Invalid argument: " + e);
|
||||
LOG.error( "Invalid argument: " + e );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// if we don't have a CVS root by now, the user has messed up
|
||||
if (globalOptions.getCVSRoot() == null)
|
||||
if ( globalOptions.getCVSRoot() == null )
|
||||
{
|
||||
LOG.error(
|
||||
"No CVS root is set. Check your <repository> information in the POM.");
|
||||
LOG.error(
|
||||
"No CVS root is set. Check your <repository> information in the POM." );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse the CVS root into its constituent parts
|
||||
CVSRoot root = null;
|
||||
final String cvsRoot = globalOptions.getCVSRoot();
|
||||
|
||||
try
|
||||
{
|
||||
root = CVSRoot.parse(cvsRoot);
|
||||
root = CVSRoot.parse( cvsRoot );
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
catch ( IllegalArgumentException e )
|
||||
{
|
||||
LOG.error(
|
||||
"Incorrect format for CVSRoot: "
|
||||
+ cvsRoot
|
||||
+ "\nThe correct format is: "
|
||||
+ "[:method:][[user][:password]@][hostname:[port]]/path/to/repository"
|
||||
+ "\nwhere \"method\" is pserver.");
|
||||
LOG.error( "Incorrect format for CVSRoot: " + cvsRoot
|
||||
+ "\nThe correct format is: "
|
||||
+ "[:method:][[user][:password]@][hostname:[port]]/path/to/repository"
|
||||
+ "\nwhere \"method\" is pserver." );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -385,58 +416,59 @@ public class CvsConnection
|
||||
|
||||
// this is not login, but a 'real' cvs command, so construct it,
|
||||
// set the options, and then connect to the server and execute it
|
||||
|
||||
Command c = null;
|
||||
|
||||
try
|
||||
{
|
||||
c =
|
||||
CommandFactory.getDefault().createCommand(
|
||||
command,
|
||||
args,
|
||||
++commandIndex,
|
||||
globalOptions,
|
||||
localPath);
|
||||
c = CommandFactory.getDefault().createCommand( command, args,
|
||||
++commandIndex, globalOptions, localPath );
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
catch ( IllegalArgumentException e )
|
||||
{
|
||||
LOG.error("Illegal argument: " + e.getMessage());
|
||||
LOG.error( "Illegal argument: " + e.getMessage() );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
String password = null;
|
||||
|
||||
if (CVSRoot.METHOD_PSERVER.equals(root.getMethod()))
|
||||
if ( CVSRoot.METHOD_PSERVER.equals( root.getMethod() ) )
|
||||
{
|
||||
password = root.getPassword();
|
||||
if (password != null)
|
||||
|
||||
if ( password != null )
|
||||
{
|
||||
password = StandardScrambler.getInstance().scramble(password);
|
||||
password =
|
||||
StandardScrambler.getInstance().scramble( password );
|
||||
}
|
||||
else
|
||||
{
|
||||
password = lookupPassword(cvsRoot);
|
||||
if (password == null)
|
||||
password = lookupPassword( cvsRoot );
|
||||
|
||||
if ( password == null )
|
||||
{
|
||||
password = StandardScrambler.getInstance().scramble("");
|
||||
password = StandardScrambler.getInstance().scramble( "" );
|
||||
|
||||
// an empty password
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CvsConnection cvsCommand = new CvsConnection();
|
||||
cvsCommand.setGlobalOptions(globalOptions);
|
||||
cvsCommand.setRepository(root.getRepository());
|
||||
|
||||
cvsCommand.setGlobalOptions( globalOptions );
|
||||
cvsCommand.setRepository( root.getRepository() );
|
||||
|
||||
// the local path is just the path where we executed the
|
||||
// command. This is the case for command-line CVS but not
|
||||
// usually for GUI front-ends
|
||||
cvsCommand.setLocalPath(localPath);
|
||||
|
||||
cvsCommand.connect(root, password);
|
||||
cvsCommand.addListener(listener);
|
||||
LOG.debug("Executing CVS command: " + c.getCVSCommand());
|
||||
cvsCommand.executeCommand(c);
|
||||
|
||||
cvsCommand.setLocalPath( localPath );
|
||||
|
||||
cvsCommand.connect( root, password );
|
||||
cvsCommand.addListener( listener );
|
||||
LOG.debug( "Executing CVS command: " + c.getCVSCommand() );
|
||||
cvsCommand.executeCommand( c );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,10 +20,11 @@ package org.apache.maven.cvslib;
|
||||
import org.netbeans.lib.cvsclient.event.CVSAdapter;
|
||||
import org.netbeans.lib.cvsclient.event.MessageEvent;
|
||||
|
||||
|
||||
/**
|
||||
* A basic implementation of a CVS listener. It merely saves up
|
||||
* into StringBuffers the stdout and stderr printstreams.
|
||||
*
|
||||
*
|
||||
* @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
|
||||
*/
|
||||
public class CvsLogListener extends CVSAdapter
|
||||
@@ -33,33 +34,32 @@ public class CvsLogListener extends CVSAdapter
|
||||
private StringBuffer stderr = new StringBuffer();
|
||||
|
||||
/**
|
||||
* Called when the server wants to send a message to be displayed to the
|
||||
* user. The message is only for information purposes and clients can
|
||||
* choose to ignore these messages if they wish.
|
||||
*
|
||||
* @param e the event
|
||||
*/
|
||||
public void messageSent(MessageEvent e)
|
||||
* Called when the server wants to send a message to be displayed to the
|
||||
* user. The message is only for information purposes and clients can
|
||||
* choose to ignore these messages if they wish.
|
||||
*
|
||||
* @param e the event
|
||||
*/
|
||||
public void messageSent( MessageEvent e )
|
||||
{
|
||||
String line = e.getMessage();
|
||||
StringBuffer stream = e.isError() ? stderr : stdout;
|
||||
|
||||
if (e.isTagged())
|
||||
if ( e.isTagged() )
|
||||
{
|
||||
String message =
|
||||
MessageEvent.parseTaggedMessage(taggedLine, e.getMessage());
|
||||
if (message != null)
|
||||
MessageEvent.parseTaggedMessage( taggedLine, e.getMessage() );
|
||||
|
||||
if ( message != null )
|
||||
{
|
||||
//stream.println(message);
|
||||
stream.append(message+"\n");
|
||||
|
||||
stream.append( message + "\n" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//stream.println(line);
|
||||
stream.append(line+"\n");
|
||||
|
||||
stream.append( line + "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,5 +70,4 @@ public class CvsLogListener extends CVSAdapter
|
||||
{
|
||||
return stdout;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import org.apache.maven.changelog.ChangeLogFactory;
|
||||
import org.apache.maven.changelog.ChangeLogGenerator;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
|
||||
|
||||
/**
|
||||
* Provides Perforce specific instances of the ChangeLogGenerator and
|
||||
* ChangeLogParser interfaces.
|
||||
@@ -37,7 +38,7 @@ import org.apache.maven.changelog.ChangeLogParser;
|
||||
* instance. The portion of the URL following the host:port should
|
||||
* match the FILESPEC in the repository connection element, sans the
|
||||
* '...'. It must end with a '/'.
|
||||
*
|
||||
*
|
||||
* For example,
|
||||
* <pre>
|
||||
* <repository>
|
||||
@@ -51,7 +52,7 @@ import org.apache.maven.changelog.ChangeLogParser;
|
||||
* </pre>
|
||||
*
|
||||
* @author <a href="mailto:jim@crossleys.org">Jim Crossley</a>
|
||||
* @version $Id:
|
||||
* @version $Id:
|
||||
*/
|
||||
public class PerforceChangeLogFactory implements ChangeLogFactory
|
||||
{
|
||||
@@ -61,7 +62,7 @@ public class PerforceChangeLogFactory implements ChangeLogFactory
|
||||
public PerforceChangeLogFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a Perforce specific ChangeLogGenerator.
|
||||
*
|
||||
@@ -81,4 +82,4 @@ public class PerforceChangeLogFactory implements ChangeLogFactory
|
||||
{
|
||||
return new PerforceChangeLogParser();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,26 +18,30 @@ package org.apache.maven.perforcelib;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.maven.changelog.AbstractChangeLogGenerator;
|
||||
import org.apache.tools.ant.types.Commandline;
|
||||
|
||||
|
||||
/**
|
||||
* A Perforce implementation of the {@link org.apache.maven.changelog.ChangeLog}
|
||||
* interface.
|
||||
*
|
||||
* @author <a href="mailto:jim@crossleys.org">Jim Crossley</a>
|
||||
* @version $Id:
|
||||
* @version $Id:
|
||||
*/
|
||||
class PerforceChangeLogGenerator extends AbstractChangeLogGenerator
|
||||
{
|
||||
/** The position after the connection prefix, 'scm:perforce:' */
|
||||
private static final int POS_PARAMS = 13;
|
||||
|
||||
/** Log */
|
||||
private static final Log LOG = LogFactory.getLog(PerforceChangeLogGenerator.class);
|
||||
|
||||
/** Log */
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog( PerforceChangeLogGenerator.class );
|
||||
|
||||
/**
|
||||
* Constructs the appropriate command line to execute the perforce
|
||||
@@ -48,61 +52,67 @@ class PerforceChangeLogGenerator extends AbstractChangeLogGenerator
|
||||
*
|
||||
* @return the cvs command line to be executed.
|
||||
*/
|
||||
protected Commandline getScmLogCommand()
|
||||
protected Commandline getScmLogCommand()
|
||||
{
|
||||
String conn = getConnection();
|
||||
if (!conn.startsWith("scm:perforce:"))
|
||||
|
||||
if ( !conn.startsWith( "scm:perforce:" ) )
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"repository connection string"
|
||||
+ " does not specify 'perforce' as the scm");
|
||||
throw new IllegalArgumentException( "repository connection string"
|
||||
+ " does not specify 'perforce' as the scm" );
|
||||
}
|
||||
int lastColon = conn.lastIndexOf(':');
|
||||
String fileSpec = conn.substring(lastColon+1);
|
||||
String p4port = (POS_PARAMS>lastColon) ? null : conn.substring(POS_PARAMS, lastColon);
|
||||
|
||||
int lastColon = conn.lastIndexOf( ':' );
|
||||
String fileSpec = conn.substring( lastColon + 1 );
|
||||
String p4port =
|
||||
( POS_PARAMS > lastColon ) ? null
|
||||
: conn.substring( POS_PARAMS, lastColon );
|
||||
|
||||
Commandline command = new Commandline();
|
||||
command.setExecutable("p4");
|
||||
if (p4port != null) {
|
||||
command.createArgument().setValue("-p");
|
||||
command.createArgument().setValue(p4port);
|
||||
|
||||
command.setExecutable( "p4" );
|
||||
|
||||
if ( p4port != null )
|
||||
{
|
||||
command.createArgument().setValue( "-p" );
|
||||
command.createArgument().setValue( p4port );
|
||||
}
|
||||
command.createArgument().setValue("filelog");
|
||||
command.createArgument().setValue("-tl");
|
||||
command.createArgument().setValue(fileSpec);
|
||||
|
||||
|
||||
command.createArgument().setValue( "filelog" );
|
||||
command.createArgument().setValue( "-tl" );
|
||||
command.createArgument().setValue( fileSpec );
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* The Perforce filelog doesn't support a revision, i.e. date,
|
||||
* range
|
||||
*
|
||||
*
|
||||
* @param before The starting point.
|
||||
* @param to The ending point.
|
||||
* @return An empty string
|
||||
*/
|
||||
protected String getScmDateArgument(Date before, Date to)
|
||||
protected String getScmDateArgument( Date before, Date to )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle ChangeLogParser IOExceptions.
|
||||
*
|
||||
/**
|
||||
* Handle ChangeLogParser IOExceptions.
|
||||
*
|
||||
* @param ioe The IOException thrown.
|
||||
* @throws IOException If the handler doesn't wish to handle the
|
||||
* exception.
|
||||
*/
|
||||
protected void handleParserException(IOException ioe)
|
||||
protected void handleParserException( IOException ioe )
|
||||
throws IOException
|
||||
{
|
||||
if (ioe.getMessage().indexOf("CreateProcess") != -1
|
||||
|| ioe.getMessage().indexOf("p4: not found") != -1)
|
||||
if ( ( ioe.getMessage().indexOf( "CreateProcess" ) != -1 )
|
||||
|| ( ioe.getMessage().indexOf( "p4: not found" ) != -1 ) )
|
||||
{
|
||||
// can't find p4 on Win32 or Linux...
|
||||
LOG.error(
|
||||
"Unable to find p4 executable. Changelog will be empty");
|
||||
LOG.error( "Unable to find p4 executable. Changelog will be empty" );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -113,8 +123,9 @@ class PerforceChangeLogGenerator extends AbstractChangeLogGenerator
|
||||
/**
|
||||
* @see AbstractChangeLogGenerator#getScmTagArgument(String, String)
|
||||
*/
|
||||
protected String getScmTagArgument(String tagStart, String tagEnd)
|
||||
protected String getScmTagArgument( String tagStart, String tagEnd )
|
||||
{
|
||||
throw new UnsupportedOperationException("This plugin currently does not support generating logs from tags with Perforce.");
|
||||
throw new UnsupportedOperationException(
|
||||
"This plugin currently does not support generating logs from tags with Perforce." );
|
||||
}
|
||||
}
|
||||
@@ -18,45 +18,45 @@ package org.apache.maven.perforcelib;
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.maven.changelog.ChangeLog;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
import org.apache.maven.changelog.ChangeLogEntry;
|
||||
import org.apache.maven.changelog.ChangeLogFile;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
import org.apache.regexp.RE;
|
||||
import org.apache.regexp.RESyntaxException;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
||||
/**
|
||||
* A class to parse the log output from the Perforce 'filelog'
|
||||
* command.
|
||||
*
|
||||
* @author <a href="mailto:jim@crossleys.org">Jim Crossley</a>
|
||||
* @version $Id:
|
||||
* @version $Id:
|
||||
*/
|
||||
class PerforceChangeLogParser implements ChangeLogParser
|
||||
{
|
||||
/** Date formatter for perforce timestamp */
|
||||
private static final SimpleDateFormat PERFORCE_TIMESTAMP =
|
||||
new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
||||
new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" );
|
||||
|
||||
/** Log */
|
||||
private static final Log LOG = LogFactory.getLog (PerforceChangeLogParser.class);
|
||||
|
||||
/**
|
||||
* RCS entries, in reverse changelist number order
|
||||
*/
|
||||
private Map entries = new TreeMap(Collections.reverseOrder());
|
||||
/** Log */
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog( PerforceChangeLogParser.class );
|
||||
|
||||
/** State machine constant: expecting revision and/or file information */
|
||||
private static final int GET_REVISION = 1;
|
||||
@@ -72,16 +72,26 @@ class PerforceChangeLogParser implements ChangeLogParser
|
||||
|
||||
/** A file line begins with two slashes */
|
||||
private static final String FILE_BEGIN_TOKEN = "//";
|
||||
private static final String pattern =
|
||||
"^\\.\\.\\. #(\\d+) " // revision number
|
||||
+ "change (\\d+) .* " // changelist number
|
||||
+ "on (.*) " // date
|
||||
+ "by (.*)@"; // author
|
||||
|
||||
/**
|
||||
* RCS entries, in reverse changelist number order
|
||||
*/
|
||||
private Map entries = new TreeMap( Collections.reverseOrder() );
|
||||
|
||||
/** Current status of the parser */
|
||||
private int status = GET_REVISION;
|
||||
|
||||
|
||||
/** The current log entry being processed by the parser */
|
||||
private ChangeLogEntry currentLogEntry;
|
||||
|
||||
/** the current file being processed by the parser */
|
||||
private String currentFile;
|
||||
|
||||
|
||||
/** The regular expression used to match header lines */
|
||||
private RE revisionRegexp;
|
||||
|
||||
@@ -93,22 +103,20 @@ class PerforceChangeLogParser implements ChangeLogParser
|
||||
|
||||
/** The depot filespec will be stripped from each filename */
|
||||
private int prefixLength;
|
||||
|
||||
private static final String pattern =
|
||||
"^\\.\\.\\. #(\\d+) " + // revision number
|
||||
"change (\\d+) .* " + // changelist number
|
||||
"on (.*) " + // date
|
||||
"by (.*)@"; // author
|
||||
|
||||
/**
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public PerforceChangeLogParser()
|
||||
{
|
||||
try {
|
||||
revisionRegexp = new RE(pattern);
|
||||
} catch (RESyntaxException ignored) {
|
||||
LOG.error("Could not create regexp to parse perforce log file", ignored);
|
||||
try
|
||||
{
|
||||
revisionRegexp = new RE( pattern );
|
||||
}
|
||||
catch ( RESyntaxException ignored )
|
||||
{
|
||||
LOG.error( "Could not create regexp to parse perforce log file",
|
||||
ignored );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,25 +125,27 @@ class PerforceChangeLogParser implements ChangeLogParser
|
||||
*
|
||||
* @param changeLog The controlling task
|
||||
* @see ChangeLogParser#init(ChangeLog)
|
||||
*/
|
||||
public void init(ChangeLog changeLog)
|
||||
*/
|
||||
public void init( ChangeLog changeLog )
|
||||
{
|
||||
this.changeLog = changeLog;
|
||||
setDateRange();
|
||||
|
||||
String conn = changeLog.getRepositoryConnection();
|
||||
String filespec = conn.substring(conn.lastIndexOf(':')+1);
|
||||
this.prefixLength = 1 + filespec.lastIndexOf ('/');
|
||||
String filespec = conn.substring( conn.lastIndexOf( ':' ) + 1 );
|
||||
|
||||
this.prefixLength = 1 + filespec.lastIndexOf( '/' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up any parser resources.
|
||||
*
|
||||
* @see ChangeLogParser#cleanup()
|
||||
*/
|
||||
*/
|
||||
public void cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the input stream into a collection of entries
|
||||
*
|
||||
@@ -143,31 +153,41 @@ class PerforceChangeLogParser implements ChangeLogParser
|
||||
* @return A collection of ChangeLogEntry's
|
||||
* @throws IOException When there are errors reading the provided stream
|
||||
*/
|
||||
public Collection parse(InputStream anInputStream) throws IOException
|
||||
public Collection parse( InputStream anInputStream )
|
||||
throws IOException
|
||||
{
|
||||
BufferedReader stream = new BufferedReader(new InputStreamReader(anInputStream));
|
||||
BufferedReader stream =
|
||||
new BufferedReader( new InputStreamReader( anInputStream ) );
|
||||
|
||||
String line = null;
|
||||
while ((line = stream.readLine()) != null)
|
||||
|
||||
while ( ( line = stream.readLine() ) != null )
|
||||
{
|
||||
switch (status)
|
||||
switch ( status )
|
||||
{
|
||||
case GET_REVISION:
|
||||
processGetRevision(line);
|
||||
break;
|
||||
case GET_COMMENT_BEGIN:
|
||||
status = GET_COMMENT;
|
||||
break;
|
||||
case GET_COMMENT:
|
||||
processGetComment(line);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown state: " + status);
|
||||
case GET_REVISION :
|
||||
processGetRevision( line );
|
||||
|
||||
break;
|
||||
|
||||
case GET_COMMENT_BEGIN :
|
||||
status = GET_COMMENT;
|
||||
|
||||
break;
|
||||
|
||||
case GET_COMMENT :
|
||||
processGetComment( line );
|
||||
|
||||
break;
|
||||
|
||||
default :
|
||||
throw new IllegalStateException( "Unknown state: " + status );
|
||||
}
|
||||
}
|
||||
|
||||
return entries.values();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a change log entry to the list (if it's not already there)
|
||||
* with the given file.
|
||||
@@ -175,43 +195,54 @@ class PerforceChangeLogParser implements ChangeLogParser
|
||||
* with the same key (p4 change number) doesn't exist already.
|
||||
* @param file a {@link ChangeLogFile} to be added to the entry
|
||||
*/
|
||||
private void addEntry(ChangeLogEntry entry, ChangeLogFile file)
|
||||
private void addEntry( ChangeLogEntry entry, ChangeLogFile file )
|
||||
{
|
||||
if (beforeDate != null) {
|
||||
if (entry.getDate().before(beforeDate)) {
|
||||
if ( beforeDate != null )
|
||||
{
|
||||
if ( entry.getDate().before( beforeDate ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
Integer key = new Integer(revisionRegexp.getParen(2));
|
||||
if (!entries.containsKey(key)) {
|
||||
entry.addFile(file);
|
||||
entries.put(key, entry);
|
||||
} else {
|
||||
ChangeLogEntry existingEntry = (ChangeLogEntry) entries.get(key);
|
||||
existingEntry.addFile(file);
|
||||
|
||||
Integer key = new Integer( revisionRegexp.getParen( 2 ) );
|
||||
|
||||
if ( !entries.containsKey( key ) )
|
||||
{
|
||||
entry.addFile( file );
|
||||
entries.put( key, entry );
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeLogEntry existingEntry = (ChangeLogEntry) entries.get( key );
|
||||
|
||||
existingEntry.addFile( file );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Most of the relevant info is on the revision line matching the
|
||||
* 'pattern' string.
|
||||
*
|
||||
* @param line A line of text from the perforce log output
|
||||
*/
|
||||
private void processGetRevision(String line)
|
||||
private void processGetRevision( String line )
|
||||
{
|
||||
if (line.startsWith(FILE_BEGIN_TOKEN)) {
|
||||
currentFile = line.substring (this.prefixLength);
|
||||
if ( line.startsWith( FILE_BEGIN_TOKEN ) )
|
||||
{
|
||||
currentFile = line.substring( this.prefixLength );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!revisionRegexp.match(line)) {
|
||||
|
||||
if ( !revisionRegexp.match( line ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
currentLogEntry = new ChangeLogEntry();
|
||||
currentLogEntry.setDate(parseDate(revisionRegexp.getParen(3)));
|
||||
currentLogEntry.setAuthor(revisionRegexp.getParen(4));
|
||||
currentLogEntry.setDate( parseDate( revisionRegexp.getParen( 3 ) ) );
|
||||
currentLogEntry.setAuthor( revisionRegexp.getParen( 4 ) );
|
||||
|
||||
status = GET_COMMENT_BEGIN;
|
||||
}
|
||||
@@ -222,29 +253,38 @@ class PerforceChangeLogParser implements ChangeLogParser
|
||||
*
|
||||
* @param line a line of text from the perforce log output
|
||||
*/
|
||||
private void processGetComment(String line)
|
||||
private void processGetComment( String line )
|
||||
{
|
||||
if (line.equals(COMMENT_DELIMITER)) {
|
||||
addEntry(currentLogEntry, new ChangeLogFile(currentFile, revisionRegexp.getParen(1)));
|
||||
if ( line.equals( COMMENT_DELIMITER ) )
|
||||
{
|
||||
addEntry( currentLogEntry,
|
||||
new ChangeLogFile( currentFile, revisionRegexp.getParen( 1 ) ) );
|
||||
status = GET_REVISION;
|
||||
} else {
|
||||
currentLogEntry.setComment(currentLogEntry.getComment() + line + "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
currentLogEntry.setComment( currentLogEntry.getComment() + line
|
||||
+ "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Converts the date timestamp from the perforce output into a date
|
||||
* object.
|
||||
*
|
||||
*
|
||||
* @return A date representing the timestamp of the log entry.
|
||||
*/
|
||||
private Date parseDate(String date)
|
||||
private Date parseDate( String date )
|
||||
{
|
||||
try {
|
||||
return PERFORCE_TIMESTAMP.parse(date);
|
||||
} catch (ParseException e) {
|
||||
LOG.error("ParseException Caught", e);
|
||||
return null;
|
||||
try
|
||||
{
|
||||
return PERFORCE_TIMESTAMP.parse( date );
|
||||
}
|
||||
catch ( ParseException e )
|
||||
{
|
||||
LOG.error( "ParseException Caught", e );
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,14 +297,18 @@ class PerforceChangeLogParser implements ChangeLogParser
|
||||
*/
|
||||
private void setDateRange()
|
||||
{
|
||||
if (this.changeLog == null ||
|
||||
this.changeLog.getRange() == null ||
|
||||
this.changeLog.getRange().length() == 0)
|
||||
if ( ( this.changeLog == null )
|
||||
|| ( this.changeLog.getRange() == null )
|
||||
|| ( this.changeLog.getRange().length() == 0 ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
int days = Integer.parseInt(this.changeLog.getRange());
|
||||
beforeDate = new Date(System.currentTimeMillis() - (long) days * 24 * 60 * 60 * 1000);
|
||||
|
||||
int days = Integer.parseInt( this.changeLog.getRange() );
|
||||
|
||||
beforeDate =
|
||||
new Date( System.currentTimeMillis()
|
||||
- ( (long) days * 24 * 60 * 60 * 1000 ) );
|
||||
}
|
||||
|
||||
public void setDateFormatInFile( String dateFormat )
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.apache.maven.changelog.ChangeLogFactory;
|
||||
import org.apache.maven.changelog.ChangeLogGenerator;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
|
||||
|
||||
/**
|
||||
* Provides Starteam specific instances of the ChangeLogGenerator and
|
||||
* ChangeLogParser interfaces.
|
||||
@@ -36,7 +37,7 @@ public class StarteamChangeLogFactory implements ChangeLogFactory
|
||||
public StarteamChangeLogFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a Starteam specific ChangeLogGenerator.
|
||||
*
|
||||
|
||||
@@ -18,15 +18,20 @@ package org.apache.maven.starteamlib;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
// commons imports
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
// maven imports
|
||||
import org.apache.maven.changelog.AbstractChangeLogGenerator;
|
||||
|
||||
// ant imports
|
||||
import org.apache.tools.ant.types.Commandline;
|
||||
|
||||
|
||||
/**
|
||||
* A Starteam implementation of the {@link org.apache.maven.changelog.ChangeLog}
|
||||
* interface.
|
||||
@@ -37,44 +42,47 @@ import org.apache.tools.ant.types.Commandline;
|
||||
class StarteamChangeLogGenerator extends AbstractChangeLogGenerator
|
||||
{
|
||||
/** Log */
|
||||
private static final Log LOG = LogFactory.getLog(
|
||||
StarteamChangeLogGenerator.class);
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog( StarteamChangeLogGenerator.class );
|
||||
|
||||
/**
|
||||
* Constructs the appropriate command line to execute the starteam
|
||||
* log command whose output is then later parsed.
|
||||
*
|
||||
* @return the starteam command line to be executed.
|
||||
*/
|
||||
protected Commandline getScmLogCommand()
|
||||
protected Commandline getScmLogCommand()
|
||||
{
|
||||
Commandline command = new Commandline();
|
||||
command.setExecutable("stcmd");
|
||||
command.createArgument().setValue("hist");
|
||||
command.createArgument().setValue("-x");
|
||||
command.createArgument().setValue("-nologo");
|
||||
command.createArgument().setValue("-is");
|
||||
command.createArgument().setValue("-p");
|
||||
|
||||
command.setExecutable( "stcmd" );
|
||||
command.createArgument().setValue( "hist" );
|
||||
command.createArgument().setValue( "-x" );
|
||||
command.createArgument().setValue( "-nologo" );
|
||||
command.createArgument().setValue( "-is" );
|
||||
command.createArgument().setValue( "-p" );
|
||||
|
||||
String repo = changeLogExecutor.getRepositoryConnection();
|
||||
|
||||
if ("starteam".equals(repo.substring(4, 12)))
|
||||
if ( "starteam".equals( repo.substring( 4, 12 ) ) )
|
||||
{
|
||||
repo = repo.substring(13);
|
||||
command.createArgument().setValue(repo);
|
||||
repo = repo.substring( 13 );
|
||||
command.createArgument().setValue( repo );
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Construct the Starteam command-line argument that is used to specify
|
||||
* the appropriate date range. This date option doesn't supported with
|
||||
* Starteam
|
||||
*
|
||||
*
|
||||
* @param before The starting point.
|
||||
* @param to The ending point.
|
||||
* @return An empty string
|
||||
*/
|
||||
protected String getScmDateArgument(Date before, Date to)
|
||||
protected String getScmDateArgument( Date before, Date to )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
@@ -82,27 +90,29 @@ class StarteamChangeLogGenerator extends AbstractChangeLogGenerator
|
||||
/**
|
||||
* @see AbstractChangeLogGenerator#getScmTagArgument(String, String)
|
||||
*/
|
||||
protected String getScmTagArgument(String tagStart, String tagEnd)
|
||||
protected String getScmTagArgument( String tagStart, String tagEnd )
|
||||
{
|
||||
throw new UnsupportedOperationException("This plugin currently does not support generating logs from tags with Starteam.");
|
||||
throw new UnsupportedOperationException(
|
||||
"This plugin currently does not support generating logs from tags with Starteam." );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle ChangeLogParser IOExceptions.
|
||||
*
|
||||
/**
|
||||
* Handle ChangeLogParser IOExceptions.
|
||||
*
|
||||
* @param ioe The IOException thrown.
|
||||
* @throws IOException If the handler doesn't wish to handle the
|
||||
* exception.
|
||||
*/
|
||||
protected void handleParserException(IOException ioe)
|
||||
protected void handleParserException( IOException ioe )
|
||||
throws IOException
|
||||
{
|
||||
if (ioe.getMessage().indexOf("CreateProcess") != -1
|
||||
|| ioe.getMessage().indexOf("Starteam: not found") != -1)
|
||||
if ( ( ioe.getMessage().indexOf( "CreateProcess" ) != -1 )
|
||||
|| ( ioe.getMessage().indexOf( "Starteam: not found" ) != -1 ) )
|
||||
{
|
||||
// can't find Starteam on Win32 or Linux...
|
||||
LOG.error(
|
||||
"Unable to find Starteam executable. Changelog will be empty("+ioe+")");
|
||||
LOG.error(
|
||||
"Unable to find Starteam executable. Changelog will be empty("
|
||||
+ ioe + ")" );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -18,24 +18,27 @@ package org.apache.maven.starteamlib;
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.maven.changelog.ChangeLog;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
import org.apache.maven.changelog.ChangeLogEntry;
|
||||
import org.apache.maven.changelog.ChangeLogFile;
|
||||
// commons imports
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.maven.changelog.ChangeLog;
|
||||
import org.apache.maven.changelog.ChangeLogEntry;
|
||||
import org.apache.maven.changelog.ChangeLogFile;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
|
||||
|
||||
/**
|
||||
* A class to parse starteam log output
|
||||
@@ -49,48 +52,59 @@ class StarteamChangeLogParser implements ChangeLogParser
|
||||
* Custom date/time formatter. Rounds ChangeLogEntry times to the nearest
|
||||
* minute.
|
||||
*/
|
||||
private static final SimpleDateFormat ENTRY_KEY_TIMESTAMP_FORMAT =
|
||||
new SimpleDateFormat("yyyyMMddHHmm");
|
||||
private static final SimpleDateFormat ENTRY_KEY_TIMESTAMP_FORMAT =
|
||||
new SimpleDateFormat( "yyyyMMddHHmm" );
|
||||
|
||||
/** Log */
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog( StarteamChangeLogGenerator.class );
|
||||
|
||||
// state machine constants for reading Starteam output
|
||||
|
||||
/** expecting file information */
|
||||
private static final int GET_FILE = 1;
|
||||
|
||||
/** expecting date */
|
||||
private static final int GET_AUTHOR = 2;
|
||||
|
||||
/** expecting comments */
|
||||
private static final int GET_COMMENT = 3;
|
||||
|
||||
/** expecting revision */
|
||||
private static final int GET_REVISION = 4;
|
||||
|
||||
/** Marks start of file data*/
|
||||
private static final String START_FILE = "History for: ";
|
||||
|
||||
/** Marks end of file */
|
||||
private static final String END_FILE =
|
||||
"==================================="
|
||||
+ "==========================================";
|
||||
|
||||
/** Marks start of revision */
|
||||
private static final String START_REVISION = "----------------------------";
|
||||
|
||||
/** Marks revision data */
|
||||
private static final String REVISION_TAG = "Branch Revision: ";
|
||||
|
||||
/** Marks author data */
|
||||
private static final String AUTHOR_TAG = "Author: ";
|
||||
|
||||
/** Marks date data */
|
||||
private static final String DATE_TAG = " Date: ";
|
||||
private SimpleDateFormat localFormat = new SimpleDateFormat();
|
||||
|
||||
|
||||
/**
|
||||
* rcs entries, in reverse (date, time, author, comment) order
|
||||
*/
|
||||
private Map entries = new TreeMap(Collections.reverseOrder());
|
||||
|
||||
/** Log */
|
||||
private static final Log LOG = LogFactory.getLog(
|
||||
StarteamChangeLogGenerator.class);
|
||||
// state machine constants for reading Starteam output
|
||||
/** expecting file information */
|
||||
private static final int GET_FILE = 1;
|
||||
/** expecting date */
|
||||
private static final int GET_AUTHOR = 2;
|
||||
/** expecting comments */
|
||||
private static final int GET_COMMENT = 3;
|
||||
/** expecting revision */
|
||||
private static final int GET_REVISION = 4;
|
||||
/** Marks start of file data*/
|
||||
private static final String START_FILE = "History for: ";
|
||||
/** Marks end of file */
|
||||
private static final String END_FILE = "==================================="
|
||||
+ "==========================================";
|
||||
/** Marks start of revision */
|
||||
private static final String START_REVISION = "----------------------------";
|
||||
/** Marks revision data */
|
||||
private static final String REVISION_TAG = "Branch Revision: ";
|
||||
/** Marks author data */
|
||||
private static final String AUTHOR_TAG = "Author: ";
|
||||
/** Marks date data */
|
||||
private static final String DATE_TAG = " Date: ";
|
||||
private Map entries = new TreeMap( Collections.reverseOrder() );
|
||||
|
||||
/** current status of the parser */
|
||||
private int status = GET_FILE;
|
||||
|
||||
|
||||
/** the current log entry being processed by the parser*/
|
||||
private ChangeLogEntry currentLogEntry = null;
|
||||
|
||||
|
||||
/** the current file being processed by the parser */
|
||||
private ChangeLogFile currentFile = null;
|
||||
|
||||
@@ -117,25 +131,27 @@ class StarteamChangeLogParser implements ChangeLogParser
|
||||
* initialize the parser from the change log
|
||||
* @param changeLog the controlling task
|
||||
* @see ChangeLogParser#init(ChangeLog)
|
||||
*/
|
||||
public void init(ChangeLog changeLog)
|
||||
*/
|
||||
public void init( ChangeLog changeLog )
|
||||
{
|
||||
this.changeLog = changeLog;
|
||||
if (changeLog.getRange() != null &&
|
||||
changeLog.getRange().length() != 0)
|
||||
|
||||
if ( ( changeLog.getRange() != null )
|
||||
&& ( changeLog.getRange().length() != 0 ) )
|
||||
{
|
||||
setDateRange(changeLog.getRange());
|
||||
setDateRange( changeLog.getRange() );
|
||||
}
|
||||
if (changeLog.getDateFormat() != null)
|
||||
|
||||
if ( changeLog.getDateFormat() != null )
|
||||
{
|
||||
localFormat = new SimpleDateFormat(changeLog.getDateFormat());
|
||||
localFormat = new SimpleDateFormat( changeLog.getDateFormat() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up any parser resources
|
||||
* @see ChangeLogParser#cleanup()
|
||||
*/
|
||||
*/
|
||||
public void cleanup()
|
||||
{
|
||||
}
|
||||
@@ -156,17 +172,18 @@ class StarteamChangeLogParser implements ChangeLogParser
|
||||
{
|
||||
localFormat = new SimpleDateFormat( dateFormat );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the input stream into a collection.
|
||||
* @param anInputStream an input stream containing Starteam log output
|
||||
* @return a collection of ChangeLogEntry's
|
||||
* @throws IOException when there are errors reading the provided stream
|
||||
*/
|
||||
public Collection parse(InputStream anInputStream) throws IOException
|
||||
public Collection parse( InputStream anInputStream )
|
||||
throws IOException
|
||||
{
|
||||
BufferedReader stream = new BufferedReader(
|
||||
new InputStreamReader(anInputStream));
|
||||
BufferedReader stream =
|
||||
new BufferedReader( new InputStreamReader( anInputStream ) );
|
||||
|
||||
// current state transitions in the state machine - starts with Get File
|
||||
// Get File -> Get Revision
|
||||
@@ -174,30 +191,39 @@ class StarteamChangeLogParser implements ChangeLogParser
|
||||
// Get Date -> Get Comment
|
||||
// Get Comment -> Get Comment or Get Revision
|
||||
String line = null;
|
||||
while ((line = stream.readLine()) != null)
|
||||
|
||||
while ( ( line = stream.readLine() ) != null )
|
||||
{
|
||||
switch (getStatus())
|
||||
switch ( getStatus() )
|
||||
{
|
||||
case GET_FILE:
|
||||
processGetFile(line);
|
||||
break;
|
||||
case GET_REVISION:
|
||||
processGetRevision(line);
|
||||
break;
|
||||
case GET_AUTHOR:
|
||||
processGetAuthor(line);
|
||||
break;
|
||||
case GET_COMMENT:
|
||||
processGetComment(line);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown state: " + status);
|
||||
case GET_FILE :
|
||||
processGetFile( line );
|
||||
|
||||
break;
|
||||
|
||||
case GET_REVISION :
|
||||
processGetRevision( line );
|
||||
|
||||
break;
|
||||
|
||||
case GET_AUTHOR :
|
||||
processGetAuthor( line );
|
||||
|
||||
break;
|
||||
|
||||
case GET_COMMENT :
|
||||
processGetComment( line );
|
||||
|
||||
break;
|
||||
|
||||
default :
|
||||
throw new IllegalStateException( "Unknown state: " + status );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return entries.values();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a change log entry to the list (if it's not already there)
|
||||
* with the given file.
|
||||
@@ -206,53 +232,56 @@ class StarteamChangeLogParser implements ChangeLogParser
|
||||
* is null, the entry wont be added
|
||||
* @param file a {@link ChangeLogFile} to be added to the entry
|
||||
*/
|
||||
private void addEntry(ChangeLogEntry entry, ChangeLogFile file)
|
||||
private void addEntry( ChangeLogEntry entry, ChangeLogFile file )
|
||||
{
|
||||
// do not add if entry is not populated
|
||||
if (entry.getAuthor() == null)
|
||||
if ( entry.getAuthor() == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// do not add if entry is out of date range
|
||||
if (!testMode)
|
||||
if ( !testMode )
|
||||
{
|
||||
if (beforeDate != null && toDate != null)
|
||||
if ( ( beforeDate != null ) && ( toDate != null ) )
|
||||
{
|
||||
if (entry.getDate().before(beforeDate) || entry.getDate().after(toDate))
|
||||
if ( entry.getDate().before( beforeDate )
|
||||
|| entry.getDate().after( toDate ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String key = ENTRY_KEY_TIMESTAMP_FORMAT.format(entry.getDate())
|
||||
|
||||
String key =
|
||||
ENTRY_KEY_TIMESTAMP_FORMAT.format( entry.getDate() )
|
||||
+ entry.getAuthor() + entry.getComment();
|
||||
|
||||
if (!entries.containsKey(key))
|
||||
|
||||
if ( !entries.containsKey( key ) )
|
||||
{
|
||||
entry.addFile(file);
|
||||
entries.put(key, entry);
|
||||
entry.addFile( file );
|
||||
entries.put( key, entry );
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeLogEntry existingEntry = (ChangeLogEntry) entries.get(key);
|
||||
existingEntry.addFile(file);
|
||||
ChangeLogEntry existingEntry = (ChangeLogEntry) entries.get( key );
|
||||
|
||||
existingEntry.addFile( file );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the current input line in the Get File state.
|
||||
* @param line a line of text from the Starteam log output
|
||||
*/
|
||||
private void processGetFile(String line)
|
||||
private void processGetFile( String line )
|
||||
{
|
||||
if (line.startsWith(START_FILE))
|
||||
if ( line.startsWith( START_FILE ) )
|
||||
{
|
||||
setCurrentLogEntry(new ChangeLogEntry());
|
||||
setCurrentFile(new ChangeLogFile(line.substring(START_FILE.length(),
|
||||
line.length())));
|
||||
setStatus(GET_REVISION);
|
||||
setCurrentLogEntry( new ChangeLogEntry() );
|
||||
setCurrentFile( new ChangeLogFile( line.substring(
|
||||
START_FILE.length(), line.length() ) ) );
|
||||
setStatus( GET_REVISION );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,21 +289,23 @@ class StarteamChangeLogParser implements ChangeLogParser
|
||||
* Process the current input line in the Get Revision state.
|
||||
* @param line a line of text from the Starteam log output
|
||||
*/
|
||||
private void processGetRevision(String line)
|
||||
private void processGetRevision( String line )
|
||||
{
|
||||
int pos;
|
||||
if ((pos=line.indexOf(REVISION_TAG)) != -1)
|
||||
|
||||
if ( ( pos = line.indexOf( REVISION_TAG ) ) != -1 )
|
||||
{
|
||||
getCurrentFile().setRevision(line.substring(pos + REVISION_TAG.length()));
|
||||
setStatus(GET_AUTHOR);
|
||||
getCurrentFile().setRevision( line.substring( pos
|
||||
+ REVISION_TAG.length() ) );
|
||||
setStatus( GET_AUTHOR );
|
||||
}
|
||||
else if (line.startsWith(END_FILE))
|
||||
else if ( line.startsWith( END_FILE ) )
|
||||
{
|
||||
// If we encounter an end of file line, it means there
|
||||
// are no more revisions for the current file.
|
||||
// there could also be a file still being processed.
|
||||
setStatus(GET_FILE);
|
||||
addEntry(getCurrentLogEntry(), getCurrentFile());
|
||||
setStatus( GET_FILE );
|
||||
addEntry( getCurrentLogEntry(), getCurrentFile() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,16 +313,19 @@ class StarteamChangeLogParser implements ChangeLogParser
|
||||
* Process the current input line in the Get Author/Date state.
|
||||
* @param line a line of text from the Starteam log output
|
||||
*/
|
||||
private void processGetAuthor(String line)
|
||||
private void processGetAuthor( String line )
|
||||
{
|
||||
if (line.startsWith(AUTHOR_TAG))
|
||||
if ( line.startsWith( AUTHOR_TAG ) )
|
||||
{
|
||||
int posDateTag = line.indexOf(DATE_TAG);
|
||||
String author = line.substring(AUTHOR_TAG.length(), posDateTag);
|
||||
getCurrentLogEntry().setAuthor(author);
|
||||
String date = line.substring(posDateTag + DATE_TAG.length());
|
||||
getCurrentLogEntry().setDate(parseDate(date));
|
||||
setStatus(GET_COMMENT);
|
||||
int posDateTag = line.indexOf( DATE_TAG );
|
||||
String author = line.substring( AUTHOR_TAG.length(), posDateTag );
|
||||
|
||||
getCurrentLogEntry().setAuthor( author );
|
||||
|
||||
String date = line.substring( posDateTag + DATE_TAG.length() );
|
||||
|
||||
getCurrentLogEntry().setDate( parseDate( date ) );
|
||||
setStatus( GET_COMMENT );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,28 +333,31 @@ class StarteamChangeLogParser implements ChangeLogParser
|
||||
* Process the current input line in the Get Comment state.
|
||||
* @param line a line of text from the Starteam log output
|
||||
*/
|
||||
private void processGetComment(String line)
|
||||
private void processGetComment( String line )
|
||||
{
|
||||
if (line.startsWith(START_REVISION))
|
||||
if ( line.startsWith( START_REVISION ) )
|
||||
{
|
||||
// add entry, and set state to get revision
|
||||
addEntry(getCurrentLogEntry(), getCurrentFile());
|
||||
addEntry( getCurrentLogEntry(), getCurrentFile() );
|
||||
|
||||
// new change log entry
|
||||
setCurrentLogEntry(new ChangeLogEntry());
|
||||
setCurrentLogEntry( new ChangeLogEntry() );
|
||||
|
||||
// same file name, but different rev
|
||||
setCurrentFile(new ChangeLogFile(getCurrentFile().getName()));
|
||||
setStatus(GET_REVISION);
|
||||
setCurrentFile( new ChangeLogFile( getCurrentFile().getName() ) );
|
||||
setStatus( GET_REVISION );
|
||||
}
|
||||
else if (line.startsWith(END_FILE))
|
||||
else if ( line.startsWith( END_FILE ) )
|
||||
{
|
||||
addEntry(getCurrentLogEntry(), getCurrentFile());
|
||||
setStatus(GET_FILE);
|
||||
addEntry( getCurrentLogEntry(), getCurrentFile() );
|
||||
setStatus( GET_FILE );
|
||||
}
|
||||
else
|
||||
{
|
||||
// keep gathering comments
|
||||
getCurrentLogEntry().setComment(
|
||||
getCurrentLogEntry().getComment() + line + "\n");
|
||||
getCurrentLogEntry().setComment( getCurrentLogEntry()
|
||||
.getComment() + line
|
||||
+ "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,16 +369,16 @@ class StarteamChangeLogParser implements ChangeLogParser
|
||||
{
|
||||
return currentFile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for property currentFile.
|
||||
* @param currentFile New value of property currentFile.
|
||||
*/
|
||||
private void setCurrentFile(ChangeLogFile currentFile)
|
||||
private void setCurrentFile( ChangeLogFile currentFile )
|
||||
{
|
||||
this.currentFile = currentFile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for property currentLogEntry.
|
||||
* @return Value of property currentLogEntry.
|
||||
@@ -350,16 +387,16 @@ class StarteamChangeLogParser implements ChangeLogParser
|
||||
{
|
||||
return currentLogEntry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for property currentLogEntry.
|
||||
* @param currentLogEntry New value of property currentLogEntry.
|
||||
*/
|
||||
private void setCurrentLogEntry(ChangeLogEntry currentLogEntry)
|
||||
private void setCurrentLogEntry( ChangeLogEntry currentLogEntry )
|
||||
{
|
||||
this.currentLogEntry = currentLogEntry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for property status.
|
||||
* @return Value of property status.
|
||||
@@ -368,32 +405,33 @@ class StarteamChangeLogParser implements ChangeLogParser
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for property status.
|
||||
* @param status New value of property status.
|
||||
*/
|
||||
private void setStatus(int status)
|
||||
private void setStatus( int status )
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Converts the date timestamp from the svn output into a date
|
||||
* object.
|
||||
*
|
||||
*
|
||||
* @return A date representing the timestamp of the log entry.
|
||||
*/
|
||||
private Date parseDate(String date)
|
||||
private Date parseDate( String date )
|
||||
{
|
||||
try
|
||||
{
|
||||
return localFormat.parse(date.toString());
|
||||
return localFormat.parse( date.toString() );
|
||||
}
|
||||
catch (ParseException e)
|
||||
catch ( ParseException e )
|
||||
{
|
||||
LOG.error("ParseException Caught", e);
|
||||
return null;
|
||||
LOG.error( "ParseException Caught", e );
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,13 +442,15 @@ class StarteamChangeLogParser implements ChangeLogParser
|
||||
* @param numDaysString The number of days of log output to
|
||||
* generate.
|
||||
*/
|
||||
private void setDateRange(String numDaysString)
|
||||
private void setDateRange( String numDaysString )
|
||||
{
|
||||
int days = Integer.parseInt(numDaysString);
|
||||
int days = Integer.parseInt( numDaysString );
|
||||
|
||||
beforeDate = new Date(
|
||||
System.currentTimeMillis() - (long) days * 24 * 60 * 60 * 1000);
|
||||
toDate = new Date(
|
||||
System.currentTimeMillis() + (long) 1 * 24 * 60 * 60 * 1000);
|
||||
beforeDate =
|
||||
new Date( System.currentTimeMillis()
|
||||
- ( (long) days * 24 * 60 * 60 * 1000 ) );
|
||||
toDate =
|
||||
new Date( System.currentTimeMillis()
|
||||
+ ( (long) 1 * 24 * 60 * 60 * 1000 ) );
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import org.apache.maven.changelog.ChangeLogFactory;
|
||||
import org.apache.maven.changelog.ChangeLogGenerator;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
|
||||
|
||||
/**
|
||||
* Provides Subversion specific instances of the ChangeLogGenerator and
|
||||
* ChangeLogParser interfaces.
|
||||
@@ -36,7 +37,7 @@ public class SvnChangeLogFactory implements ChangeLogFactory
|
||||
public SvnChangeLogFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a Subversion specific ChangeLogGenerator.
|
||||
*
|
||||
|
||||
@@ -18,16 +18,22 @@ package org.apache.maven.svnlib;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
// commons imports
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
// maven imports
|
||||
import org.apache.maven.changelog.AbstractChangeLogGenerator;
|
||||
|
||||
// ant imports
|
||||
import org.apache.tools.ant.types.Commandline;
|
||||
|
||||
|
||||
/**
|
||||
* A Subversion implementation of the {@link org.apache.maven.changelog.ChangeLog}
|
||||
* interface.
|
||||
@@ -40,83 +46,88 @@ import org.apache.tools.ant.types.Commandline;
|
||||
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
|
||||
* @author <a href="mailto:pete-apache-dev@kazmier.com">Pete Kazmier</a>
|
||||
* @author Daniel Rall
|
||||
* @version
|
||||
* @version
|
||||
* $Id$
|
||||
*/
|
||||
class SvnChangeLogGenerator extends AbstractChangeLogGenerator
|
||||
{
|
||||
/** Log */
|
||||
private static final Log LOG = LogFactory.getLog(
|
||||
SvnChangeLogGenerator.class);
|
||||
/** Log */
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog( SvnChangeLogGenerator.class );
|
||||
|
||||
/**
|
||||
* Constructs the appropriate command line to execute the subversion
|
||||
* log command whose output is then later parsed.
|
||||
*
|
||||
* @return the cvs command line to be executed.
|
||||
*/
|
||||
protected Commandline getScmLogCommand()
|
||||
protected Commandline getScmLogCommand()
|
||||
{
|
||||
Commandline command = new Commandline();
|
||||
|
||||
command.setExecutable("svn");
|
||||
command.createArgument().setValue("log");
|
||||
command.createArgument().setValue("-v");
|
||||
command.setExecutable( "svn" );
|
||||
command.createArgument().setValue( "log" );
|
||||
command.createArgument().setValue( "-v" );
|
||||
|
||||
if (dateRange != null)
|
||||
if ( dateRange != null )
|
||||
{
|
||||
command.createArgument().setValue(dateRange);
|
||||
command.createArgument().setValue( dateRange );
|
||||
}
|
||||
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Construct the svn command-line argument that is used to specify
|
||||
* the appropriate date range. This date option takes the format
|
||||
* of <code>-r{start}:{end}</code> in the case of Subversion.
|
||||
*
|
||||
*
|
||||
* @param before The starting point.
|
||||
* @param to The ending point.
|
||||
* @return A string that can be used to specify a date to a scm
|
||||
* system.
|
||||
*/
|
||||
protected String getScmDateArgument(Date before, Date to)
|
||||
protected String getScmDateArgument( Date before, Date to )
|
||||
{
|
||||
SimpleDateFormat outputDate = new SimpleDateFormat("yyyy-MM-dd");
|
||||
SimpleDateFormat outputDate = new SimpleDateFormat( "yyyy-MM-dd" );
|
||||
|
||||
// Tell SVN to sort log entries from newest to oldest.
|
||||
String cmd = "-r{" + outputDate.format(to) + "}:{" +
|
||||
outputDate.format(before) + "}";
|
||||
String cmd =
|
||||
"-r{" + outputDate.format( to ) + "}:{"
|
||||
+ outputDate.format( before ) + "}";
|
||||
|
||||
if ( System.getProperty( "os.name" ).startsWith( "Windows" ) )
|
||||
{
|
||||
cmd = "\"" + cmd + "\"";
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AbstractChangeLogGenerator#getScmTagArgument(String, String)
|
||||
*/
|
||||
protected String getScmTagArgument(String tagStart, String tagEnd)
|
||||
protected String getScmTagArgument( String tagStart, String tagEnd )
|
||||
{
|
||||
throw new UnsupportedOperationException("This plugin currently does not support generating logs from tags with Subversion.");
|
||||
throw new UnsupportedOperationException(
|
||||
"This plugin currently does not support generating logs from tags with Subversion." );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle ChangeLogParser IOExceptions.
|
||||
*
|
||||
/**
|
||||
* Handle ChangeLogParser IOExceptions.
|
||||
*
|
||||
* @param ioe The IOException thrown.
|
||||
* @throws IOException If the handler doesn't wish to handle the
|
||||
* exception.
|
||||
*/
|
||||
protected void handleParserException(IOException ioe)
|
||||
protected void handleParserException( IOException ioe )
|
||||
throws IOException
|
||||
{
|
||||
if (ioe.getMessage().indexOf("CreateProcess") != -1
|
||||
|| ioe.getMessage().indexOf("svn: not found") != -1)
|
||||
if ( ( ioe.getMessage().indexOf( "CreateProcess" ) != -1 )
|
||||
|| ( ioe.getMessage().indexOf( "svn: not found" ) != -1 ) )
|
||||
{
|
||||
// can't find svn on Win32 or Linux...
|
||||
LOG.error(
|
||||
"Unable to find svn executable. Changelog will be empty");
|
||||
LOG.error( "Unable to find svn executable. Changelog will be empty" );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -18,26 +18,32 @@ package org.apache.maven.svnlib;
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.ArrayList;
|
||||
|
||||
// commons imports
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
// maven
|
||||
import org.apache.maven.changelog.ChangeLog;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
import org.apache.maven.changelog.ChangeLogEntry;
|
||||
import org.apache.maven.changelog.ChangeLogFile;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
|
||||
// regexp
|
||||
import org.apache.regexp.RE;
|
||||
import org.apache.regexp.RESyntaxException;
|
||||
|
||||
|
||||
/**
|
||||
* A class to parse the log output from Subversion.
|
||||
*
|
||||
@@ -50,12 +56,12 @@ class SvnChangeLogParser implements ChangeLogParser
|
||||
{
|
||||
/** Date formatter for svn timestamp (after a little massaging) */
|
||||
private static final SimpleDateFormat SVN_TIMESTAMP =
|
||||
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzzzzzzzz");
|
||||
new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss zzzzzzzzz" );
|
||||
|
||||
/** Log */
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog( SvnChangeLogParser.class );
|
||||
|
||||
/** Log */
|
||||
private static final Log LOG = LogFactory.getLog(
|
||||
SvnChangeLogParser.class);
|
||||
|
||||
/** State machine constant: expecting header */
|
||||
private static final int GET_HEADER = 1;
|
||||
|
||||
@@ -75,21 +81,21 @@ class SvnChangeLogParser implements ChangeLogParser
|
||||
private static final int FILE_START_INDEX = 5;
|
||||
|
||||
/** The comment section ends with a dashed line */
|
||||
private static final String COMMENT_END_TOKEN =
|
||||
"------------------------------------" +
|
||||
"------------------------------------";
|
||||
private static final String COMMENT_END_TOKEN =
|
||||
"------------------------------------"
|
||||
+ "------------------------------------";
|
||||
|
||||
/** The pattern used to match svn header lines */
|
||||
private static final String pattern =
|
||||
"^r(\\d+)\\s+\\|\\s+" + // revision number
|
||||
"([^|]+)\\|\\s+" + // author username
|
||||
"(\\d+-\\d+-\\d+ " + // date 2002-08-24
|
||||
"\\d+:\\d+:\\d+) " + // time 16:01:00
|
||||
"([\\-+])(\\d\\d)(\\d\\d)"; // gmt offset -0400
|
||||
"^r(\\d+)\\s+\\|\\s+" // revision number
|
||||
+ "([^|]+)\\|\\s+" // author username
|
||||
+ "(\\d+-\\d+-\\d+ " // date 2002-08-24
|
||||
+ "\\d+:\\d+:\\d+) " // time 16:01:00
|
||||
+ "([\\-+])(\\d\\d)(\\d\\d)"; // gmt offset -0400
|
||||
|
||||
/** Current status of the parser */
|
||||
private int status = GET_HEADER;
|
||||
|
||||
|
||||
/** List of change log entries */
|
||||
private Collection entries = new ArrayList();
|
||||
|
||||
@@ -108,18 +114,18 @@ class SvnChangeLogParser implements ChangeLogParser
|
||||
/** The invoking changelog controller (useful to log messages) */
|
||||
private ChangeLog changeLog;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public SvnChangeLogParser()
|
||||
{
|
||||
try
|
||||
{
|
||||
headerRegexp = new RE(pattern);
|
||||
headerRegexp = new RE( pattern );
|
||||
}
|
||||
catch (RESyntaxException ignored)
|
||||
catch ( RESyntaxException ignored )
|
||||
{
|
||||
LOG.error("Could not create regexp to parse svn log file", ignored);
|
||||
LOG.error( "Could not create regexp to parse svn log file", ignored );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,8 +134,8 @@ class SvnChangeLogParser implements ChangeLogParser
|
||||
*
|
||||
* @param changeLog The controlling task
|
||||
* @see ChangeLogParser#init(ChangeLog)
|
||||
*/
|
||||
public void init(ChangeLog changeLog)
|
||||
*/
|
||||
public void init( ChangeLog changeLog )
|
||||
{
|
||||
this.changeLog = changeLog;
|
||||
}
|
||||
@@ -138,11 +144,11 @@ class SvnChangeLogParser implements ChangeLogParser
|
||||
* Clean up any parser resources.
|
||||
*
|
||||
* @see ChangeLogParser#cleanup()
|
||||
*/
|
||||
*/
|
||||
public void cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the input stream into a collection.
|
||||
*
|
||||
@@ -150,57 +156,67 @@ class SvnChangeLogParser implements ChangeLogParser
|
||||
* @return A collection of ChangeLogEntry's
|
||||
* @throws IOException When there are errors reading the provided stream
|
||||
*/
|
||||
public Collection parse(InputStream anInputStream) throws IOException
|
||||
public Collection parse( InputStream anInputStream )
|
||||
throws IOException
|
||||
{
|
||||
BufferedReader stream = new BufferedReader(
|
||||
new InputStreamReader(anInputStream));
|
||||
BufferedReader stream =
|
||||
new BufferedReader( new InputStreamReader( anInputStream ) );
|
||||
|
||||
// Current state transitions in the parser's state machine:
|
||||
// Get Header -> Get File
|
||||
// Get File -> Get Comment or Get (another) File
|
||||
// Get Comment -> Get (another) Comment
|
||||
String line = null;
|
||||
while ((line = stream.readLine()) != null)
|
||||
|
||||
while ( ( line = stream.readLine() ) != null )
|
||||
{
|
||||
switch (status)
|
||||
switch ( status )
|
||||
{
|
||||
case GET_HEADER:
|
||||
processGetHeader(line);
|
||||
break;
|
||||
case GET_FILE:
|
||||
processGetFile(line);
|
||||
break;
|
||||
case GET_COMMENT:
|
||||
processGetComment(line);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown state: " + status);
|
||||
case GET_HEADER :
|
||||
processGetHeader( line );
|
||||
|
||||
break;
|
||||
|
||||
case GET_FILE :
|
||||
processGetFile( line );
|
||||
|
||||
break;
|
||||
|
||||
case GET_COMMENT :
|
||||
processGetComment( line );
|
||||
|
||||
break;
|
||||
|
||||
default :
|
||||
throw new IllegalStateException( "Unknown state: " + status );
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the current input line in the GET_HEADER state. The
|
||||
* author, date, and the revision of the entry are gathered. Note,
|
||||
* Subversion does not have per-file revisions, instead, the entire
|
||||
* repository is given a single revision number, which is used for
|
||||
* the revision number of each file.
|
||||
* the revision number of each file.
|
||||
*
|
||||
* @param line A line of text from the svn log output
|
||||
*/
|
||||
private void processGetHeader(String line)
|
||||
private void processGetHeader( String line )
|
||||
{
|
||||
if (!headerRegexp.match(line))
|
||||
if ( !headerRegexp.match( line ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
currentRevision = headerRegexp.getParen(1);
|
||||
currentRevision = headerRegexp.getParen( 1 );
|
||||
currentLogEntry = new ChangeLogEntry();
|
||||
|
||||
/* set author to be trimmed author field */
|
||||
currentLogEntry.setAuthor(headerRegexp.getParen(2).trim());
|
||||
currentLogEntry.setDate(parseDate());
|
||||
currentLogEntry.setAuthor( headerRegexp.getParen( 2 ).trim() );
|
||||
currentLogEntry.setDate( parseDate() );
|
||||
|
||||
status = GET_FILE;
|
||||
}
|
||||
@@ -213,17 +229,18 @@ class SvnChangeLogParser implements ChangeLogParser
|
||||
*
|
||||
* @param line A line of text from the svn log output
|
||||
*/
|
||||
private void processGetFile(String line)
|
||||
private void processGetFile( String line )
|
||||
{
|
||||
if (line.startsWith(FILE_BEGIN_TOKEN))
|
||||
if ( line.startsWith( FILE_BEGIN_TOKEN ) )
|
||||
{
|
||||
// Skip the status flags and just get the name of the file
|
||||
String name = line.substring(FILE_START_INDEX);
|
||||
currentLogEntry.addFile(new ChangeLogFile(name, currentRevision));
|
||||
String name = line.substring( FILE_START_INDEX );
|
||||
|
||||
currentLogEntry.addFile( new ChangeLogFile( name, currentRevision ) );
|
||||
|
||||
status = GET_FILE;
|
||||
}
|
||||
else if (line.equals(FILE_END_TOKEN))
|
||||
else if ( line.equals( FILE_END_TOKEN ) )
|
||||
{
|
||||
// Create a buffer for the collection of the comment now
|
||||
// that we are leaving the GET_FILE state.
|
||||
@@ -239,45 +256,46 @@ class SvnChangeLogParser implements ChangeLogParser
|
||||
*
|
||||
* @param line a line of text from the svn log output
|
||||
*/
|
||||
private void processGetComment(String line)
|
||||
private void processGetComment( String line )
|
||||
{
|
||||
if (line.equals(COMMENT_END_TOKEN))
|
||||
if ( line.equals( COMMENT_END_TOKEN ) )
|
||||
{
|
||||
currentLogEntry.setComment(currentComment.toString());
|
||||
entries.add(currentLogEntry);
|
||||
currentLogEntry.setComment( currentComment.toString() );
|
||||
entries.add( currentLogEntry );
|
||||
|
||||
status = GET_HEADER;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentComment.append(line).append('\n');
|
||||
currentComment.append( line ).append( '\n' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Converts the date timestamp from the svn output into a date
|
||||
* object.
|
||||
*
|
||||
*
|
||||
* @return A date representing the timestamp of the log entry.
|
||||
*/
|
||||
private Date parseDate()
|
||||
{
|
||||
try
|
||||
{
|
||||
StringBuffer date = new StringBuffer()
|
||||
.append(headerRegexp.getParen(3))
|
||||
.append(" GMT")
|
||||
.append(headerRegexp.getParen(4))
|
||||
.append(headerRegexp.getParen(5))
|
||||
.append(':')
|
||||
.append(headerRegexp.getParen(6));
|
||||
StringBuffer date =
|
||||
new StringBuffer().append( headerRegexp.getParen( 3 ) )
|
||||
.append( " GMT" )
|
||||
.append( headerRegexp.getParen( 4 ) )
|
||||
.append( headerRegexp.getParen( 5 ) )
|
||||
.append( ':' ).append( headerRegexp
|
||||
.getParen( 6 ) );
|
||||
|
||||
return SVN_TIMESTAMP.parse(date.toString());
|
||||
return SVN_TIMESTAMP.parse( date.toString() );
|
||||
}
|
||||
catch (ParseException e)
|
||||
catch ( ParseException e )
|
||||
{
|
||||
LOG.error("ParseException Caught", e);
|
||||
return null;
|
||||
LOG.error( "ParseException Caught", e );
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,10 @@ package org.apache.maven.util;
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* A class to asynchronously read the provided InputStream and
|
||||
@@ -33,7 +34,7 @@ public class AsyncStreamReader extends Thread
|
||||
{
|
||||
/** buffer to dump output to */
|
||||
private StringBuffer streamBuffer = new StringBuffer();
|
||||
|
||||
|
||||
/** stream to read from */
|
||||
private BufferedReader stream;
|
||||
|
||||
@@ -41,34 +42,36 @@ public class AsyncStreamReader extends Thread
|
||||
* Create a reader to process the provided stream
|
||||
* @param anInputStream any input stream
|
||||
*/
|
||||
public AsyncStreamReader(InputStream anInputStream)
|
||||
public AsyncStreamReader( InputStream anInputStream )
|
||||
{
|
||||
if (anInputStream == null)
|
||||
if ( anInputStream == null )
|
||||
{
|
||||
throw new NullPointerException("input stream parameter is null");
|
||||
throw new NullPointerException( "input stream parameter is null" );
|
||||
}
|
||||
stream = new BufferedReader(new InputStreamReader(anInputStream));
|
||||
|
||||
stream = new BufferedReader( new InputStreamReader( anInputStream ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Read lines from the input stream provided, appending to a buffer
|
||||
* for retrieval via the toString() method
|
||||
* for retrieval via the toString() method
|
||||
*/
|
||||
public void run()
|
||||
{
|
||||
String line;
|
||||
|
||||
try
|
||||
{
|
||||
while ((line = stream.readLine()) != null)
|
||||
while ( ( line = stream.readLine() ) != null )
|
||||
{
|
||||
if (okToConsume(line))
|
||||
if ( okToConsume( line ) )
|
||||
{
|
||||
streamBuffer.append(line);
|
||||
streamBuffer.append('\n');
|
||||
streamBuffer.append( line );
|
||||
streamBuffer.append( '\n' );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException ioe)
|
||||
catch ( IOException ioe )
|
||||
{
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
@@ -89,9 +92,9 @@ public class AsyncStreamReader extends Thread
|
||||
* @param line the line to check.
|
||||
* @return if its ok to add this line to the buffer.
|
||||
*/
|
||||
protected boolean okToConsume(String line)
|
||||
protected boolean okToConsume( String line )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
} // end of AsyncStreamReader
|
||||
}
|
||||
// end of AsyncStreamReader
|
||||
@@ -20,6 +20,7 @@ package org.apache.maven.util;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: This is very CVS specific, but I would like to try additional SCM
|
||||
* package like subversion ASAP.
|
||||
@@ -31,48 +32,54 @@ import java.util.List;
|
||||
public final class RepositoryUtils
|
||||
{
|
||||
/**
|
||||
* Splits an SCM string into parts
|
||||
* Splits an SCM string into parts
|
||||
* @param connection
|
||||
* @return String[]
|
||||
*/
|
||||
public static String[] splitSCMConnection(String connection)
|
||||
public static String[] splitSCMConnection( String connection )
|
||||
{
|
||||
if (connection == null)
|
||||
if ( connection == null )
|
||||
{
|
||||
throw new NullPointerException("repository connection is null");
|
||||
throw new NullPointerException( "repository connection is null" );
|
||||
}
|
||||
|
||||
if (connection.length() < 4)
|
||||
if ( connection.length() < 4 )
|
||||
{
|
||||
throw new IllegalArgumentException("repository connection is too short");
|
||||
throw new IllegalArgumentException(
|
||||
"repository connection is too short" );
|
||||
}
|
||||
|
||||
if (!connection.startsWith("scm"))
|
||||
if ( !connection.startsWith( "scm" ) )
|
||||
{
|
||||
throw new IllegalArgumentException("repository connection must start with scm[delim]");
|
||||
throw new IllegalArgumentException(
|
||||
"repository connection must start with scm[delim]" );
|
||||
}
|
||||
|
||||
String delimiter = "" + connection.charAt(3);
|
||||
|
||||
EnhancedStringTokenizer tok = new EnhancedStringTokenizer(connection, delimiter);
|
||||
String delimiter = "" + connection.charAt( 3 );
|
||||
|
||||
String[] tokens = tokenizerToArray(tok);
|
||||
EnhancedStringTokenizer tok =
|
||||
new EnhancedStringTokenizer( connection, delimiter );
|
||||
|
||||
String[] tokens = tokenizerToArray( tok );
|
||||
|
||||
// for a valid repository, it should be scm:<provider> at least
|
||||
if (tokens.length >= 1 && tokens[1].equals("cvs"))
|
||||
if ( ( tokens.length >= 1 ) && tokens[1].equals( "cvs" ) )
|
||||
{
|
||||
if (tokens.length >= 2 && tokens[2].equals("local"))
|
||||
if ( ( tokens.length >= 2 ) && tokens[2].equals( "local" ) )
|
||||
{
|
||||
if (tokens.length == 6)
|
||||
if ( tokens.length == 6 )
|
||||
{
|
||||
if (tokens[3].length() > 0 && !tokens[3].equals("local"))
|
||||
if ( ( tokens[3].length() > 0 )
|
||||
&& !tokens[3].equals( "local" ) )
|
||||
{
|
||||
throw new IllegalArgumentException("cvs local repository connection string must specify 5 tokens, or an empty 3rd token if 6");
|
||||
throw new IllegalArgumentException(
|
||||
"cvs local repository connection string must specify 5 tokens, or an empty 3rd token if 6" );
|
||||
}
|
||||
}
|
||||
else if (tokens.length == 5)
|
||||
else if ( tokens.length == 5 )
|
||||
{
|
||||
String[] newTokens = new String[6];
|
||||
|
||||
newTokens[0] = tokens[0];
|
||||
newTokens[1] = tokens[1];
|
||||
newTokens[2] = tokens[2];
|
||||
@@ -83,14 +90,18 @@ public final class RepositoryUtils
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("cvs local repository connection string doesn't contain five tokens");
|
||||
throw new IllegalArgumentException(
|
||||
"cvs local repository connection string doesn't contain five tokens" );
|
||||
}
|
||||
}
|
||||
if (tokens.length != 6)
|
||||
|
||||
if ( tokens.length != 6 )
|
||||
{
|
||||
throw new IllegalArgumentException("cvs repository connection string doesn't contain six tokens");
|
||||
throw new IllegalArgumentException(
|
||||
"cvs repository connection string doesn't contain six tokens" );
|
||||
}
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
@@ -100,14 +111,15 @@ public final class RepositoryUtils
|
||||
* @param tok
|
||||
* @return String[]
|
||||
*/
|
||||
public static String[] tokenizerToArray(EnhancedStringTokenizer tok)
|
||||
public static String[] tokenizerToArray( EnhancedStringTokenizer tok )
|
||||
{
|
||||
List l = new ArrayList();
|
||||
while (tok.hasMoreTokens())
|
||||
{
|
||||
l.add(tok.nextToken());
|
||||
}
|
||||
return (String[]) l.toArray(new String[l.size()]);
|
||||
}
|
||||
|
||||
while ( tok.hasMoreTokens() )
|
||||
{
|
||||
l.add( tok.nextToken() );
|
||||
}
|
||||
|
||||
return (String[]) l.toArray( new String[l.size()] );
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,13 @@ package org.apache.maven.vsslib;
|
||||
/*
|
||||
* ====================================================================
|
||||
* Copyright 2001-2004 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
|
||||
@@ -21,36 +21,40 @@ package org.apache.maven.vsslib;
|
||||
import org.apache.maven.changelog.ChangeLogGenerator;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
|
||||
|
||||
/**
|
||||
* Provides VSS specific instances of the ChangeLogGenerator and ChangeLogParser
|
||||
* interfaces.
|
||||
*
|
||||
*
|
||||
* @author Freddy Mallet
|
||||
*/
|
||||
public class VssChangeLogFactory implements
|
||||
org.apache.maven.changelog.ChangeLogFactory {
|
||||
|
||||
public class VssChangeLogFactory
|
||||
implements org.apache.maven.changelog.ChangeLogFactory
|
||||
{
|
||||
/**
|
||||
* Default no-arg constructor.
|
||||
*/
|
||||
public VssChangeLogFactory() {
|
||||
public VssChangeLogFactory()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a VSS specific ChangeLogGenerator.
|
||||
*
|
||||
*
|
||||
* @return a VSS specific ChangeLogGenerator.
|
||||
*/
|
||||
public ChangeLogGenerator createGenerator() {
|
||||
public ChangeLogGenerator createGenerator()
|
||||
{
|
||||
return new VssChangeLogGenerator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a VSS specific ChangeLogParser.
|
||||
*
|
||||
*
|
||||
* @return a VSS specific ChangeLogParser.
|
||||
*/
|
||||
public ChangeLogParser createParser() {
|
||||
public ChangeLogParser createParser()
|
||||
{
|
||||
return new VssChangeLogParser();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,13 @@ package org.apache.maven.vsslib;
|
||||
/*
|
||||
* ====================================================================
|
||||
* Copyright 2001-2004 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
|
||||
@@ -20,7 +20,9 @@ package org.apache.maven.vsslib;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
@@ -28,110 +30,126 @@ import java.util.Locale;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.maven.changelog.AbstractChangeLogGenerator;
|
||||
import org.apache.maven.changelog.ChangeLogEntry;
|
||||
import org.apache.maven.changelog.ChangeLogGenerator;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
import org.apache.tools.ant.taskdefs.Execute;
|
||||
import org.apache.tools.ant.types.Commandline;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* A Visual Source Safe implementation of the
|
||||
* {@link org.apache.maven.changelog.ChangeLogGenerator}interface realized
|
||||
* extending the {@link org.apache.maven.changelog.AbstractChangeLogGenerator}.
|
||||
*
|
||||
*
|
||||
* The command line build by this class uses the <code>ss History</code> VSS
|
||||
* command and formats the output in a way the VssChangeLogParser can
|
||||
* understand. Due to this fact this implementations works only if used within a
|
||||
* vss view.
|
||||
*
|
||||
*
|
||||
* The command looks like this:
|
||||
* <p>
|
||||
* set ssdir=vssRepositoryPath ss History vssProject -YvssUserId,vssUserPassword
|
||||
* -R -Vd01/12/04~23/11/04 -I-Y
|
||||
*
|
||||
*
|
||||
* @author Freddy Mallet
|
||||
*/
|
||||
public class VssChangeLogGenerator extends AbstractChangeLogGenerator {
|
||||
|
||||
public class VssChangeLogGenerator extends AbstractChangeLogGenerator
|
||||
{
|
||||
/**
|
||||
* Log
|
||||
*/
|
||||
private static final Log LOG = LogFactory
|
||||
.getLog(VssChangeLogGenerator.class);
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog( VssChangeLogGenerator.class );
|
||||
|
||||
/***************************************************************************
|
||||
* Constructs the appropriate command line to execute the scm's log command.
|
||||
* For Clearcase it's lshistory.
|
||||
*
|
||||
*
|
||||
* @see org.apache.maven.changelog.AbstractChangeLogGenerator#getScmLogCommand()
|
||||
* @return The command line to be executed.
|
||||
*/
|
||||
protected Commandline getScmLogCommand() {
|
||||
VssConnection vssConnection = new VssConnection(getConnection());
|
||||
protected Commandline getScmLogCommand()
|
||||
{
|
||||
VssConnection vssConnection = new VssConnection( getConnection() );
|
||||
Commandline command = new Commandline();
|
||||
command.setExecutable("ss");
|
||||
command.createArgument().setValue("History");
|
||||
command.createArgument().setValue("$" + vssConnection.getVssProject());
|
||||
|
||||
command.setExecutable( "ss" );
|
||||
command.createArgument().setValue( "History" );
|
||||
command.createArgument().setValue( "$"
|
||||
+ vssConnection.getVssProject() );
|
||||
|
||||
//User identification to get access to vss repository
|
||||
if(vssConnection.getVssUserInf() != null){
|
||||
command.createArgument().setValue("-Y" + vssConnection.getVssUserInf());
|
||||
if ( vssConnection.getVssUserInf() != null )
|
||||
{
|
||||
command.createArgument().setValue( "-Y"
|
||||
+ vssConnection.getVssUserInf() );
|
||||
}
|
||||
|
||||
//Display the history of an entire project list
|
||||
command.createArgument().setValue("-R");
|
||||
command.createArgument().setValue( "-R" );
|
||||
|
||||
//Ignore: Do not ask for input under any circumstances.
|
||||
command.createArgument().setValue("-I-");
|
||||
command.createArgument().setValue( "-I-" );
|
||||
|
||||
//Display only versions that fall within specified data range.
|
||||
if (dateRange != null) {
|
||||
command.createArgument().setValue("-Vd" + dateRange);
|
||||
if ( dateRange != null )
|
||||
{
|
||||
command.createArgument().setValue( "-Vd" + dateRange );
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Construct the command-line argument that is passed to the scm client to
|
||||
* specify the appropriate date range.
|
||||
*
|
||||
*
|
||||
* @param before
|
||||
* The starting point.
|
||||
* @param to
|
||||
* The ending point.
|
||||
* @return A string that can be used to specify a date to a scm system.
|
||||
*
|
||||
*
|
||||
* @see org.apache.maven.changelog.AbstractChangeLogGenerator#getScmDateArgument(java.util.Date,
|
||||
* java.util.Date)
|
||||
*/
|
||||
protected String getScmDateArgument(Date before, Date to) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy",
|
||||
Locale.ENGLISH);
|
||||
String result = sdf.format(to) + "~" + sdf.format(before);
|
||||
protected String getScmDateArgument( Date before, Date to )
|
||||
{
|
||||
SimpleDateFormat sdf =
|
||||
new SimpleDateFormat( "dd/MM/yyyy", Locale.ENGLISH );
|
||||
String result = sdf.format( to ) + "~" + sdf.format( before );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected String getScmTagArgument( String tagStart, String tagEnd )
|
||||
{
|
||||
throw new UnsupportedOperationException( "Cannot presently use tags for SCM operations on VSS" );
|
||||
throw new UnsupportedOperationException(
|
||||
"Cannot presently use tags for SCM operations on VSS" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert date range from 'number of days' format to 'date to date' format
|
||||
*
|
||||
*
|
||||
* @param numDaysString
|
||||
* String
|
||||
*/
|
||||
public void setDateRange(String numDaysString) {
|
||||
int days = Integer.parseInt(numDaysString);
|
||||
public void setDateRange( String numDaysString )
|
||||
{
|
||||
int days = Integer.parseInt( numDaysString );
|
||||
|
||||
Date before = new Date(System.currentTimeMillis() - (long) days * 24
|
||||
* 60 * 60 * 1000);
|
||||
Date to = new Date(System.currentTimeMillis() + (long) 1 * 24 * 60 * 60
|
||||
* 1000);
|
||||
Date before =
|
||||
new Date( System.currentTimeMillis()
|
||||
- ( (long) days * 24 * 60 * 60 * 1000 ) );
|
||||
Date to =
|
||||
new Date( System.currentTimeMillis()
|
||||
+ ( (long) 1 * 24 * 60 * 60 * 1000 ) );
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Execute vss client driving the given parser. This method has been
|
||||
* overwritten to be able to set 'SSDIR' environment variable. This variable
|
||||
* set the vss repository
|
||||
*
|
||||
*
|
||||
* @param parser
|
||||
* A {@link ChangeLogParser parser}to process the vss output.
|
||||
* @return A collection of {@link ChangeLogEntry entries}parsed from the
|
||||
@@ -140,51 +158,70 @@ public class VssChangeLogGenerator extends AbstractChangeLogGenerator {
|
||||
* When there are issues executing vss.
|
||||
* @see ChangeLogGenerator#getEntries(ChangeLogParser)
|
||||
*/
|
||||
public Collection getEntries(ChangeLogParser parser) throws IOException {
|
||||
if (parser == null) {
|
||||
throw new NullPointerException("parser cannot be null");
|
||||
public Collection getEntries( ChangeLogParser parser )
|
||||
throws IOException
|
||||
{
|
||||
if ( parser == null )
|
||||
{
|
||||
throw new NullPointerException( "parser cannot be null" );
|
||||
}
|
||||
|
||||
if (base == null) {
|
||||
throw new NullPointerException("basedir must be set");
|
||||
if ( base == null )
|
||||
{
|
||||
throw new NullPointerException( "basedir must be set" );
|
||||
}
|
||||
|
||||
if (!base.exists()) {
|
||||
throw new FileNotFoundException("Cannot find base dir "
|
||||
+ base.getAbsolutePath());
|
||||
if ( !base.exists() )
|
||||
{
|
||||
throw new FileNotFoundException( "Cannot find base dir "
|
||||
+ base.getAbsolutePath() );
|
||||
}
|
||||
|
||||
clParser = parser;
|
||||
try {
|
||||
VssConnection vssConnection = new VssConnection(getConnection());
|
||||
|
||||
Execute exe = new Execute(this);
|
||||
try
|
||||
{
|
||||
VssConnection vssConnection =
|
||||
new VssConnection( getConnection() );
|
||||
|
||||
Execute exe = new Execute( this );
|
||||
|
||||
String[] env = exe.getEnvironment();
|
||||
if (env == null) {
|
||||
|
||||
if ( env == null )
|
||||
{
|
||||
env = new String[0];
|
||||
}
|
||||
|
||||
String[] newEnv = new String[env.length + 1];
|
||||
for (int i = 0; i < env.length; i++) {
|
||||
|
||||
for ( int i = 0; i < env.length; i++ )
|
||||
{
|
||||
newEnv[i] = env[i];
|
||||
}
|
||||
|
||||
newEnv[env.length] = "SSDIR=" + vssConnection.getVssDir();
|
||||
|
||||
exe.setEnvironment(newEnv);
|
||||
exe.setCommandline(getScmLogCommand().getCommandline());
|
||||
exe.setEnvironment( newEnv );
|
||||
exe.setCommandline( getScmLogCommand().getCommandline() );
|
||||
|
||||
//exe.setVMLauncher(false);
|
||||
exe.setWorkingDirectory(base);
|
||||
logExecute(exe, base);
|
||||
exe.setWorkingDirectory( base );
|
||||
logExecute( exe, base );
|
||||
|
||||
exe.execute();
|
||||
|
||||
// log messages from stderr
|
||||
String errors = errorReader.toString().trim();
|
||||
if (errors.length() > 0) {
|
||||
LOG.error(errors);
|
||||
|
||||
if ( errors.length() > 0 )
|
||||
{
|
||||
LOG.error( errors );
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
handleParserException(ioe);
|
||||
}
|
||||
catch ( IOException ioe )
|
||||
{
|
||||
handleParserException( ioe );
|
||||
}
|
||||
|
||||
return entries;
|
||||
|
||||
@@ -3,13 +3,13 @@ package org.apache.maven.vsslib;
|
||||
/*
|
||||
* ====================================================================
|
||||
* Copyright 2001-2004 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
|
||||
@@ -22,8 +22,10 @@ import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
@@ -36,32 +38,29 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.maven.changelog.ChangeLog;
|
||||
import org.apache.maven.changelog.ChangeLogEntry;
|
||||
import org.apache.maven.changelog.ChangeLogFile;
|
||||
import org.apache.maven.changelog.ChangeLogParser;
|
||||
|
||||
|
||||
/**
|
||||
* Visual Source Safe specific implementation of ChangeLogParser interface.
|
||||
*
|
||||
*
|
||||
* @author Freddy Mallet
|
||||
*/
|
||||
public class VssChangeLogParser implements
|
||||
org.apache.maven.changelog.ChangeLogParser {
|
||||
|
||||
public class VssChangeLogParser
|
||||
implements org.apache.maven.changelog.ChangeLogParser
|
||||
{
|
||||
/** * Log */
|
||||
private static final Log LOG = LogFactory.getLog(VssChangeLogParser.class);
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog( VssChangeLogParser.class );
|
||||
|
||||
/**
|
||||
* Custom date/time formatter. Rounds ChangeLogEntry times to the nearest
|
||||
* minute.
|
||||
*/
|
||||
private static final SimpleDateFormat ENTRY_KEY_TIMESTAMP_FORMAT = new SimpleDateFormat(
|
||||
"yyyyMMddHHmm");
|
||||
|
||||
/**
|
||||
* rcs entries, in reverse (date, time, author, comment) order
|
||||
*/
|
||||
private Map entries = new TreeMap(Collections.reverseOrder());
|
||||
private static final SimpleDateFormat ENTRY_KEY_TIMESTAMP_FORMAT =
|
||||
new SimpleDateFormat( "yyyyMMddHHmm" );
|
||||
|
||||
// state machine constants for reading Starteam output
|
||||
|
||||
/** * expecting file information */
|
||||
private static final int GET_FILE = 1;
|
||||
|
||||
@@ -95,6 +94,11 @@ public class VssChangeLogParser implements
|
||||
/** * Marks comment data */
|
||||
private static final String START_COMMENT = "Comment: ";
|
||||
|
||||
/**
|
||||
* rcs entries, in reverse (date, time, author, comment) order
|
||||
*/
|
||||
private Map entries = new TreeMap( Collections.reverseOrder() );
|
||||
|
||||
/** * last status of the parser */
|
||||
private int lastStatus = GET_FILE;
|
||||
|
||||
@@ -110,178 +114,236 @@ public class VssChangeLogParser implements
|
||||
/**
|
||||
* Create a new ChangeLogParser.
|
||||
*/
|
||||
public VssChangeLogParser() {
|
||||
public VssChangeLogParser()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize the parser from the change log
|
||||
*
|
||||
*
|
||||
* @param changeLog
|
||||
* the controlling task
|
||||
* @see ChangeLogParser#init(ChangeLog)
|
||||
*/
|
||||
public void init(ChangeLog changeLog) {
|
||||
public void init( ChangeLog changeLog )
|
||||
{
|
||||
String connection = changeLog.getRepositoryConnection();
|
||||
try {
|
||||
vssConnection = new VssConnection(connection);
|
||||
} catch (Exception e) {
|
||||
String message = "Unable to parse vss connection string : "
|
||||
+ connection;
|
||||
throw new IllegalArgumentException(message);
|
||||
|
||||
try
|
||||
{
|
||||
vssConnection = new VssConnection( connection );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
String message =
|
||||
"Unable to parse vss connection string : " + connection;
|
||||
|
||||
throw new IllegalArgumentException( message );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the input stream into a collection.
|
||||
*
|
||||
*
|
||||
* @param inputStream
|
||||
* an input stream containing clearcase log output
|
||||
* @return a collection of ChangeLogEntry's
|
||||
* @throws IOException
|
||||
* when there are errors reading the provided stream
|
||||
*/
|
||||
public Collection parse(InputStream inputStream) throws IOException {
|
||||
BufferedReader stream = new BufferedReader(new InputStreamReader(
|
||||
inputStream));
|
||||
public Collection parse( InputStream inputStream )
|
||||
throws IOException
|
||||
{
|
||||
BufferedReader stream =
|
||||
new BufferedReader( new InputStreamReader( inputStream ) );
|
||||
|
||||
String line;
|
||||
|
||||
while ((line = stream.readLine()) != null) {
|
||||
switch (getLineStatus(line)) {
|
||||
case GET_FILE:
|
||||
processGetFile(line);
|
||||
while ( ( line = stream.readLine() ) != null )
|
||||
{
|
||||
switch ( getLineStatus( line ) )
|
||||
{
|
||||
case GET_FILE :
|
||||
processGetFile( line );
|
||||
|
||||
break;
|
||||
case GET_REVISION:
|
||||
processGetRevision(line);
|
||||
|
||||
case GET_REVISION :
|
||||
processGetRevision( line );
|
||||
|
||||
break;
|
||||
case GET_AUTHOR:
|
||||
processGetAuthor(line);
|
||||
|
||||
case GET_AUTHOR :
|
||||
processGetAuthor( line );
|
||||
|
||||
break;
|
||||
case GET_FILE_PATH:
|
||||
processGetFilePath(line);
|
||||
|
||||
case GET_FILE_PATH :
|
||||
processGetFilePath( line );
|
||||
|
||||
break;
|
||||
case GET_COMMENT:
|
||||
processGetComment(line);
|
||||
|
||||
case GET_COMMENT :
|
||||
processGetComment( line );
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return entries.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the current input line in the Get Comment state.
|
||||
*
|
||||
*
|
||||
* @param line
|
||||
* a line of text from the VSS log output
|
||||
*/
|
||||
private void processGetComment(String line) {
|
||||
String[] commentLine = line.split(":");
|
||||
if (commentLine.length == 2) {
|
||||
getCurrentLogEntry().setComment(commentLine[1]);
|
||||
private void processGetComment( String line )
|
||||
{
|
||||
String[] commentLine = line.split( ":" );
|
||||
|
||||
if ( commentLine.length == 2 )
|
||||
{
|
||||
getCurrentLogEntry().setComment( commentLine[1] );
|
||||
}
|
||||
|
||||
//Comment suite on a new line
|
||||
else {
|
||||
else
|
||||
{
|
||||
String comment = getCurrentLogEntry().getComment();
|
||||
|
||||
comment = comment + " " + line;
|
||||
getCurrentLogEntry().setComment(comment);
|
||||
getCurrentLogEntry().setComment( comment );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the current input line in the Get Author state.
|
||||
*
|
||||
*
|
||||
* @param line
|
||||
* a line of text from the VSS log output
|
||||
*/
|
||||
private void processGetAuthor(String line) {
|
||||
String[] result = line.split("\\s");
|
||||
private void processGetAuthor( String line )
|
||||
{
|
||||
String[] result = line.split( "\\s" );
|
||||
Vector vector = new Vector();
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
if (!result[i].equals("")) {
|
||||
vector.add(result[i]);
|
||||
|
||||
for ( int i = 0; i < result.length; i++ )
|
||||
{
|
||||
if ( !result[i].equals( "" ) )
|
||||
{
|
||||
vector.add( result[i] );
|
||||
}
|
||||
}
|
||||
|
||||
ChangeLogEntry entry = getCurrentLogEntry();
|
||||
entry.setAuthor((String) vector.get(1));
|
||||
entry.setDate(parseDate((String) vector.get(3) + " "
|
||||
+ (String) vector.get(5)));
|
||||
|
||||
entry.setAuthor( (String) vector.get( 1 ) );
|
||||
entry.setDate( parseDate( (String) vector.get( 3 ) + " "
|
||||
+ (String) vector.get( 5 ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the current input line in the Get File state.
|
||||
*
|
||||
*
|
||||
* @param line
|
||||
* a line of text from the VSS log output
|
||||
*/
|
||||
private void processGetFile(String line) {
|
||||
setCurrentLogEntry(new ChangeLogEntry());
|
||||
String[] fileLine = line.split(" ");
|
||||
setCurrentFile(new ChangeLogFile(fileLine[2]));
|
||||
private void processGetFile( String line )
|
||||
{
|
||||
setCurrentLogEntry( new ChangeLogEntry() );
|
||||
|
||||
String[] fileLine = line.split( " " );
|
||||
|
||||
setCurrentFile( new ChangeLogFile( fileLine[2] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the current input line in the Get File Path state.
|
||||
*
|
||||
*
|
||||
* @param line
|
||||
* a line of text from the VSS log output
|
||||
*/
|
||||
private void processGetFilePath(String line) {
|
||||
if (getCurrentFile() != null) {
|
||||
private void processGetFilePath( String line )
|
||||
{
|
||||
if ( getCurrentFile() != null )
|
||||
{
|
||||
String fileName = getCurrentFile().getName();
|
||||
|
||||
String path = line.substring(line.indexOf("$"), line.length());
|
||||
String longPath = path.substring(vssConnection.getVssProject()
|
||||
.length() + 1, path.length())
|
||||
+ "/" + fileName;
|
||||
getCurrentFile().setName(longPath);
|
||||
addEntry(getCurrentLogEntry(), getCurrentFile());
|
||||
String path =
|
||||
line.substring( line.indexOf( "$" ), line.length() );
|
||||
String longPath =
|
||||
path.substring( vssConnection.getVssProject().length() + 1,
|
||||
path.length() ) + "/" + fileName;
|
||||
|
||||
getCurrentFile().setName( longPath );
|
||||
addEntry( getCurrentLogEntry(), getCurrentFile() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the current input line in the Get Revision state.
|
||||
*
|
||||
*
|
||||
* @param line
|
||||
* a line of text from the VSS log output
|
||||
*/
|
||||
private void processGetRevision(String line) {
|
||||
String[] revisionLine = line.split(" ");
|
||||
getCurrentFile().setRevision(revisionLine[1]);
|
||||
private void processGetRevision( String line )
|
||||
{
|
||||
String[] revisionLine = line.split( " " );
|
||||
|
||||
getCurrentFile().setRevision( revisionLine[1] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify the status of a vss history line
|
||||
*
|
||||
*
|
||||
* @param the
|
||||
* line to process
|
||||
* @return status
|
||||
*/
|
||||
private int getLineStatus(String line) {
|
||||
private int getLineStatus( String line )
|
||||
{
|
||||
int argument = GET_UNKNOWN;
|
||||
if (line.startsWith(START_FILE)) {
|
||||
|
||||
if ( line.startsWith( START_FILE ) )
|
||||
{
|
||||
argument = GET_FILE;
|
||||
} else if (line.startsWith(START_REVISION)) {
|
||||
}
|
||||
else if ( line.startsWith( START_REVISION ) )
|
||||
{
|
||||
argument = GET_REVISION;
|
||||
} else if (line.startsWith(START_AUTHOR)) {
|
||||
}
|
||||
else if ( line.startsWith( START_AUTHOR ) )
|
||||
{
|
||||
argument = GET_AUTHOR;
|
||||
} else if (line.indexOf(START_FILE_PATH) != -1) {
|
||||
}
|
||||
else if ( line.indexOf( START_FILE_PATH ) != -1 )
|
||||
{
|
||||
argument = GET_FILE_PATH;
|
||||
} else if (line.startsWith(START_COMMENT)) {
|
||||
}
|
||||
else if ( line.startsWith( START_COMMENT ) )
|
||||
{
|
||||
argument = GET_COMMENT;
|
||||
} else if (getLastStatus() == GET_COMMENT) {
|
||||
}
|
||||
else if ( getLastStatus() == GET_COMMENT )
|
||||
{
|
||||
//Comment suite on a new line
|
||||
argument = getLastStatus();
|
||||
}
|
||||
setLastStatus(argument);
|
||||
|
||||
setLastStatus( argument );
|
||||
|
||||
return argument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a change log entry to the list (if it's not already there) with the
|
||||
* given file.
|
||||
*
|
||||
*
|
||||
* @param entry
|
||||
* a {@link ChangeLogEntry}to be added to the list if another
|
||||
* with the same key doesn't exist already. If the entry's author
|
||||
@@ -289,110 +351,131 @@ public class VssChangeLogParser implements
|
||||
* @param file
|
||||
* a {@link ChangeLogFile}to be added to the entry
|
||||
*/
|
||||
private void addEntry(ChangeLogEntry entry, ChangeLogFile file) {
|
||||
private void addEntry( ChangeLogEntry entry, ChangeLogFile file )
|
||||
{
|
||||
// do not add if entry is not populated
|
||||
if (entry.getAuthor() == null) {
|
||||
if ( entry.getAuthor() == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String key = ENTRY_KEY_TIMESTAMP_FORMAT.format(entry.getDate())
|
||||
+ entry.getAuthor() + entry.getComment();
|
||||
String key =
|
||||
ENTRY_KEY_TIMESTAMP_FORMAT.format( entry.getDate() )
|
||||
+ entry.getAuthor() + entry.getComment();
|
||||
|
||||
if (!entries.containsKey(key)) {
|
||||
entry.addFile(file);
|
||||
entries.put(key, entry);
|
||||
} else {
|
||||
ChangeLogEntry existingEntry = (ChangeLogEntry) entries.get(key);
|
||||
existingEntry.addFile(file);
|
||||
if ( !entries.containsKey( key ) )
|
||||
{
|
||||
entry.addFile( file );
|
||||
entries.put( key, entry );
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeLogEntry existingEntry = (ChangeLogEntry) entries.get( key );
|
||||
|
||||
existingEntry.addFile( file );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the date timestamp from the svn output into a date object.
|
||||
*
|
||||
*
|
||||
* @return A date representing the timestamp of the log entry.
|
||||
*/
|
||||
private Date parseDate(String dateString) {
|
||||
try {
|
||||
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yy HH:mm");
|
||||
Date date = format.parse(dateString);
|
||||
private Date parseDate( String dateString )
|
||||
{
|
||||
try
|
||||
{
|
||||
SimpleDateFormat format = new SimpleDateFormat( "dd.MM.yy HH:mm" );
|
||||
Date date = format.parse( dateString );
|
||||
|
||||
return date;
|
||||
} catch (ParseException e) {
|
||||
LOG.error("ParseException Caught", e);
|
||||
}
|
||||
catch ( ParseException e )
|
||||
{
|
||||
LOG.error( "ParseException Caught", e );
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for property currentFile.
|
||||
*
|
||||
*
|
||||
* @return Value of property currentFile.
|
||||
*/
|
||||
private ChangeLogFile getCurrentFile() {
|
||||
private ChangeLogFile getCurrentFile()
|
||||
{
|
||||
return currentFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for property currentFile.
|
||||
*
|
||||
*
|
||||
* @param currentFile
|
||||
* New value of property currentFile.
|
||||
*/
|
||||
private void setCurrentFile(ChangeLogFile currentFile) {
|
||||
private void setCurrentFile( ChangeLogFile currentFile )
|
||||
{
|
||||
this.currentFile = currentFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for property currentLogEntry.
|
||||
*
|
||||
*
|
||||
* @return Value of property currentLogEntry.
|
||||
*/
|
||||
private ChangeLogEntry getCurrentLogEntry() {
|
||||
private ChangeLogEntry getCurrentLogEntry()
|
||||
{
|
||||
return currentLogEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for property currentLogEntry.
|
||||
*
|
||||
*
|
||||
* @param currentLogEntry
|
||||
* New value of property currentLogEntry.
|
||||
*/
|
||||
private void setCurrentLogEntry(ChangeLogEntry currentLogEntry) {
|
||||
private void setCurrentLogEntry( ChangeLogEntry currentLogEntry )
|
||||
{
|
||||
this.currentLogEntry = currentLogEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for property status.
|
||||
*
|
||||
*
|
||||
* @return Value of property status.
|
||||
*/
|
||||
private int getLastStatus() {
|
||||
private int getLastStatus()
|
||||
{
|
||||
return lastStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for property status.
|
||||
*
|
||||
*
|
||||
* @param status
|
||||
* New value of property status.
|
||||
*/
|
||||
private void setLastStatus(int status) {
|
||||
private void setLastStatus( int status )
|
||||
{
|
||||
this.lastStatus = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up any parser resources
|
||||
*
|
||||
*
|
||||
* @see ChangeLogParser#cleanup()
|
||||
*/
|
||||
public void cleanup() {
|
||||
public void cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined in ChangeLogParser interface
|
||||
*
|
||||
*
|
||||
* @see ChangeLogParser
|
||||
*/
|
||||
public void setDateFormatInFile(String s) {
|
||||
public void setDateFormatInFile( String s )
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,13 @@ package org.apache.maven.vsslib;
|
||||
/*
|
||||
* ====================================================================
|
||||
* Copyright 2001-2004 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
|
||||
@@ -21,16 +21,17 @@ package org.apache.maven.vsslib;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Bean representation of the vss connection string
|
||||
*
|
||||
*
|
||||
* @author Freddy Mallet
|
||||
*/
|
||||
public class VssConnection {
|
||||
|
||||
public class VssConnection
|
||||
{
|
||||
/** Log */
|
||||
private static final Log LOG = LogFactory
|
||||
.getLog(VssChangeLogGenerator.class);
|
||||
private static final Log LOG =
|
||||
LogFactory.getLog( VssChangeLogGenerator.class );
|
||||
|
||||
/**
|
||||
* VSS repository path
|
||||
@@ -52,54 +53,68 @@ public class VssConnection {
|
||||
* string. Here is an example:
|
||||
* scm:vss:\\lancelot\Vss_EApplications\:guest,password:/Security/LOSCProduction
|
||||
* the password is not madatory
|
||||
*
|
||||
*
|
||||
* @param connection
|
||||
* the vss connection string
|
||||
*/
|
||||
public VssConnection(String connection) {
|
||||
if (!connection.startsWith("scm:vss")) {
|
||||
throw new IllegalArgumentException(
|
||||
"repositoy connection string does not specify 'vss' as the scm");
|
||||
public VssConnection( String connection )
|
||||
{
|
||||
if ( !connection.startsWith( "scm:vss" ) )
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"repositoy connection string does not specify 'vss' as the scm" );
|
||||
}
|
||||
try {
|
||||
String[] splitedConnection = connection.split(":");
|
||||
|
||||
try
|
||||
{
|
||||
String[] splitedConnection = connection.split( ":" );
|
||||
|
||||
vssDir = splitedConnection[2];
|
||||
if(!splitedConnection[3].equals("")){
|
||||
|
||||
if ( !splitedConnection[3].equals( "" ) )
|
||||
{
|
||||
vssUserInf = splitedConnection[3];
|
||||
}
|
||||
|
||||
vssProject = splitedConnection[4];
|
||||
} catch (Exception e) {
|
||||
String message = "Unable to parse VSS connection string :"
|
||||
+ connection;
|
||||
LOG.error(message, e);
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
String message =
|
||||
"Unable to parse VSS connection string :" + connection;
|
||||
|
||||
LOG.error( message, e );
|
||||
throw new IllegalArgumentException( message );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the vss directory
|
||||
*
|
||||
*
|
||||
* @return vss directory
|
||||
*/
|
||||
public String getVssDir() {
|
||||
public String getVssDir()
|
||||
{
|
||||
return vssDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the vss project
|
||||
*
|
||||
*
|
||||
* @return vss project
|
||||
*/
|
||||
public String getVssProject() {
|
||||
public String getVssProject()
|
||||
{
|
||||
return vssProject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the vss user information
|
||||
*
|
||||
*
|
||||
* @return vss user information
|
||||
*/
|
||||
public String getVssUserInf() {
|
||||
public String getVssUserInf()
|
||||
{
|
||||
return vssUserInf;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,10 +18,8 @@ package org.apache.maven.starteamlib;
|
||||
*/
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.maven.changelog.ChangeLogEntry;
|
||||
|
||||
@@ -18,10 +18,8 @@ package org.apache.maven.starteamlib;
|
||||
*/
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.maven.changelog.ChangeLogEntry;
|
||||
|
||||
Reference in new issue
Block a user