home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / phing / tasks / system / MoveTask.php < prev    next >
Encoding:
PHP Script  |  2007-08-14  |  8.6 KB  |  248 lines

  1. <?php
  2. /*
  3.  *  $Id: MoveTask.php 217 2007-08-14 15:39:59Z mrook $
  4.  *
  5.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9.  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16.  *
  17.  * This software consists of voluntary contributions made by many individuals
  18.  * and is licensed under the LGPL. For more information please see
  19.  * <http://phing.info>.
  20.  */
  21.  
  22. require_once 'phing/tasks/system/CopyTask.php';
  23. include_once 'phing/system/io/PhingFile.php';
  24. include_once 'phing/system/io/IOException.php';
  25.  
  26. /**
  27.  * Moves a file or directory to a new file or directory.
  28.  * 
  29.  * By default, the destination file is overwritten if it
  30.  * already exists.  When overwrite is turned off, then files
  31.  * are only moved if the source file is newer than the
  32.  * destination file, or when the destination file does not
  33.  * exist.
  34.  *
  35.  * Source files and directories are only deleted when the file or
  36.  * directory has been copied to the destination successfully.
  37.  *
  38.  * @version $Revision: 1.8 $
  39.  * @package phing.tasks.system
  40.  */
  41. class MoveTask extends CopyTask {
  42.  
  43.     function __construct() {
  44.         parent::__construct();
  45.         $this->forceOverwrite = true;
  46.     }
  47.     
  48.     /**
  49.      * Validates attributes coming in from XML
  50.      *
  51.      * @access  private
  52.      * @return  void
  53.      * @throws  BuildException
  54.      */
  55.     protected function validateAttributes() {    
  56.         if ($this->file !== null && $this->file->isDirectory()) {
  57.             if (($this->destFile !== null && $this->destDir !== null)
  58.                 || ($this->destFile === null && $this->destDir === null)) {
  59.                     throw new BuildException("One and only one of tofile and todir must be set.");
  60.             }
  61.             
  62.             if ($this->destFile === null)
  63.             {
  64.                 $this->destFile = new PhingFile($this->destDir, $this->file->getName());
  65.             }
  66.             
  67.             if ($this->destDir === null)
  68.             {
  69.                 $this->destDir = $this->destFile->getParentFile();
  70.             }
  71.             
  72.             $this->completeDirMap[$this->file->getAbsolutePath()] = $this->destFile->getAbsolutePath();
  73.             
  74.             $this->file = null;
  75.         } else {
  76.             parent::validateAttributes();
  77.         }
  78.     }
  79.     
  80.     protected function doWork() {
  81.         if (count($this->completeDirMap) > 0)
  82.         {
  83.             foreach ($this->completeDirMap as $from => $to)
  84.             {
  85.                 $f = new PhingFile($from);
  86.                 $d = new PhingFile($to);
  87.                 
  88.                 $moved = false;
  89.                 try { // try to rename                    
  90.                     $this->log("Attempting to rename $from to $to", $this->verbosity);
  91.                     $this->renameFile($f, $d, $this->forceOverwrite);
  92.                     $moved = true;
  93.                 } catch (IOException $ioe) {
  94.                     $moved = false;
  95.                     $this->log("Failed to rename $from to $to: " . $ioe->getMessage(), $this->verbosity);
  96.                 }
  97.             }
  98.         }
  99.     
  100.         $copyMapSize = count($this->fileCopyMap);
  101.         if ($copyMapSize > 0) {
  102.             // files to move
  103.             $this->log("Moving $copyMapSize files to " . $this->destDir->getAbsolutePath());
  104.  
  105.             foreach($this->fileCopyMap as $from => $to) {
  106.                 if ($from == $to) {
  107.                     $this->log("Skipping self-move of $from", $this->verbosity);
  108.                     continue;
  109.                 }
  110.  
  111.                 $moved = false;
  112.                 $f = new PhingFile($from);
  113.                 $d = new PhingFile($to);
  114.                 
  115.                 $moved = false;
  116.                 try { // try to rename                    
  117.                     $this->log("Attempting to rename $from to $to", $this->verbosity);
  118.                     $this->renameFile($f, $d, $this->forceOverwrite);
  119.                     $moved = true;
  120.                 } catch (IOException $ioe) {
  121.                     $moved = false;
  122.                     $this->log("Failed to rename $from to $to: " . $ioe->getMessage(), $this->verbosity);
  123.                 }
  124.  
  125.                 if (!$moved) {                    
  126.                     try { // try to move
  127.                         $this->log("Moving $from to $to", $this->verbosity);
  128.  
  129.                         $this->fileUtils->copyFile($f, $d, $this->forceOverwrite, $this->preserveLMT, $this->filterChains, $this->getProject());                        
  130.  
  131.                         $f = new PhingFile($fromFile);
  132.                         $f->delete();
  133.                     } catch (IOException $ioe) {
  134.                         $msg = "Failed to move $from to $to: " . $ioe->getMessage();
  135.                         throw new BuildException($msg, $this->location);
  136.                     }
  137.                 } // if !moved
  138.             } // foreach fileCopyMap
  139.         } // if copyMapSize
  140.  
  141.         // handle empty dirs if appropriate
  142.         if ($this->includeEmpty) {
  143.             $e = array_keys($this->dirCopyMap);
  144.             $count = 0;
  145.             foreach ($e as $dir) {
  146.                 $d = new PhingFile((string) $dir);
  147.                 if (!$d->exists()) {
  148.                     if (!$d->mkdirs()) {
  149.                         $this->log("Unable to create directory " . $d->getAbsolutePath(), Project::MSG_ERR);
  150.                     } else {
  151.                         $count++;
  152.                     }
  153.                 }
  154.             }
  155.             if ($count > 0) {
  156.                 $this->log("moved $count empty director" . ($count == 1 ? "y" : "ies") . " to " . $this->destDir->getAbsolutePath());
  157.             }
  158.         }
  159.  
  160.         if (count($this->filesets) > 0) {
  161.             // process filesets
  162.             foreach($this->filesets as $fs) {
  163.                 $dir = $fs->getDir($this->project);
  164.                 if ($this->okToDelete($dir)) {
  165.                     $this->deleteDir($dir);
  166.                 }
  167.             }
  168.         }
  169.     }
  170.  
  171.     /** Its only ok to delete a dir tree if there are no files in it. */
  172.     private function okToDelete($d) {
  173.         $list = $d->listDir();
  174.         if ($list === null) {
  175.             return false;     // maybe io error?
  176.         }
  177.         
  178.         foreach($list as $s) {
  179.             $f = new PhingFile($d, $s);
  180.             if ($f->isDirectory()) {
  181.                 if (!$this->okToDelete($f)) {
  182.                     return false;
  183.                 }
  184.             } else {
  185.                 // found a file
  186.                 return false;
  187.             }
  188.         }
  189.         return true;
  190.     }
  191.  
  192.     /** Go and delete the directory tree. */
  193.     private function deleteDir($d) {
  194.     
  195.         $list = $d->listDir();
  196.         if ($list === null) {
  197.             return;      // on an io error list() can return null
  198.         }
  199.         
  200.         foreach($list as $fname) {
  201.             $f = new PhingFile($d, $fname);
  202.             if ($f->isDirectory()) {
  203.                 $this->deleteDir($f);
  204.             } else {
  205.                 throw new BuildException("UNEXPECTED ERROR - The file " . $f->getAbsolutePath() . " should not exist!");
  206.             }
  207.         }
  208.  
  209.         $this->log("Deleting directory " . $d->getPath(), $this->verbosity);
  210.         try {
  211.             $d->delete();
  212.         } catch (Exception $e) {
  213.             throw new BuildException("Unable to delete directory " . $d->__toString() . ": " . $e->getMessage());
  214.         }
  215.     }
  216.  
  217.     /**
  218.      * Attempts to rename a file from a source to a destination.
  219.      * If overwrite is set to true, this method overwrites existing file
  220.      * even if the destination file is newer.
  221.      * Otherwise, the source f
  222.      * ile is renamed only if the destination file #
  223.      * is older than it.
  224.      */
  225.     private function renameFile(PhingFile $sourceFile, PhingFile $destFile, $overwrite) {
  226.         $renamed = true;
  227.  
  228.         // ensure that parent dir of dest file exists!
  229.         $parent = $destFile->getParentFile();
  230.         if ($parent !== null) {
  231.             if (!$parent->exists()) {
  232.                 $parent->mkdirs();
  233.             }
  234.         }
  235.         if ($destFile->exists()) {
  236.             try {
  237.                 $destFile->delete();
  238.             } catch (Exception $e) {
  239.                 throw new BuildException("Unable to remove existing file " . $destFile->__toString() . ": " . $e->getMessage());
  240.             }
  241.         }
  242.         $renamed = $sourceFile->renameTo($destFile);
  243.  
  244.         return $renamed;
  245.     }
  246. }
  247. ?>
  248.