FileDocCategorySizeDatePackage
CvsTagDiff.javaAPI DocApache Ant 1.7015338Wed Dec 13 06:16:24 GMT 2006org.apache.tools.ant.taskdefs.cvslib

CvsTagDiff

public class CvsTagDiff extends org.apache.tools.ant.taskdefs.AbstractCvsTask
Examines the output of cvs rdiff between two tags. It produces an XML output representing the list of changes.
<!-- Root element -->
<!ELEMENT tagdiff ( entry+ ) >
<!-- Start tag of the report -->
<!ATTLIST tagdiff startTag NMTOKEN #IMPLIED >
<!-- End tag of the report -->
<!ATTLIST tagdiff endTag NMTOKEN #IMPLIED >
<!-- Start date of the report -->
<!ATTLIST tagdiff startDate NMTOKEN #IMPLIED >
<!-- End date of the report -->
<!ATTLIST tagdiff endDate NMTOKEN #IMPLIED >

<!-- CVS tag entry -->
<!ELEMENT entry ( file ) >
<!-- File added, changed or removed -->
<!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="cvstagdiff"

Fields Summary
private static final org.apache.tools.ant.util.FileUtils
FILE_UTILS
Used to create the temp file for cvs log
private static final org.apache.tools.ant.util.DOMElementWriter
DOM_WRITER
stateless helper for writing the XML document
static final String
FILE_STRING
Token to identify the word file in the rdiff log
static final String
TO_STRING
Token to identify the word file in the rdiff log
static final String
FILE_IS_NEW
Token to identify a new file in the rdiff log
static final String
REVISION
Token to identify the revision
static final String
FILE_HAS_CHANGED
Token to identify a modified file in the rdiff log
static final String
FILE_WAS_REMOVED
Token to identify a removed file in the rdiff log
private String
mypackage
The cvs package/module to analyse
private String
mystartTag
The earliest tag from which diffs are to be included in the report.
private String
myendTag
The latest tag from which diffs are to be included in the report.
private String
mystartDate
The earliest date from which diffs are to be included in the report.
private String
myendDate
The latest date from which diffs are to be included in the report.
private File
mydestfile
The file in which to write the diff report.
Constructors Summary
Methods Summary
public voidexecute()
Execute task.

exception
BuildException if an error occurs

        // validate the input parameters
        validate();

        // build the rdiff command
        addCommandArgument("rdiff");
        addCommandArgument("-s");
        if (mystartTag != null) {
            addCommandArgument("-r");
            addCommandArgument(mystartTag);
        } else {
            addCommandArgument("-D");
            addCommandArgument(mystartDate);
        }
        if (myendTag != null) {
            addCommandArgument("-r");
            addCommandArgument(myendTag);
        } else {
            addCommandArgument("-D");
            addCommandArgument(myendDate);
        }
        // support multiple packages
        StringTokenizer myTokenizer = new StringTokenizer(mypackage);
        while (myTokenizer.hasMoreTokens()) {
            addCommandArgument(myTokenizer.nextToken());
        }
        // force command not to be null
        setCommand("");
        File tmpFile = null;
        try {
            tmpFile = FILE_UTILS.createTempFile("cvstagdiff", ".log", null);
            tmpFile.deleteOnExit();
            setOutput(tmpFile);

            // run the cvs command
            super.execute();

            // parse the rdiff
            CvsTagEntry[] entries = parseRDiff(tmpFile);

            // write the tag diff
            writeTagDiff(entries);

        } finally {
            if (tmpFile != null) {
                tmpFile.delete();
            }
        }
    
private CvsTagEntry[]parseRDiff(java.io.File tmpFile)
Parse the tmpFile and return and array of CvsTagEntry to be written in the output.

param
tmpFile the File containing the output of the cvs rdiff command
return
the entries in the output
exception
BuildException if an error occurs

        // parse the output of the command
        BufferedReader reader = null;

        try {
            reader = new BufferedReader(new FileReader(tmpFile));

            // entries are of the form:
            //CVS 1.11
            // File module/filename is new; current revision 1.1
            //CVS 1.11.9
            // File module/filename is new; cvstag_2003_11_03_2  revision 1.1
            // or
            // File module/filename changed from revision 1.4 to 1.6
            // or
            // File module/filename is removed; not included in
            // release tag SKINLF_12
            //CVS 1.11.9
            // File testantoine/antoine.bat is removed; TESTANTOINE_1 revision 1.1.1.1
            //
            // get rid of 'File module/"
            String toBeRemoved = FILE_STRING + mypackage + "/";
            int headerLength = toBeRemoved.length();
            Vector entries = new Vector();

            String line = reader.readLine();
            int index;
            CvsTagEntry entry = null;

            while (null != line) {
                if (line.length() > headerLength) {
                    if (line.startsWith(toBeRemoved)) {
                        line = line.substring(headerLength);
                    } else {
                        line = line.substring(FILE_STRING.length());
                    }

                    if ((index = line.indexOf(FILE_IS_NEW)) != -1) {
                        // it is a new file
                        // set the revision but not the prevrevision
                        String filename = line.substring(0, index);
                        String rev = null;
                        int indexrev = -1;
                        if ((indexrev = line.indexOf(REVISION, index)) != -1) {
                            rev = line.substring(indexrev + REVISION.length());
                        }
                        entry = new CvsTagEntry(filename, rev);
                        entries.addElement(entry);
                        log(entry.toString(), Project.MSG_VERBOSE);
                    } else if ((index = line.indexOf(FILE_HAS_CHANGED)) != -1) {
                        // it is a modified file
                        // set the revision and the prevrevision
                        String filename = line.substring(0, index);
                        int revSeparator = line.indexOf(" to ", index);
                        String prevRevision =
                            line.substring(index + FILE_HAS_CHANGED.length(),
                                revSeparator);
                        String revision = line.substring(revSeparator + TO_STRING.length());
                        entry = new CvsTagEntry(filename,
                            revision,
                            prevRevision);
                        entries.addElement(entry);
                        log(entry.toString(), Project.MSG_VERBOSE);
                    } else if ((index = line.indexOf(FILE_WAS_REMOVED)) != -1) {
                        // it is a removed file
                        String filename = line.substring(0, index);
                        String rev = null;
                        int indexrev = -1;
                        if ((indexrev = line.indexOf(REVISION, index)) != -1) {
                            rev = line.substring(indexrev + REVISION.length());
                        }
                        entry = new CvsTagEntry(filename, null, rev);
                        entries.addElement(entry);
                        log(entry.toString(), Project.MSG_VERBOSE);
                    }
                }
                line = reader.readLine();
            }

            CvsTagEntry[] array = new CvsTagEntry[entries.size()];
            entries.copyInto(array);

            return array;
        } catch (IOException e) {
            throw new BuildException("Error in parsing", e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    log(e.toString(), Project.MSG_ERR);
                }
            }
        }
    
