[ Index ] |
|
Code source de Symfony 1.0.0 |
1 <?php 2 /* 3 * $Id: CopyTask.php 3076 2006-12-18 08:52:12Z fabien $ 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/Task.php'; 23 include_once 'phing/system/io/PhingFile.php'; 24 include_once 'phing/util/FileUtils.php'; 25 include_once 'phing/util/SourceFileScanner.php'; 26 include_once 'phing/mappers/IdentityMapper.php'; 27 include_once 'phing/mappers/FlattenMapper.php'; 28 29 /** 30 * A phing copy task. Copies a file or directory to a new file 31 * or directory. Files are only copied if the source file is newer 32 * than the destination file, or when the destination file does not 33 * exist. It is possible to explictly overwrite existing files. 34 * 35 * @author Andreas Aderhold, andi@binarycloud.com 36 * @version $Revision: 1.16 $ $Date: 2006-06-12 21:46:05 +0200 (Mon, 12 Jun 2006) $ 37 * @package phing.tasks.system 38 */ 39 class CopyTask extends Task { 40 41 protected $file = null; // the source file (from xml attribute) 42 protected $destFile = null; // the destiantion file (from xml attribute) 43 protected $destDir = null; // the destination dir (from xml attribute) 44 protected $overwrite = false; // overwrite destination (from xml attribute) 45 protected $preserveLMT = true; // sync timestamps (from xml attribute) 46 protected $includeEmpty = true; // include empty dirs? (from XML) 47 protected $flatten = false; // apply the FlattenMapper right way (from XML) 48 protected $mapperElement = null; 49 50 protected $fileCopyMap = array(); // asoc array containing mapped file names 51 protected $dirCopyMap = array(); // asoc array containing mapped file names 52 protected $fileUtils = null; // a instance of fileutils 53 protected $filesets = array(); // all fileset objects assigned to this task 54 protected $filterChains = array(); // all filterchains objects assigned to this task 55 56 protected $verbosity = PROJECT_MSG_VERBOSE; 57 58 /** 59 * Sets up this object internal stuff. i.e. the Fileutils instance 60 * 61 * @return object The CopyTask instnace 62 * @access public 63 */ 64 function __construct() { 65 $this->fileUtils = new FileUtils(); 66 } 67 68 /** 69 * Set the overwrite flag. IntrospectionHelper takes care of 70 * booleans in set* methods so we can assume that the right 71 * value (boolean primitive) is coming in here. 72 * 73 * @param boolean Overwrite the destination file(s) if it/they already exist 74 * @return void 75 * @access public 76 */ 77 function setOverwrite($bool) { 78 $this->overwrite = (boolean) $bool; 79 } 80 81 /** 82 * Used to force listing of all names of copied files. 83 * @param boolean $verbosity 84 */ 85 function setVerbose($verbosity) { 86 if ($verbosity) { 87 $this->verbosity = PROJECT_MSG_INFO; 88 } else { 89 $this->verbosity = PROJECT_MSG_VERBOSE; 90 } 91 } 92 93 /** 94 * Set the preserve timestmap flag. IntrospectionHelper takes care of 95 * booleans in set* methods so we can assume that the right 96 * value (boolean primitive) is coming in here. 97 * 98 * @param boolean Preserve the timestamp on the destination file 99 * @return void 100 * @access public 101 */ 102 function setTstamp($bool) { 103 $this->preserveLMT = (boolean) $bool; 104 } 105 106 107 /** 108 * Set the include empty dirs flag. IntrospectionHelper takes care of 109 * booleans in set* methods so we can assume that the right 110 * value (boolean primitive) is coming in here. 111 * 112 * @param boolean Flag if empty dirs should be cpoied too 113 * @return void 114 * @access public 115 */ 116 function setIncludeEmptyDirs($bool) { 117 $this->includeEmpty = (boolean) $bool; 118 } 119 120 121 /** 122 * Set the file. We have to manually take care of the 123 * type that is coming due to limited type support in php 124 * in and convert it manually if neccessary. 125 * 126 * @param string/object The source file. Either a string or an PhingFile object 127 * @return void 128 * @access public 129 */ 130 function setFile(PhingFile $file) { 131 $this->file = $file; 132 } 133 134 135 /** 136 * Set the toFile. We have to manually take care of the 137 * type that is coming due to limited type support in php 138 * in and convert it manually if neccessary. 139 * 140 * @param string/object The dest file. Either a string or an PhingFile object 141 * @return void 142 * @access public 143 */ 144 function setTofile(PhingFile $file) { 145 $this->destFile = $file; 146 } 147 148 149 /** 150 * Set the toDir. We have to manually take care of the 151 * type that is coming due to limited type support in php 152 * in and convert it manually if neccessary. 153 * 154 * @param string/object The directory, either a string or an PhingFile object 155 * @return void 156 * @access public 157 */ 158 function setTodir(PhingFile $dir) { 159 $this->destDir = $dir; 160 } 161 162 /** 163 * Nested creator, creates a FileSet for this task 164 * 165 * @access public 166 * @return object The created fileset object 167 */ 168 function createFileSet() { 169 $num = array_push($this->filesets, new FileSet()); 170 return $this->filesets[$num-1]; 171 } 172 173 /** 174 * Creates a filterchain 175 * 176 * @access public 177 * @return object The created filterchain object 178 */ 179 function createFilterChain() { 180 $num = array_push($this->filterChains, new FilterChain($this->project)); 181 return $this->filterChains[$num-1]; 182 } 183 184 /** 185 * Nested creator, creates one Mapper for this task 186 * 187 * @access public 188 * @return object The created Mapper type object 189 * @throws BuildException 190 */ 191 function createMapper() { 192 if ($this->mapperElement !== null) { 193 throw new BuildException("Cannot define more than one mapper", $this->location); 194 } 195 $this->mapperElement = new Mapper($this->project); 196 return $this->mapperElement; 197 } 198 199 /** 200 * The main entry point where everything gets in motion. 201 * 202 * @access public 203 * @return true on success 204 * @throws BuildException 205 */ 206 function main() { 207 208 $this->validateAttributes(); 209 210 if ($this->file !== null) { 211 if ($this->file->exists()) { 212 if ($this->destFile === null) { 213 $this->destFile = new PhingFile($this->destDir, (string) $this->file->getName()); 214 } 215 if ($this->overwrite === true || ($this->file->lastModified() > $this->destFile->lastModified())) { 216 $this->fileCopyMap[$this->file->getAbsolutePath()] = $this->destFile->getAbsolutePath(); 217 } else { 218 $this->log($this->file->getName()." omitted, is up to date"); 219 } 220 } else { 221 // terminate build 222 throw new BuildException("Could not find file " . $this->file->__toString() . " to copy."); 223 } 224 } 225 226 $project = $this->getProject(); 227 228 // process filesets 229 foreach($this->filesets as $fs) { 230 $ds = $fs->getDirectoryScanner($project); 231 $fromDir = $fs->getDir($project); 232 $srcFiles = $ds->getIncludedFiles(); 233 $srcDirs = $ds->getIncludedDirectories(); 234 $this->_scan($fromDir, $this->destDir, $srcFiles, $srcDirs); 235 } 236 237 // go and copy the stuff 238 $this->doWork(); 239 240 if ($this->destFile !== null) { 241 $this->destDir = null; 242 } 243 } 244 245 /** 246 * Validates attributes coming in from XML 247 * 248 * @access private 249 * @return void 250 * @throws BuildException 251 */ 252 private function validateAttributes() { 253 254 if ($this->file === null && count($this->filesets) === 0) { 255 throw new BuildException("CopyTask. Specify at least one source - a file or a fileset."); 256 } 257 258 if ($this->destFile !== null && $this->destDir !== null) { 259 throw new BuildException("Only one of destfile and destdir may be set."); 260 } 261 262 if ($this->destFile === null && $this->destDir === null) { 263 throw new BuildException("One of destfile or destdir must be set."); 264 } 265 266 if ($this->file !== null && $this->file->exists() && $this->file->isDirectory()) { 267 throw new BuildException("Use a fileset to copy directories."); 268 } 269 270 if ($this->destFile !== null && count($this->filesets) > 0) { 271 throw new BuildException("Cannot concatenate multple files into a single file."); 272 } 273 274 if ($this->destFile !== null) { 275 $this->destDir = new PhingFile($this->destFile->getParent()); 276 } 277 } 278 279 /** 280 * Compares source files to destination files to see if they 281 * should be copied. 282 * 283 * @access private 284 * @return void 285 */ 286 private function _scan(&$fromDir, &$toDir, &$files, &$dirs) { 287 /* mappers should be generic, so we get the mappers here and 288 pass them on to builMap. This method is not redundan like it seems */ 289 $mapper = null; 290 if ($this->mapperElement !== null) { 291 $mapper = $this->mapperElement->getImplementation(); 292 } else if ($this->flatten) { 293 $mapper = new FlattenMapper(); 294 } else { 295 $mapper = new IdentityMapper(); 296 } 297 $this->buildMap($fromDir, $toDir, $files, $mapper, $this->fileCopyMap); 298 $this->buildMap($fromDir, $toDir, $dirs, $mapper, $this->dirCopyMap); 299 } 300 301 /** 302 * Builds a map of filenames (from->to) that should be copied 303 * 304 * @access private 305 * @return void 306 */ 307 private function buildMap(&$fromDir, &$toDir, &$names, &$mapper, &$map) { 308 $toCopy = null; 309 if ($this->overwrite) { 310 $v = array(); 311 foreach($names as $name) { 312 $result = $mapper->main($name); 313 if ($result !== null) { 314 $v[] = $name; 315 } 316 } 317 $toCopy = $v; 318 } else { 319 $ds = new SourceFileScanner($this); 320 $toCopy = $ds->restrict($names, $fromDir, $toDir, $mapper); 321 } 322 323 for ($i=0,$_i=count($toCopy); $i < $_i; $i++) { 324 $src = new PhingFile($fromDir, $toCopy[$i]); 325 $mapped = $mapper->main($toCopy[$i]); 326 $dest = new PhingFile($toDir, $mapped[0]); 327 $map[$src->getAbsolutePath()] = $dest->getAbsolutePath(); 328 } 329 } 330 331 332 /** 333 * Actually copies the files 334 * 335 * @access private 336 * @return void 337 * @throws BuildException 338 */ 339 private function doWork() { 340 341 // These "slots" allow filters to retrieve information about the currently-being-process files 342 $fromSlot = $this->getRegisterSlot("currentFromFile"); 343 $fromBasenameSlot = $this->getRegisterSlot("currentFromFile.basename"); 344 345 $toSlot = $this->getRegisterSlot("currentToFile"); 346 $toBasenameSlot = $this->getRegisterSlot("currentToFile.basename"); 347 348 $mapSize = count($this->fileCopyMap); 349 $total = $mapSize; 350 if ($mapSize > 0) { 351 $this->log("Copying ".$mapSize." file".(($mapSize) === 1 ? '' : 's')." to ". $this->destDir->getAbsolutePath()); 352 // walks the map and actually copies the files 353 $count=0; 354 foreach($this->fileCopyMap as $from => $to) { 355 if ($from === $to) { 356 $this->log("Skipping self-copy of " . $from, $this->verbosity); 357 $total--; 358 continue; 359 } 360 $this->log("From ".$from." to ".$to, $this->verbosity); 361 try { // try to copy file 362 363 $fromFile = new PhingFile($from); 364 $toFile = new PhingFile($to); 365 366 $fromSlot->setValue($fromFile->getPath()); 367 $fromBasenameSlot->setValue($fromFile->getName()); 368 369 $toSlot->setValue($toFile->getPath()); 370 $toBasenameSlot->setValue($toFile->getName()); 371 372 $this->fileUtils->copyFile($fromFile, $toFile, $this->overwrite, $this->preserveLMT, $this->filterChains, $this->getProject()); 373 374 $count++; 375 } catch (IOException $ioe) { 376 $this->log("Failed to copy " . $from . " to " . $to . ": " . $ioe->getMessage(), PROJECT_MSG_ERR); 377 } 378 } 379 } 380 381 // handle empty dirs if appropriate 382 if ($this->includeEmpty) { 383 $destdirs = array_values($this->dirCopyMap); 384 $count = 0; 385 foreach ($destdirs as $destdir) { 386 $d = new PhingFile((string) $destdir); 387 if (!$d->exists()) { 388 if (!$d->mkdirs()) { 389 $this->log("Unable to create directory " . $d->__toString(), PROJECT_MSG_ERR); 390 } else { 391 $count++; 392 } 393 } 394 } 395 if ($count > 0) { 396 $this->log("Copied ".$count." empty director" . ($count == 1 ? "y" : "ies") . " to " . $this->destDir->getAbsolutePath()); 397 } 398 } 399 } 400 401 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |