kaz 02/04/30 08:33:15
Added: src/java/org/apache/maven/cvslib CvsChangeLogGenerator.java
CvsChangeLogParser.java
Log:
Adding missing files from glenn's patch.
Revision Changes Path
1.1
jakarta-turbine-maven/src/java/org/apache/maven/cvslib/CvsChangeLogGenerator.java
Index: CvsChangeLogGenerator.java
===================================================================
package org.apache.maven.cvslib;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Maven" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Maven", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Date;
import java.text.SimpleDateFormat;
// maven imports
import org.apache.maven.changelog.ChangeLog;
import org.apache.maven.changelog.ChangeLogGenerator;
import org.apache.maven.changelog.ChangeLogParser;
import org.apache.maven.util.AsyncStreamReader;
// ant imports
import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
import org.apache.tools.ant.taskdefs.Execute;
import org.apache.tools.ant.types.Commandline;
/**
* A CVS implementation of the {@link org.apache.maven.changelog.ChangeLog}
* interface.
*
* @todo Check CVS exists first by running cvs -version instead of current hack
* @author Glenn McAllister
* @author <a href="mailto:[EMAIL PROTECTED]">Jeff Martin</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a>
* @author <a href="mailto:[EMAIL PROTECTED]">dIon Gillard</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Stefan Bodewig</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
* @version $Id: CvsChangeLogGenerator.java,v 1.1 2002/04/30 15:33:15 kaz Exp $
*/
public class CvsChangeLogGenerator
implements ChangeLogGenerator, ExecuteStreamHandler
{
/**
* Reference to the enclosing ChangeLog instance - used to obtain any
* necessary configuration information.
* */
private ChangeLog changeLogExecutor;
/**
* stderr stream eater
* */
private AsyncStreamReader errorReader;
/**
* The cvs process input stream.
* */
private InputStream in;
/**
* The working directory for cvs.
* */
private File base;
/**
* The CVS date range.
*/
private String dateRange;
/**
* The parser that takes the cvs log output and transforms it into a
* collection of ChangeLogEntry's.
*/
private ChangeLogParser clParser;
/**
* The collection of ChangeLogEntry's returned from clParser.
*/
private Collection entries;
// doc comment inherited from interface
public void init( ChangeLog changeLog )
{
changeLogExecutor = changeLog;
base = changeLogExecutor.getBasedir();
if (changeLogExecutor.getRange() != null)
{
setDateRange( changeLogExecutor.getRange() );
}
}
/**
* Set the dateRange member based on the number of days obtained from the
* ChangeLog.
*/
private 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);
SimpleDateFormat outputDate = new SimpleDateFormat("yyyy-MM-dd");
// We want something of the form: -d ">=YYYY-MM-dd"
dateRange = "-d " + outputDate.format(before) + "<" +
outputDate.format(to);
}
// doc comment inherited from ChangeLogGenerator interface
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(getCvsLogCommand().getCommandline());
exe.setAntRun(changeLogExecutor.getProject());
exe.setWorkingDirectory(base);
exe.execute();
// log messages from stderr
String errors = errorReader.toString().trim();
if (errors.length() > 0)
{
changeLogExecutor.log(errors);
}
}
catch (IOException ioe)
{
if (ioe.getMessage().indexOf("CreateProcess") != -1 ||
ioe.getMessage().indexOf("cvs: not found") != -1)
{
// can't find CVS on Win32 or Linux...
changeLogExecutor.log(
"Unable to find cvs executable. Changelog will be empty");
}
else
{
throw ioe;
}
}
return entries;
}
// doc comment inherited from interface - nothing to do
public void cleanup()
{
}
/**
* @return the cvs command line to be executed.
*/
private Commandline getCvsLogCommand()
{
Commandline command = new Commandline();
command.setExecutable("cvs");
command.createArgument().setValue("log");
if (dateRange != null)
{
command.createArgument().setValue(dateRange);
}
return command;
}
/**
* Stop the process - currently unimplemented
*/
public void stop()
{
}
/**
* Set the input stream for the cvs process. cvs requires no input so this
* is not used.
* @param os - an {@link java.io.OutputStream}
*/
public void setProcessInputStream(OutputStream os)
{
}
/**
* 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 AsyncStreamReader(is);
}
/**
* Set the input stream used to read from cvs log
* @param is - a stream of cvs log output to be read from
*/
public void setProcessOutputStream(InputStream is)
{
in = is;
}
/**
* Start read from the cvs log.
* @throws IOException when there are errors reading from the streams
* previously provided
*/
public void start() throws IOException
{
errorReader.start();
entries = clParser.parse(in);
}
}
1.1
jakarta-turbine-maven/src/java/org/apache/maven/cvslib/CvsChangeLogParser.java
Index: CvsChangeLogParser.java
===================================================================
package org.apache.maven.cvslib;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Maven" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Maven", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
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;
/**
* A class to parse cvs log output
*
* @author <a href="mailto:[EMAIL PROTECTED]">dIon Gillard</a>
* @version $Id: CvsChangeLogParser.java,v 1.1 2002/04/30 15:33:15 kaz Exp $
*/
public class CvsChangeLogParser implements ChangeLogParser
{
/**
* rcs entries, in reverse (date, time, author, comment) order
*/
private Map entries = new TreeMap(Collections.reverseOrder());
// 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 = "==================================="
+ "==========================================";
/** 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: ";
/** 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;
/**
* Create a new ChangeLogParser.
*/
public CvsChangeLogParser()
{
}
// doc comment inherited from ChangeLogParer interface
public void init( ChangeLog changeLog )
{
}
// doc comment inherited from ChangeLogParer interface
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
{
BufferedReader stream = new BufferedReader(
new InputStreamReader(anInputStream) );
// current state transitions in the state machine - starts with Get File
// Get File -> Get Revision
// Get Revision -> Get Date or Get File
// Get Date -> Get Comment
// Get Comment -> Get Comment or Get Revision
String line = null;
while ((line = stream.readLine()) != null)
{
switch (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.
* @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
* 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)
{
// do not add if entry is not populated
if (entry.getAuthor() == null)
{
return;
}
String key = entry.getDateFormatted() + entry.getTimeFormatted() +
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);
}
}
/**
* 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)
{
if (line.startsWith(START_FILE))
{
setCurrentLogEntry(new ChangeLogEntry());
setCurrentFile(new ChangeLogFile(line.substring(START_FILE.length(),
line.length())));
setStatus(GET_REVISION);
}
}
/**
* 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)
{
if (line.startsWith(REVISION_TAG))
{
getCurrentFile().setRevision(line.substring(REVISION_TAG.length()));
setStatus(GET_DATE);
}
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());
}
}
/**
* 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)
{
if (line.startsWith(DATE_TAG))
{
StringTokenizer tokenizer = new StringTokenizer(line, " ;");
// date: YYYY/mm/dd HH:mm:ss; author: name
tokenizer.nextToken(); // date tag
String date = tokenizer.nextToken();
String time = tokenizer.nextToken();
getCurrentLogEntry().setDate(date + " " + time);
tokenizer.nextToken(); // author tag
// assumes author can't contain spaces
String author = tokenizer.nextToken();
getCurrentLogEntry().setAuthor(author);
setStatus(GET_COMMENT);
}
}
/**
* 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)
{
if (line.startsWith(START_REVISION))
{
// add entry, and set state to get revision
addEntry(getCurrentLogEntry(), getCurrentFile());
// new change log entry
setCurrentLogEntry(new ChangeLogEntry());
// same file name, but different rev
setCurrentFile(new ChangeLogFile(getCurrentFile().getName()));
setStatus(GET_REVISION);
}
else if (line.startsWith(END_FILE))
{
addEntry(getCurrentLogEntry(), getCurrentFile());
setStatus(GET_FILE);
}
else
{
// keep gathering comments
getCurrentLogEntry().setComment(
getCurrentLogEntry().getComment() + line + "\n");
}
}
/**
* Getter for property currentFile.
* @return Value of property currentFile.
*/
private ChangeLogFile getCurrentFile()
{
return currentFile;
}
/**
* Setter for property currentFile.
* @param currentFile New value of property currentFile.
*/
private void setCurrentFile(ChangeLogFile currentFile)
{
this.currentFile = currentFile;
}
/**
* Getter for property currentLogEntry.
* @return Value of property currentLogEntry.
*/
private ChangeLogEntry getCurrentLogEntry()
{
return currentLogEntry;
}
/**
* Setter for property currentLogEntry.
* @param currentLogEntry New value of property currentLogEntry.
*/
private void setCurrentLogEntry(ChangeLogEntry currentLogEntry)
{
this.currentLogEntry = currentLogEntry;
}
/**
* Getter for property status.
* @return Value of property status.
*/
private int getStatus()
{
return status;
}
/**
* Setter for property status.
* @param status New value of property status.
*/
private void setStatus(int status)
{
this.status = status;
}
}