FileDocCategorySizeDatePackage
ChangeLogTask.javaAPI DocApache Ant 1.7014074Wed Dec 13 06:16:20 GMT 2006org.apache.tools.ant.taskdefs.cvslib

ChangeLogTask

public class ChangeLogTask extends org.apache.tools.ant.taskdefs.AbstractCvsTask
Examines the output of cvs log and group related changes together. It produces an XML output representing the list of changes.
<!-- Root element -->
<!ELEMENT changelog 
(entry+)
>
<!-- CVS Entry -->
<!ELEMENT entry 
(date,author,file+,msg)
>
<!-- Date of cvs entry -->
<!ELEMENT date (#PCDATA)
>
<!-- Author of change -->
<!ELEMENT author (#PCDATA)
>
<!-- List of files affected -->
<!ELEMENT msg (#PCDATA)
>
<!-- File changed -->
<!ELEMENT file 
(name,revision,prevrevision?
)>
<!-- Name of the file -->
<!ELEMENT name (#PCDATA)
>
<!-- Revision number -->
<!ELEMENT revision 
(#PCDATA)>
<!-- Previous revision number -->
<!ELEMENT prevrevision 
(#PCDATA)>
since
Ant 1.5
ant.task
name="cvschangelog" category="scm"

Fields Summary
private File
usersFile
User list
private Vector
cvsUsers
User list
private File
inputDir
Input dir
private File
destFile
Output file
private Date
startDate
The earliest date at which to start processing entries.
private Date
endDate
The latest date at which to stop processing entries.
private final Vector
filesets
Filesets containing list of files against which the cvs log will be performed. If empty then all files in the working directory will be checked.
Constructors Summary
Methods Summary
public voidaddFileset(org.apache.tools.ant.types.FileSet fileSet)
Adds a set of files about which cvs logs will be generated.

param
fileSet a set of files about which cvs logs will be generated.

        filesets.addElement(fileSet);
    
public voidaddUser(CvsUser user)
Add a user to list changelog knows about.

param
user the user

        cvsUsers.addElement(user);
    
public voidexecute()
Execute task

exception
BuildException if something goes wrong executing the cvs command

        File savedDir = inputDir; // may be altered in validate

        try {

            validate();
            final Properties userList = new Properties();

            loadUserlist(userList);

            for (int i = 0, size = cvsUsers.size(); i < size; i++) {
                final CvsUser user = (CvsUser) cvsUsers.get(i);
                user.validate();
                userList.put(user.getUserID(), user.getDisplayname());
            }

            setCommand("log");

            if (getTag() != null) {
                CvsVersion myCvsVersion = new CvsVersion();
                myCvsVersion.setProject(getProject());
                myCvsVersion.setTaskName("cvsversion");
                myCvsVersion.setCvsRoot(getCvsRoot());
                myCvsVersion.setCvsRsh(getCvsRsh());
                myCvsVersion.setPassfile(getPassFile());
                myCvsVersion.setDest(inputDir);
                myCvsVersion.execute();
                if (myCvsVersion.supportsCvsLogWithSOption()) {
                    addCommandArgument("-S");
                }
            }
            if (null != startDate) {
                final SimpleDateFormat outputDate =
                    new SimpleDateFormat("yyyy-MM-dd");

                // We want something of the form: -d ">=YYYY-MM-dd"
                final String dateRange = ">=" + outputDate.format(startDate);

                // Supply '-d' as a separate argument - Bug# 14397
                addCommandArgument("-d");
                addCommandArgument(dateRange);
            }

            // Check if list of files to check has been specified
            if (!filesets.isEmpty()) {
                final Enumeration e = filesets.elements();

                while (e.hasMoreElements()) {
                    final FileSet fileSet = (FileSet) e.nextElement();
                    final DirectoryScanner scanner =
                        fileSet.getDirectoryScanner(getProject());
                    final String[] files = scanner.getIncludedFiles();

                    for (int i = 0; i < files.length; i++) {
                        addCommandArgument(files[i]);
                    }
                }
            }

            final ChangeLogParser parser = new ChangeLogParser();
            final RedirectingStreamHandler handler =
                new RedirectingStreamHandler(parser);

            log(getCommand(), Project.MSG_VERBOSE);

            setDest(inputDir);
            setExecuteStreamHandler(handler);
            try {
                super.execute();
            } finally {
                final String errors = handler.getErrors();

                if (null != errors) {
                    log(errors, Project.MSG_ERR);
                }
            }
            final CVSEntry[] entrySet = parser.getEntrySetAsArray();
            final CVSEntry[] filteredEntrySet = filterEntrySet(entrySet);

            replaceAuthorIdWithName(userList, filteredEntrySet);

            writeChangeLog(filteredEntrySet);

        } finally {
            inputDir = savedDir;
        }
    
private CVSEntry[]filterEntrySet(CVSEntry[] entrySet)
Filter the specified entries according to an appropriate rule.

param
entrySet the entry set to filter
return
the filtered entry set

        final Vector results = new Vector();

        for (int i = 0; i < entrySet.length; i++) {
            final CVSEntry cvsEntry = entrySet[i];
            final Date date = cvsEntry.getDate();

            //bug#30471
            //this is caused by Date.after throwing a NullPointerException
            //for some reason there's no date set in the CVSEntry
            //Java 1.3.1 API
            //http://java.sun.com/j2se/1.3/docs/api/java/util/Date.html#after(java.util.Date)
            //doesn't throw NullPointerException
            //Java 1.4.2 + 1.5 API
            //http://java.sun.com/j2se/1.4.2/docs/api/java/util/Date.html#after(java.util.Date)
            //according to the docs it doesn't throw, according to the bug report it does
            //http://java.sun.com/j2se/1.5.0/docs/api/java/util/Date.html#after(java.util.Date)
            //according to the docs it does throw

            //for now skip entries which are missing a date
            if (null == date) {
                continue;
            }

            if (null != startDate && startDate.after(date)) {
                //Skip dates that are too early
                continue;
            }
            if (null != endDate && endDate.before(date)) {
                //Skip dates that are too late
                continue;
            }
            results.addElement(cvsEntry);
        }

        final CVSEntry[] resultArray = new CVSEntry[results.size()];

        results.copyInto(resultArray);
        return resultArray;
    
private voidloadUserlist(java.util.Properties userList)
Load the userlist from the userList file (if specified) and add to list of users.

param
userList the file of users
throws
BuildException if file can not be loaded for some reason

        if (null != usersFile) {
            try {
                userList.load(new FileInputStream(usersFile));
            } catch (final IOException ioe) {
                throw new BuildException(ioe.toString(), ioe);
            }
        }
    
private voidreplaceAuthorIdWithName(java.util.Properties userList, CVSEntry[] entrySet)
replace all known author's id's with their maven specified names

        for (int i = 0; i < entrySet.length; i++) {

            final CVSEntry entry = entrySet[ i ];
            if (userList.containsKey(entry.getAuthor())) {
                entry.setAuthor(userList.getProperty(entry.getAuthor()));
            }
        }
    
public voidsetDaysinpast(int days)
Set the number of days worth of log entries to process.

param
days the number of days of log to process.

        final long time = System.currentTimeMillis()
             - (long) days * 24 * 60 * 60 * 1000;

        setStart(new Date(time));
    
public voidsetDestfile(java.io.File destFile)
Set the output file for the log.

param
destFile The new destfile value

        this.destFile = destFile;
    
public voidsetDir(java.io.File inputDir)
Set the base dir for cvs.

param
inputDir The new dir value



                     
         
        this.inputDir = inputDir;
    
public voidsetEnd(java.util.Date endDate)
Set the date at which the changelog should stop.

param
endDate The date at which the changelog should stop.

        this.endDate = endDate;
    
public voidsetStart(java.util.Date start)
Set the date at which the changelog should start.

param
start The date at which the changelog should start.

        this.startDate = start;
    
public voidsetUsersfile(java.io.File usersFile)
Set a lookup list of user names & addresses

param
usersFile The file containing the users info.

        this.usersFile = usersFile;
    
private voidvalidate()
Validate the parameters specified for task.

throws
BuildException if fails validation checks

        if (null == inputDir) {
            inputDir = getProject().getBaseDir();
        }
        if (null == destFile) {
            final String message = "Destfile must be set.";

            throw new BuildException(message);
        }
        if (!inputDir.exists()) {
            final String message = "Cannot find base dir "
                 + inputDir.getAbsolutePath();

            throw new BuildException(message);
        }
        if (null != usersFile && !usersFile.exists()) {
            final String message = "Cannot find user lookup list "
                 + usersFile.getAbsolutePath();

            throw new BuildException(message);
        }
    
private voidwriteChangeLog(CVSEntry[] entrySet)
Print changelog to file specified in task.

param
entrySet the entry set to write.
throws
BuildException if there is an error writing changelog.

        FileOutputStream output = null;

        try {
            output = new FileOutputStream(destFile);

            final PrintWriter writer =
                new PrintWriter(new OutputStreamWriter(output, "UTF-8"));

            final ChangeLogWriter serializer = new ChangeLogWriter();

            serializer.printChangeLog(writer, entrySet);
        } catch (final UnsupportedEncodingException uee) {
            getProject().log(uee.toString(), Project.MSG_ERR);
        } catch (final IOException ioe) {
            throw new BuildException(ioe.toString(), ioe);
        } finally {
            FileUtils.close(output);
        }