Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 327   Methods: 5
NCLOC: 197   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
Move.java 25% 37% 60% 33.1%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2000-2003 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   
 
 55   
 package org.apache.tools.ant.taskdefs;
 56   
 
 57   
 import java.io.File;
 58   
 import java.io.IOException;
 59   
 import java.util.Enumeration;
 60   
 import org.apache.tools.ant.BuildException;
 61   
 import org.apache.tools.ant.Project;
 62   
 import org.apache.tools.ant.types.FileSet;
 63   
 import org.apache.tools.ant.types.FilterSet;
 64   
 import org.apache.tools.ant.types.FilterSetCollection;
 65   
 
 66   
 /**
 67   
  * Moves a file or directory to a new file or directory.
 68   
  * By default, the
 69   
  * destination file is overwritten if it already exists.
 70   
  * When <i>overwrite</i> is
 71   
  * turned off, then files are only moved if the source file is
 72   
  * newer than the destination file, or when the destination file does
 73   
  * not exist.
 74   
  *
 75   
  * <p>Source files and directories are only deleted when the file or
 76   
  * directory has been copied to the destination successfully.  Filtering
 77   
  * also works.</p>
 78   
  *
 79   
  * <p>This implementation is based on Arnout Kuiper's initial design
 80   
  * document, the following mailing list discussions, and the
 81   
  * copyfile/copydir tasks.</p>
 82   
  *
 83   
  * @author Glenn McAllister
 84   
  *         <a href="mailto:glennm@ca.ibm.com">glennm@ca.ibm.com</a>
 85   
  * @author Magesh Umasankar
 86   
  * @version $Revision: 1.33 $
 87   
  *
 88   
  * @since Ant 1.2
 89   
  *
 90   
  * @ant.task category="filesystem"
 91   
  */
 92   
 public class Move extends Copy {
 93   
 
 94  2
     public Move() {
 95  2
         super();
 96  2
         forceOverwrite = true;
 97   
     }
 98   
 
 99   
 //************************************************************************
 100   
 //  protected and private methods
 101   
 //************************************************************************
 102   
 
 103  2
     protected void doFileOperations() {
 104   
         //Attempt complete directory renames, if any, first.
 105  2
         if (completeDirMap.size() > 0) {
 106  0
             Enumeration e = completeDirMap.keys();
 107  0
             while (e.hasMoreElements()) {
 108  0
                 File fromDir = (File) e.nextElement();
 109  0
                 File toDir = (File) completeDirMap.get(fromDir);
 110  0
                 try {
 111  0
                     log("Attempting to rename dir: " + fromDir +
 112   
                         " to " + toDir, verbosity);
 113  0
                     renameFile(fromDir, toDir, filtering, forceOverwrite);
 114   
                 } catch (IOException ioe) {
 115  0
                     String msg = "Failed to rename dir " + fromDir
 116   
                         + " to " + toDir
 117   
                         + " due to " + ioe.getMessage();
 118  0
                     throw new BuildException(msg, ioe, getLocation());
 119   
                 }
 120   
             }
 121   
         }
 122  2
         if (fileCopyMap.size() > 0) {   // files to move
 123  2
             log("Moving " + fileCopyMap.size() + " files to " +
 124   
                 destDir.getAbsolutePath());
 125   
 
 126  2
             Enumeration e = fileCopyMap.keys();
 127  2
             while (e.hasMoreElements()) {
 128  2
                 String fromFile = (String) e.nextElement();
 129  2
                 String toFile = (String) fileCopyMap.get(fromFile);
 130   
 
 131  2
                 if (fromFile.equals(toFile)) {
 132  0
                     log("Skipping self-move of " + fromFile, verbosity);
 133  0
                     continue;
 134   
                 }
 135   
 
 136  2
                 boolean moved = false;
 137  2
                 File f = new File(fromFile);
 138   
 
 139  2
                 if (f.exists()) { //Is this file still available to be moved?
 140  2
                     File d = new File(toFile);
 141   
 
 142  2
                     try {
 143  2
                         log("Attempting to rename: " + fromFile +
 144   
                             " to " + toFile, verbosity);
 145  2
                         moved = renameFile(f, d, filtering, forceOverwrite);
 146   
                     } catch (IOException ioe) {
 147  0
                         String msg = "Failed to rename " + fromFile
 148   
                             + " to " + toFile
 149   
                             + " due to " + ioe.getMessage();
 150  0
                         throw new BuildException(msg, ioe, getLocation());
 151   
                     }
 152   
 
 153  2
                     if (!moved) {
 154  2
                         try {
 155  2
                             log("Moving " + fromFile + " to " + toFile,
 156   
                                 verbosity);
 157   
 
 158  2
                             FilterSetCollection executionFilters =
 159   
                                 new FilterSetCollection();
 160  2
                             if (filtering) {
 161  0
                                 executionFilters
 162   
                                     .addFilterSet(getProject().getGlobalFilterSet());
 163   
                             }
 164  2
                             for (Enumeration filterEnum =
 165   
                                      getFilterSets().elements();
 166  3
                                  filterEnum.hasMoreElements();) {
 167  1
                                 executionFilters
 168   
                                     .addFilterSet((FilterSet) filterEnum
 169   
                                                   .nextElement());
 170   
                             }
 171  2
                             getFileUtils().copyFile(f, d, executionFilters,
 172   
                                                     getFilterChains(),
 173   
                                                     forceOverwrite,
 174   
                                                     getPreserveLastModified(),
 175   
                                                     getEncoding(), 
 176   
                                                     getOutputEncoding(),
 177   
                                                     getProject());
 178   
 
 179  2
                             f = new File(fromFile);
 180  2
                             if (!f.delete()) {
 181  0
                                 throw new BuildException("Unable to delete "
 182   
                                                          + "file "
 183   
                                                          + f.getAbsolutePath());
 184   
                             }
 185   
                         } catch (IOException ioe) {
 186  0
                             String msg = "Failed to copy " + fromFile + " to "
 187   
                                 + toFile
 188   
                                 + " due to " + ioe.getMessage();
 189  0
                             throw new BuildException(msg, ioe, getLocation());
 190   
                         }
 191   
                     }
 192   
                 }
 193   
             }
 194   
         }
 195   
 
 196  2
         if (includeEmpty) {
 197  2
             Enumeration e = dirCopyMap.elements();
 198  2
             int count = 0;
 199  2
             while (e.hasMoreElements()) {
 200  0
                 File d = new File((String) e.nextElement());
 201  0
                 if (!d.exists()) {
 202  0
                     if (!d.mkdirs()) {
 203  0
                         log("Unable to create directory "
 204   
                             + d.getAbsolutePath(), Project.MSG_ERR);
 205   
                     } else {
 206  0
                         count++;
 207   
                     }
 208   
                 }
 209   
             }
 210   
 
 211  2
             if (count > 0) {
 212  0
                 log("Moved " + count + " empty directories to "
 213   
                     + destDir.getAbsolutePath());
 214   
             }
 215   
         }
 216   
 
 217  2
         if (filesets.size() > 0) {
 218  0
             Enumeration e = filesets.elements();
 219  0
             while (e.hasMoreElements()) {
 220  0
                 FileSet fs = (FileSet) e.nextElement();
 221  0
                 File dir = fs.getDir(getProject());
 222   
 
 223  0
                 if (okToDelete(dir)) {
 224  0
                     deleteDir(dir);
 225   
                 }
 226   
             }
 227   
         }
 228   
     }
 229   
 
 230   
     /**
 231   
      * Its only ok to delete a directory tree if there are
 232   
      * no files in it.
 233   
      * @return true if a deletion can go ahead
 234   
      */
 235  0
     protected boolean okToDelete(File d) {
 236  0
         String[] list = d.list();
 237  0
         if (list == null) {
 238  0
             return false;
 239   
         }     // maybe io error?
 240   
 
 241  0
         for (int i = 0; i < list.length; i++) {
 242  0
             String s = list[i];
 243  0
             File f = new File(d, s);
 244  0
             if (f.isDirectory()) {
 245  0
                 if (!okToDelete(f)) {
 246  0
                     return false;
 247   
                 }
 248   
             } else {
 249  0
                 return false;   // found a file
 250   
             }
 251   
         }
 252   
 
 253  0
         return true;
 254   
     }
 255   
 
 256   
     /**
 257   
      * Go and delete the directory tree.
 258   
      */
 259  0
     protected void deleteDir(File d) {
 260  0
         String[] list = d.list();
 261  0
         if (list == null) {
 262  0
             return;
 263   
         }      // on an io error list() can return null
 264   
 
 265  0
         for (int i = 0; i < list.length; i++) {
 266  0
             String s = list[i];
 267  0
             File f = new File(d, s);
 268  0
             if (f.isDirectory()) {
 269  0
                 deleteDir(f);
 270   
             } else {
 271  0
                 throw new BuildException("UNEXPECTED ERROR - The file "
 272   
                                          + f.getAbsolutePath()
 273   
                                          + " should not exist!");
 274   
             }
 275   
         }
 276  0
         log("Deleting directory " + d.getAbsolutePath(), verbosity);
 277  0
         if (!d.delete()) {
 278  0
             throw new BuildException("Unable to delete directory "
 279   
                                      + d.getAbsolutePath());
 280   
         }
 281   
     }
 282   
 
 283   
     /**
 284   
      * Attempts to rename a file from a source to a destination.
 285   
      * If overwrite is set to true, this method overwrites existing file
 286   
      * even if the destination file is newer.  Otherwise, the source file is
 287   
      * renamed only if the destination file is older than it.
 288   
      * Method then checks if token filtering is used.  If it is, this method
 289   
      * returns false assuming it is the responsibility to the copyFile method.
 290   
      *
 291   
      * @throws IOException
 292   
      */
 293  2
     protected boolean renameFile(File sourceFile, File destFile,
 294   
                                  boolean filtering, boolean overwrite)
 295   
         throws IOException, BuildException {
 296   
 
 297  2
         boolean renamed = true;
 298  2
         if ((getFilterSets() != null && getFilterSets().size() > 0) ||
 299   
             (getFilterChains() != null && getFilterChains().size() > 0)) {
 300  2
             renamed = false;
 301   
         } else {
 302  0
             if (!filtering) {
 303   
                 // ensure that parent dir of dest file exists!
 304   
                 // not using getParentFile method to stay 1.1 compat
 305  0
                 String parentPath = destFile.getParent();
 306  0
                 if (parentPath != null) {
 307  0
                     File parent = new File(parentPath);
 308  0
                     if (!parent.exists()) {
 309  0
                         parent.mkdirs();
 310   
                     }
 311   
                 }
 312   
 
 313  0
                 if (destFile.exists() && destFile.isFile()) {
 314  0
                     if (!destFile.delete()) {
 315  0
                         throw new BuildException("Unable to remove existing "
 316   
                                                  + "file " + destFile);
 317   
                     }
 318   
                 }
 319  0
                 renamed = sourceFile.renameTo(destFile);
 320   
             } else {
 321  0
                 renamed = false;
 322   
             }
 323   
         }
 324  2
         return renamed;
 325   
     }
 326   
 }
 327