| [ Index ] |
|
Code source de Symfony 1.0.0 |
1 <?php 2 3 /* 4 * $Id: CapsuleTask.php 3076 2006-12-18 08:52:12Z fabien $ 5 * 6 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 7 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 8 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 9 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 10 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 11 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 12 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 13 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 14 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 16 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 17 * 18 * This software consists of voluntary contributions made by many individuals 19 * and is licensed under the LGPL. For more information please see 20 * <http://phing.info>. 21 */ 22 23 include_once 'phing/Task.php'; 24 include_once 'phing/BuildException.php'; 25 include_once 'phing/lib/Capsule.php'; 26 include_once 'phing/util/StringHelper.php'; 27 28 /** 29 * A phing task for generating output by using Capsule. 30 * 31 * This is based on the interface to TexenTask from Apache's Velocity engine. 32 * 33 * @author Hans Lellelid <hans@xmpl.org> 34 * @version $Revision: 1.17 $ 35 * @package phing.tasks.ext 36 */ 37 class CapsuleTask extends Task { 38 39 /** 40 * Capsule "template" engine. 41 * @var Capsule 42 */ 43 protected $context; 44 45 /** 46 * Any vars assigned via the build file. 47 * @var array AssignedVar[] 48 */ 49 protected $assignedVars = array(); 50 51 /** 52 * This is the control template that governs the output. 53 * It may or may not invoke the services of worker 54 * templates. 55 * @var string 56 */ 57 protected $controlTemplate; 58 59 /** 60 * This is where Velocity will look for templates 61 * using the file template loader. 62 * @var string 63 */ 64 protected $templatePath; 65 66 /** 67 * This is where texen will place all the output 68 * that is a product of the generation process. 69 * @var string 70 */ 71 protected $outputDirectory; 72 73 /** 74 * This is the file where the generated text 75 * will be placed. 76 * @var string 77 */ 78 protected $outputFile; 79 80 /** 81 * <p> 82 * These are properties that are fed into the 83 * initial context from a properties file. This 84 * is simply a convenient way to set some values 85 * that you wish to make available in the context. 86 * </p> 87 * <p> 88 * These values are not critical, like the template path 89 * or output path, but allow a convenient way to 90 * set a value that may be specific to a particular 91 * generation task. 92 * </p> 93 * <p> 94 * For example, if you are generating scripts to allow 95 * user to automatically create a database, then 96 * you might want the <code>$databaseName</code> 97 * to be placed 98 * in the initial context so that it is available 99 * in a script that might look something like the 100 * following: 101 * <code><pre> 102 * #!bin/sh 103 * 104 * echo y | mysqladmin create $databaseName 105 * </pre></code> 106 * The value of <code>$databaseName</code> isn't critical to 107 * output, and you obviously don't want to change 108 * the ant task to simply take a database name. 109 * So initial context values can be set with 110 * properties file. 111 * 112 * @var array 113 */ 114 protected $contextProperties; 115 116 // ----------------------------------------------------------------------- 117 // The following getters & setters are used by phing to set properties 118 // specified in the XML for the capsule task. 119 // ----------------------------------------------------------------------- 120 121 /** 122 * [REQUIRED] Set the control template for the 123 * generating process. 124 * @param string $controlTemplate 125 * @return void 126 */ 127 public function setControlTemplate ($controlTemplate) { 128 $this->controlTemplate = $controlTemplate; 129 } 130 131 /** 132 * Get the control template for the 133 * generating process. 134 * @return string 135 */ 136 public function getControlTemplate() { 137 return $this->controlTemplate; 138 } 139 140 /** 141 * [REQUIRED] Set the path where Velocity will look 142 * for templates using the file template 143 * loader. 144 * @return void 145 * @throws Exception 146 */ 147 public function setTemplatePath($templatePath) { 148 $resolvedPath = ""; 149 $tok = strtok($templatePath, ","); 150 while ( $tok ) { 151 // resolve relative path from basedir and leave 152 // absolute path untouched. 153 $fullPath = $this->project->resolveFile($tok); 154 $cpath = $fullPath->getCanonicalPath(); 155 if ($cpath === false) { 156 $this->log("Template directory does not exist: " . $fullPath->getAbsolutePath()); 157 } else { 158 $resolvedPath .= $cpath; 159 } 160 $tok = strtok(","); 161 if ( $tok ) { 162 $resolvedPath .= ","; 163 } 164 } 165 $this->templatePath = $resolvedPath; 166 } 167 168 /** 169 * Get the path where Velocity will look 170 * for templates using the file template 171 * loader. 172 * @return string 173 */ 174 public function getTemplatePath() { 175 return $this->templatePath; 176 } 177 178 /** 179 * [REQUIRED] Set the output directory. It will be 180 * created if it doesn't exist. 181 * @param PhingFile $outputDirectory 182 * @return void 183 * @throws Exception 184 */ 185 public function setOutputDirectory(PhingFile $outputDirectory) { 186 try { 187 if (!$outputDirectory->exists()) { 188 $this->log("Output directory does not exist, creating: " . $outputDirectory->getPath(),PROJECT_MSG_VERBOSE); 189 if (!$outputDirectory->mkdirs()) { 190 throw new IOException("Unable to create Ouptut directory: " . $outputDirectory->getAbsolutePath()); 191 } 192 } 193 $this->outputDirectory = $outputDirectory->getCanonicalPath(); 194 } catch (IOException $ioe) { 195 throw new BuildException($ioe); 196 } 197 } 198 199 /** 200 * Get the output directory. 201 * @return string 202 */ 203 public function getOutputDirectory() { 204 return $this->outputDirectory; 205 } 206 207 /** 208 * [REQUIRED] Set the output file for the 209 * generation process. 210 * @param string $outputFile (TODO: change this to File) 211 * @return void 212 */ 213 public function setOutputFile($outputFile) { 214 $this->outputFile = $outputFile; 215 } 216 217 /** 218 * Get the output file for the 219 * generation process. 220 * @return string 221 */ 222 public function getOutputFile() { 223 return $this->outputFile; 224 } 225 226 /** 227 * Set the context properties that will be 228 * fed into the initial context be the 229 * generating process starts. 230 * @param string $file 231 * @return void 232 */ 233 public function setContextProperties($file) { 234 $sources = explode(",", $file); 235 $this->contextProperties = new Properties(); 236 237 // Always try to get the context properties resource 238 // from a file first. Templates may be taken from a JAR 239 // file but the context properties resource may be a 240 // resource in the filesystem. If this fails than attempt 241 // to get the context properties resource from the 242 // classpath. 243 for ($i=0, $sourcesLength=count($sources); $i < $sourcesLength; $i++) { 244 $source = new Properties(); 245 246 try { 247 248 // resolve relative path from basedir and leave 249 // absolute path untouched. 250 $fullPath = $this->project->resolveFile($sources[$i]); 251 $this->log("Using contextProperties file: " . $fullPath->toString()); 252 $source->load($fullPath); 253 254 } catch (Exception $e) { 255 256 throw new BuildException("Context properties file " . $sources[$i] . 257 " could not be found in the file system!"); 258 259 } 260 261 $keys = $source->keys(); 262 263 foreach ($keys as $key) { 264 $name = $key; 265 $value = $this->project->replaceProperties($source->getProperty($name)); 266 $this->contextProperties->setProperty($name, $value); 267 } 268 } 269 } 270 271 /** 272 * Get the context properties that will be 273 * fed into the initial context be the 274 * generating process starts. 275 * @return Properties 276 */ 277 public function getContextProperties() { 278 return $this->contextProperties; 279 } 280 281 /** 282 * Creates an "AssignedVar" class. 283 */ 284 public function createAssign() { 285 $a = new AssignedVar(); 286 $this->assignedVars[] = $a; 287 return $a; 288 } 289 290 // --------------------------------------------------------------- 291 // End of XML setters & getters 292 // --------------------------------------------------------------- 293 294 /** 295 * Creates a Smarty object. 296 * 297 * @return Smarty initialized (cleared) Smarty context. 298 * @throws Exception the execute method will catch 299 * and rethrow as a <code>BuildException</code> 300 */ 301 public function initControlContext() { 302 $this->context->clear(); 303 foreach($this->assignedVars as $var) { 304 $this->context->put($var->getName(), $var->getValue()); 305 } 306 return $this->context; 307 } 308 309 /** 310 * Execute the input script with Velocity 311 * 312 * @throws BuildException 313 * BuildExceptions are thrown when required attributes are missing. 314 * Exceptions thrown by Velocity are rethrown as BuildExceptions. 315 */ 316 public function main() { 317 318 // Make sure the template path is set. 319 if (empty($this->templatePath)) { 320 throw new BuildException("The template path needs to be defined!"); 321 } 322 323 // Make sure the control template is set. 324 if ($this->controlTemplate === null) { 325 throw new BuildException("The control template needs to be defined!"); 326 } 327 328 // Make sure the output directory is set. 329 if ($this->outputDirectory === null) { 330 throw new BuildException("The output directory needs to be defined!"); 331 } 332 333 // Make sure there is an output file. 334 if ($this->outputFile === null) { 335 throw new BuildException("The output file needs to be defined!"); 336 } 337 338 // Setup Smarty runtime. 339 340 // Smarty uses one object to store properties and to store 341 // the context for the template (unlike Velocity). We setup this object, calling it 342 // $this->context, and then initControlContext simply zeros out 343 // any assigned variables. 344 $this->context = new Capsule(); 345 346 if ($this->templatePath !== null) { 347 $this->log("Using templatePath: " . $this->templatePath); 348 $this->context->setTemplatePath($this->templatePath); 349 } 350 351 // Make sure the output directory exists, if it doesn't 352 // then create it. 353 $outputDir = new PhingFile($this->outputDirectory); 354 if (!$outputDir->exists()) { 355 $this->log("Output directory does not exist, creating: " . $outputDir->getAbsolutePath()); 356 $outputDir->mkdirs(); 357 } 358 359 $this->context->setOutputDirectory($outputDir->getAbsolutePath()); 360 361 $path = $this->outputDirectory . DIRECTORY_SEPARATOR . $this->outputFile; 362 $this->log("Generating to file " . $path); 363 364 //$writer = new FileWriter($path); 365 366 // The generator and the output path should 367 // be placed in the init context here and 368 // not in the generator class itself. 369 $c = $this->initControlContext(); 370 371 // Set any variables that need to always 372 // be loaded 373 $this->populateInitialContext($c); 374 375 // Feed all the options into the initial 376 // control context so they are available 377 // in the control/worker templates. 378 if ($this->contextProperties !== null) { 379 380 foreach($this->contextProperties->keys() as $property) { 381 382 $value = $this->contextProperties->getProperty($property); 383 384 // Special exception (from Texen) 385 // for properties ending in file.contents: 386 // in that case we dump the contents of the file 387 // as the "value" for the Property. 388 if (preg_match('/file\.contents$/', $property)) { 389 // pull in contents of file specified 390 391 $property = substr($property, 0, strpos($property, "file.contents") - 1); 392 393 // reset value, and then 394 // read in teh contents of the file into that var 395 $value = ""; 396 $f = new PhingFile($project->resolveFile($value)->getCanonicalPath()); 397 if ($f->exists()) { 398 $fr = new FileReader($f); 399 $fr->readInto($value); 400 } 401 402 } // if ends with file.contents 403 404 if (StringHelper::isBoolean($value)) { 405 $value = StringHelper::booleanValue($value); 406 } 407 408 $c->put($property, $value); 409 410 } // foreach property 411 412 } // if contextProperties !== null 413 414 try { 415 $this->log("Parsing control template: " . $this->controlTemplate); 416 $c->parse($this->controlTemplate, $path); 417 } catch (Exception $ioe) { 418 throw new BuildException("Cannot write parsed template: ". $ioe->getMessage()); 419 } 420 421 $this->cleanup(); 422 } 423 424 /** 425 * Place useful objects into the initial context. 426 * 427 * 428 * @param Capsule $context The context to populate, as retrieved from 429 * {@link #initControlContext()}. 430 * @return void 431 * @throws Exception Error while populating context. The {@link 432 * #main()} method will catch and rethrow as a 433 * <code>BuildException</code>. 434 */ 435 protected function populateInitialContext(Capsule $context) { 436 $this->context->put("now", strftime("%c", time())); 437 $this->context->put("task", $this); 438 } 439 440 /** 441 * A hook method called at the end of {@link #execute()} which can 442 * be overridden to perform any necessary cleanup activities (such 443 * as the release of database connections, etc.). By default, 444 * does nothing. 445 * @return void 446 * @throws Exception Problem cleaning up. 447 */ 448 protected function cleanup() { 449 } 450 } 451 452 453 /** 454 * An "inner" class for holding assigned var values. 455 * May be need to expand beyond name/value in the future. 456 */ 457 class AssignedVar { 458 459 private $name; 460 private $value; 461 462 function setName($v) { 463 $this->name = $v; 464 } 465 466 function setValue($v) { 467 $this->value = $v; 468 } 469 470 function getName() { 471 return $this->name; 472 } 473 474 function getValue() { 475 return $this->value; 476 } 477 478 }
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 |