Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 429   Methods: 11
NCLOC: 188   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
CvsTagDiff.java 0% 0% 0% 0%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2002 The Apache Software Foundation.  All rights
 5   
  * reserved.
 6   
  *
 7   
  * Redistribution and use in source and binary forms, with or without
 8   
  * modification, are permitted provided that the following conditions
 9   
  * are met:
 10   
  *
 11   
  * 1. Redistributions of source code must retain the above copyright
 12   
  *    notice, this list of conditions and the following disclaimer.
 13   
  *
 14   
  * 2. Redistributions in binary form must reproduce the above copyright
 15   
  *    notice, this list of conditions and the following disclaimer in
 16   
  *    the documentation and/or other materials provided with the
 17   
  *    distribution.
 18   
  *
 19   
  * 3. The end-user documentation included with the redistribution, if
 20   
  *    any, must include the following acknowlegement:
 21   
  *       "This product includes software developed by the
 22   
  *        Apache Software Foundation (http://www.apache.org/)."
 23   
  *    Alternately, this acknowlegement may appear in the software itself,
 24   
  *    if and wherever such third-party acknowlegements normally appear.
 25   
  *
 26   
  * 4. The names "Ant" and "Apache Software
 27   
  *    Foundation" must not be used to endorse or promote products derived
 28   
  *    from this software without prior written permission. For written
 29   
  *    permission, please contact apache@apache.org.
 30   
  *
 31   
  * 5. Products derived from this software may not be called "Apache"
 32   
  *    nor may "Apache" appear in their names without prior written
 33   
  *    permission of the Apache Group.
 34   
  *
 35   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 36   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 37   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 39   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 41   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 42   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 43   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 44   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 45   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46   
  * SUCH DAMAGE.
 47   
  * ====================================================================
 48   
  *
 49   
  * This software consists of voluntary contributions made by many
 50   
  * individuals on behalf of the Apache Software Foundation.  For more
 51   
  * information on the Apache Software Foundation, please see
 52   
  * <http://www.apache.org/>.
 53   
  */
 54   
 package org.apache.tools.ant.taskdefs.cvslib;
 55   
 
 56   
 import java.io.BufferedReader;
 57   
 import java.io.File;
 58   
 import java.io.FileOutputStream;
 59   
 import java.io.FileReader;
 60   
 import java.io.IOException;
 61   
 import java.io.OutputStreamWriter;
 62   
 import java.io.PrintWriter;
 63   
 import java.io.UnsupportedEncodingException;
 64   
 import java.util.Vector;
 65   
 import org.apache.tools.ant.BuildException;
 66   
 import org.apache.tools.ant.Project;
 67   
 import org.apache.tools.ant.taskdefs.AbstractCvsTask;
 68   
 import org.apache.tools.ant.util.FileUtils;
 69   
 
 70   
 /**
 71   
  * Examines the output of cvs rdiff between two tags.
 72   
  *
 73   
  * It produces an XML output representing the list of changes.
 74   
  * <PRE>
 75   
  * &lt;!-- Root element --&gt;
 76   
  * &lt;!ELEMENT tagdiff ( entry+ ) &gt;
 77   
  * &lt;!-- Start tag of the report --&gt;
 78   
  * &lt;!ATTLIST tagdiff startTag NMTOKEN #IMPLIED &gt;
 79   
  * &lt;!-- End tag of the report --&gt;
 80   
  * &lt;!ATTLIST tagdiff endTag NMTOKEN #IMPLIED &gt;
 81   
  * &lt;!-- Start date of the report --&gt;
 82   
  * &lt;!ATTLIST tagdiff startDate NMTOKEN #IMPLIED &gt;
 83   
  * &lt;!-- End date of the report --&gt;
 84   
  * &lt;!ATTLIST tagdiff endDate NMTOKEN #IMPLIED &gt;
 85   
  *
 86   
  * &lt;!-- CVS tag entry --&gt;
 87   
  * &lt;!ELEMENT entry ( file ) &gt;
 88   
  * &lt;!-- File added, changed or removed --&gt;
 89   
  * &lt;!ELEMENT file ( name, revision?, prevrevision? ) &gt;
 90   
  * &lt;!-- Name of the file --&gt;
 91   
  * &lt;!ELEMENT name ( #PCDATA ) &gt;
 92   
  * &lt;!-- Revision number --&gt;
 93   
  * &lt;!ELEMENT revision ( #PCDATA ) &gt;
 94   
  * &lt;!-- Previous revision number --&gt;
 95   
  * &lt;!ELEMENT prevrevision ( #PCDATA ) &gt;
 96   
  * </PRE>
 97   
  *
 98   
  * @author <a href="mailto:fred@castify.net">Frederic Lavigne</a>
 99   
  * @author <a href="mailto:rvanoo@xs4all.nl">Rob van Oostrum</a>
 100   
  * @version $Revision: 1.12 $ $Date: 2003/02/10 14:13:43 $
 101   
  * @since Ant 1.5
 102   
  * @ant.task name="cvstagdiff"
 103   
  */
 104   
 public class CvsTagDiff extends AbstractCvsTask {
 105   
 
 106   
     /**
 107   
      * Token to identify a new file in the rdiff log
 108   
      */
 109   
     static final String FILE_IS_NEW = " is new; current revision ";
 110   
 
 111   
     /**
 112   
      * Token to identify a modified file in the rdiff log
 113   
      */
 114   
     static final String FILE_HAS_CHANGED = " changed from revision ";
 115   
 
 116   
     /**
 117   
      * Token to identify a removed file in the rdiff log
 118   
      */
 119   
     static final String FILE_WAS_REMOVED = " is removed";
 120   
 
 121   
     /**
 122   
      * The cvs package/module to analyse
 123   
      */
 124   
     private String m_package;
 125   
 
 126   
     /**
 127   
      * The earliest tag from which diffs are to be included in the report.
 128   
      */
 129   
     private String m_startTag;
 130   
 
 131   
     /**
 132   
      * The latest tag from which diffs are to be included in the report.
 133   
      */
 134   
     private String m_endTag;
 135   
 
 136   
     /**
 137   
      * The earliest date from which diffs are to be included in the report.
 138   
      */
 139   
     private String m_startDate;
 140   
 
 141   
     /**
 142   
      * The latest date from which diffs are to be included in the report.
 143   
      */
 144   
     private String m_endDate;
 145   
 
 146   
     /**
 147   
      * The file in which to write the diff report.
 148   
      */
 149   
     private File m_destfile;
 150   
 
 151   
     /**
 152   
      * Used to create the temp file for cvs log
 153   
      */
 154   
     private FileUtils m_fileUtils = FileUtils.newFileUtils();
 155   
 
 156   
     /**
 157   
      * The package/module to analyze.
 158   
      */
 159  0
     public void setPackage(String p) {
 160  0
         m_package = p;
 161   
     }
 162   
 
 163   
     /**
 164   
      * Set the start tag.
 165   
      *
 166   
      * @param s the start tag.
 167   
      */
 168  0
     public void setStartTag(String s) {
 169  0
         m_startTag = s;
 170   
     }
 171   
 
 172   
     /**
 173   
      * Set the start date.
 174   
      *
 175   
      * @param s the start date.
 176   
      */
 177  0
     public void setStartDate(String s) {
 178  0
         m_startDate = s;
 179   
     }
 180   
 
 181   
     /**
 182   
      * Set the end tag.
 183   
      *
 184   
      * @param s the end tag.
 185   
      */
 186  0
     public void setEndTag(String s) {
 187  0
         m_endTag = s;
 188   
     }
 189   
 
 190   
     /**
 191   
      * Set the end date.
 192   
      *
 193   
      * @param s the end date.
 194   
      */
 195  0
     public void setEndDate(String s) {
 196  0
         m_endDate = s;
 197   
     }
 198   
 
 199   
     /**
 200   
      * Set the output file for the diff.
 201   
      *
 202   
      * @param f the output file for the diff.
 203   
      */
 204  0
     public void setDestFile(File f) {
 205  0
         m_destfile = f;
 206   
     }
 207   
 
 208   
     /**
 209   
      * Execute task.
 210   
      *
 211   
      * @exception BuildException if an error occurs
 212   
      */
 213  0
     public void execute() throws BuildException {
 214   
         // validate the input parameters
 215  0
         validate();
 216   
 
 217   
         // build the rdiff command
 218  0
         String rdiff = "rdiff -s " +
 219   
             (m_startTag != null ? ("-r " + m_startTag) : ("-D " + m_startDate))
 220   
             + " "
 221   
             + (m_endTag != null ? ("-r " + m_endTag) : ("-D " + m_endDate))
 222   
             + " " + m_package;
 223  0
         log("Cvs command is " + rdiff, Project.MSG_VERBOSE);
 224  0
         setCommand(rdiff);
 225   
 
 226  0
         File tmpFile = null;
 227  0
         try {
 228  0
             tmpFile = m_fileUtils.createTempFile("cvstagdiff", ".log", null);
 229  0
             setOutput(tmpFile);
 230   
 
 231   
             // run the cvs command
 232  0
             super.execute();
 233   
 
 234   
             // parse the rdiff
 235  0
             CvsTagEntry[] entries = parseRDiff(tmpFile);
 236   
 
 237   
             // write the tag diff
 238  0
             writeTagDiff(entries);
 239   
 
 240   
         } finally {
 241  0
             if (tmpFile != null) {
 242  0
                 tmpFile.delete();
 243   
             }
 244   
         }
 245   
     }
 246   
 
 247   
     /**
 248   
      * Parse the tmpFile and return and array of CvsTagEntry to be
 249   
      * written in the output.
 250   
      *
 251   
      * @param tmpFile the File containing the output of the cvs rdiff command
 252   
      * @return the entries in the output
 253   
      * @exception BuildException if an error occurs
 254   
      */
 255  0
     private CvsTagEntry[] parseRDiff(File tmpFile) throws BuildException {
 256   
         // parse the output of the command
 257  0
         BufferedReader reader = null;
 258   
 
 259  0
         try {
 260  0
             reader = new BufferedReader(new FileReader(tmpFile));
 261   
 
 262   
             // entries are of the form:
 263   
             // File module/filename is new; current revision 1.1
 264   
             // or
 265   
             // File module/filename changed from revision 1.4 to 1.6
 266   
             // or
 267   
             // File module/filename is removed; not included in
 268   
             // release tag SKINLF_12
 269   
 
 270   
             // get rid of 'File module/"
 271  0
             int headerLength = 5 + m_package.length() + 1;
 272  0
             Vector entries = new Vector();
 273   
 
 274  0
             String line = reader.readLine();
 275  0
             int index;
 276  0
             CvsTagEntry entry = null;
 277   
 
 278  0
             while (null != line) {
 279  0
                 line = line.substring(headerLength);
 280   
 
 281  0
                 if ((index = line.indexOf(FILE_IS_NEW)) != -1) {
 282   
                     // it is a new file
 283   
                     // set the revision but not the prevrevision
 284  0
                     String filename = line.substring(0, index);
 285  0
                     String rev = line.substring(index + FILE_IS_NEW.length());
 286   
 
 287  0
                     entries.addElement(entry = new CvsTagEntry(filename, rev));
 288  0
                     log(entry.toString(), Project.MSG_VERBOSE);
 289  0
                 } else if ((index = line.indexOf(FILE_HAS_CHANGED)) != -1) {
 290   
                     // it is a modified file
 291   
                     // set the revision and the prevrevision
 292  0
                     String filename = line.substring(0, index);
 293  0
                     int revSeparator = line.indexOf(" to ", index);
 294  0
                     String prevRevision =
 295   
                         line.substring(index + FILE_HAS_CHANGED.length(),
 296   
                                        revSeparator);
 297   
                      // 4 is " to " length
 298  0
                     String revision = line.substring(revSeparator + 4);
 299   
 
 300  0
                     entries.addElement(entry = new CvsTagEntry(filename,
 301   
                                                                revision,
 302   
                                                                prevRevision));
 303  0
                     log(entry.toString(), Project.MSG_VERBOSE);
 304  0
                 } else if ((index = line.indexOf(FILE_WAS_REMOVED)) != -1) {
 305   
                     // it is a removed file
 306  0
                     String filename = line.substring(0, index);
 307   
 
 308  0
                     entries.addElement(entry = new CvsTagEntry(filename));
 309  0
                     log(entry.toString(), Project.MSG_VERBOSE);
 310   
                 }
 311  0
                 line = reader.readLine();
 312   
             }
 313   
 
 314  0
             CvsTagEntry[] array = new CvsTagEntry[entries.size()];
 315  0
             entries.copyInto(array);
 316   
 
 317  0
             return array;
 318   
         } catch (IOException e) {
 319  0
             throw new BuildException("Error in parsing", e);
 320   
         } finally {
 321  0
             if (reader != null) {
 322  0
                 try {
 323  0
                     reader.close();
 324   
                 } catch (IOException e) {
 325   
                 }
 326   
             }
 327   
         }
 328   
     }
 329   
 
 330   
     /**
 331   
      * Write the rdiff log.
 332   
      *
 333   
      * @param entries a <code>CvsTagEntry[]</code> value
 334   
      * @exception BuildException if an error occurs
 335   
      */
 336  0
     private void writeTagDiff(CvsTagEntry[] entries) throws BuildException {
 337  0
         FileOutputStream output = null;
 338  0
         try {
 339  0
             output = new FileOutputStream(m_destfile);
 340  0
             PrintWriter writer = new PrintWriter(
 341   
                                      new OutputStreamWriter(output, "UTF-8"));
 342  0
             writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
 343  0
             writer.print("<tagdiff ");
 344  0
             if (m_startTag != null) {
 345  0
                 writer.print("startTag=\"" + m_startTag + "\" ");
 346   
             } else {
 347  0
                 writer.print("startDate=\"" + m_startDate + "\" ");
 348   
             }
 349  0
             if (m_endTag != null) {
 350  0
                 writer.print("endTag=\"" + m_endTag + "\" ");
 351   
             } else {
 352  0
                 writer.print("endDate=\"" + m_endDate + "\" ");
 353   
             }
 354  0
             writer.println(">");
 355  0
             for (int i = 0, c = entries.length; i < c; i++) {
 356  0
                 writeTagEntry(writer, entries[i]);
 357   
             }
 358  0
             writer.println("</tagdiff>");
 359  0
             writer.flush();
 360  0
             writer.close();
 361   
         } catch (UnsupportedEncodingException uee) {
 362  0
             log(uee.toString(), Project.MSG_ERR);
 363   
         } catch (IOException ioe) {
 364  0
             throw new BuildException(ioe.toString(), ioe);
 365   
         } finally {
 366  0
             if (null != output) {
 367  0
                 try {
 368  0
                     output.close();
 369   
                 } catch (IOException ioe) { }
 370   
             }
 371   
         }
 372   
     }
 373   
 
 374   
     /**
 375   
      * Write a single entry to the given writer.
 376   
      *
 377   
      * @param writer a <code>PrintWriter</code> value
 378   
      * @param entry a <code>CvsTagEntry</code> value
 379   
      */
 380  0
     private void writeTagEntry(PrintWriter writer, CvsTagEntry entry) {
 381  0
         writer.println("\t<entry>");
 382  0
         writer.println("\t\t<file>");
 383  0
         writer.println("\t\t\t<name>" + entry.getFile() + "</name>");
 384  0
         if (entry.getRevision() != null) {
 385  0
             writer.println("\t\t\t<revision>" + entry.getRevision()
 386   
                            + "</revision>");
 387   
         }
 388  0
         if (entry.getPreviousRevision() != null) {
 389  0
             writer.println("\t\t\t<prevrevision>"
 390   
                            + entry.getPreviousRevision() + "</prevrevision>");
 391   
         }
 392  0
         writer.println("\t\t</file>");
 393  0
         writer.println("\t</entry>");
 394   
     }
 395   
 
 396   
     /**
 397   
      * Validate the parameters specified for task.
 398   
      *
 399   
      * @exception BuildException if a parameter is not correctly set
 400   
      */
 401  0
     private void validate() throws BuildException {
 402  0
         if (null == m_package) {
 403  0
             throw new BuildException("Package/module must be set.");
 404   
         }
 405   
 
 406  0
         if (null == m_destfile) {
 407  0
             throw new BuildException("Destfile must be set.");
 408   
         }
 409   
 
 410  0
         if (null == m_startTag && null == m_startDate) {
 411  0
             throw new BuildException("Start tag or start date must be set.");
 412   
         }
 413   
 
 414  0
         if (null != m_startTag && null != m_startDate) {
 415  0
             throw new BuildException("Only one of start tag and start date "
 416   
                                      + "must be set.");
 417   
         }
 418   
 
 419  0
         if (null == m_endTag && null == m_endDate) {
 420  0
             throw new BuildException("End tag or end date must be set.");
 421   
         }
 422   
 
 423  0
         if (null != m_endTag && null != m_endDate) {
 424  0
             throw new BuildException("Only one of end tag and end date must "
 425   
                                      + "be set.");
 426   
         }
 427   
     }
 428   
 }
 429