public voidsetDestFile(java.io.File f)
Set the output file for the diff.

param
f the output file for the diff.

        mydestfile = f;
    
public voidsetEndDate(java.lang.String s)
Set the end date.

param
s the end date.

        myendDate = s;
    
public voidsetEndTag(java.lang.String s)
Set the end tag.

param
s the end tag.

        myendTag = s;
    
public voidsetPackage(java.lang.String p)
The package/module to analyze.

param
p the name of the package to analyse


                      
        
        mypackage = p;
    
public voidsetStartDate(java.lang.String s)
Set the start date.

param
s the start date.

        mystartDate = s;
    
public voidsetStartTag(java.lang.String s)
Set the start tag.

param
s the start tag.

        mystartTag = s;
    
private voidvalidate()
Validate the parameters specified for task.

exception
BuildException if a parameter is not correctly set

        if (null == mypackage) {
            throw new BuildException("Package/module must be set.");
        }

        if (null == mydestfile) {
            throw new BuildException("Destfile must be set.");
        }

        if (null == mystartTag && null == mystartDate) {
            throw new BuildException("Start tag or start date must be set.");
        }

        if (null != mystartTag && null != mystartDate) {
            throw new BuildException("Only one of start tag and start date "
                                     + "must be set.");
        }

        if (null == myendTag && null == myendDate) {
            throw new BuildException("End tag or end date must be set.");
        }

        if (null != myendTag && null != myendDate) {
            throw new BuildException("Only one of end tag and end date must "
                                     + "be set.");
        }
    
private voidwriteTagDiff(CvsTagEntry[] entries)
Write the rdiff log.

param
entries a CvsTagEntry[] value
exception
BuildException if an error occurs

        FileOutputStream output = null;
        try {
            output = new FileOutputStream(mydestfile);
            PrintWriter writer = new PrintWriter(
                                     new OutputStreamWriter(output, "UTF-8"));
            writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            Document doc = DOMUtils.newDocument();
            Element root = doc.createElement("tagdiff");
            if (mystartTag != null) {
                root.setAttribute("startTag", mystartTag);
            } else {
                root.setAttribute("startDate", mystartDate);
            }
            if (myendTag != null) {
                root.setAttribute("endTag", myendTag);
            } else {
                root.setAttribute("endDate", myendDate);
            }

            root.setAttribute("cvsroot", getCvsRoot());
            root.setAttribute("package", mypackage);
            DOM_WRITER.openElement(root, writer, 0, "\t");
            writer.println();
            for (int i = 0, c = entries.length; i < c; i++) {
                writeTagEntry(doc, writer, entries[i]);
            }
            DOM_WRITER.closeElement(root, writer, 0, "\t", true);
            writer.flush();
            writer.close();
        } catch (UnsupportedEncodingException uee) {
            log(uee.toString(), Project.MSG_ERR);
        } catch (IOException ioe) {
            throw new BuildException(ioe.toString(), ioe);
        } finally {
            if (null != output) {
                try {
                    output.close();
                } catch (IOException ioe) {
                    log(ioe.toString(), Project.MSG_ERR);
                }
            }
        }
    
private voidwriteTagEntry(org.w3c.dom.Document doc, java.io.PrintWriter writer, CvsTagEntry entry)
Write a single entry to the given writer.

param
doc Document used to create elements.
param
writer a PrintWriter value
param
entry a CvsTagEntry value

        Element ent = doc.createElement("entry");
        Element f = DOMUtils.createChildElement(ent, "file");
        DOMUtils.appendCDATAElement(f, "name", entry.getFile());
        if (entry.getRevision() != null) {
            DOMUtils.appendTextElement(f, "revision", entry.getRevision());
        }
        if (entry.getPreviousRevision() != null) {
            DOMUtils.appendTextElement(f, "prevrevision",
                                       entry.getPreviousRevision());
        }
        DOM_WRITER.write(ent, writer, 1, "\t");