[ Index ]
 

Code source de Symfony 1.0.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/vendor/phing/types/ -> Path.php (source)

   1  <?php
   2  /*
   3   *  $Id: Path.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/types/DataType.php';
  23  include_once 'phing/util/PathTokenizer.php';
  24  include_once 'phing/types/FileSet.php';
  25  
  26  /**
  27   * This object represents a path as used by include_path or PATH
  28   * environment variable.
  29   *
  30   * This class has been adopted from the Java Ant equivalent.  The ability have
  31   * path structures in Phing is important; however, because of how PHP classes interact
  32   * the ability to specify CLASSPATHs makes less sense than Java.Rather than providing
  33   * CLASSPATH for any tasks that take classes as parameters, perhaps a better
  34   * solution in PHP is to have an IncludePath task, which prepends paths to PHP's include_path
  35   * INI variable. This gets around the problem that simply using a path to load the initial
  36   * PHP class is not enough (in most cases the loaded class may assume that it is on the global
  37   * PHP include_path, and will try to load dependent classes accordingly).  The other option is
  38   * to provide a way for this class to add paths to the include path, if desired -- or to create
  39   * an IncludePath subclass.  Once added, though, when would a path be removed from the include path?
  40   * 
  41   * <p>
  42   * <code>
  43   * &lt;sometask&gt;<br>
  44   * &nbsp;&nbsp;&lt;somepath&gt;<br>
  45   * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement location="/path/to/file" /&gt;<br>
  46   * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement path="/path/to/class2;/path/to/class3" /&gt;<br>
  47   * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement location="/path/to/file3" /&gt;<br>
  48   * &nbsp;&nbsp;&lt;/somepath&gt;<br>
  49   * &lt;/sometask&gt;<br>
  50   * </code>
  51   * <p>
  52   * The object implemention <code>sometask</code> must provide a method called
  53   * <code>createSomepath</code> which returns an instance of <code>Path</code>.
  54   * Nested path definitions are handled by the Path object and must be labeled
  55   * <code>pathelement</code>.<p>
  56   *
  57   * The path element takes a parameter <code>path</code> which will be parsed
  58   * and split into single elements. It will usually be used
  59   * to define a path from an environment variable.
  60   *
  61   * @author Hans Lellelid <hans@xmpl.org> (Phing)
  62   * @author Thomas.Haas@softwired-inc.com (Ant)
  63   * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
  64   * @package phing.types
  65   */
  66  class Path extends DataType {
  67  
  68      private $elements = array();    
  69      
  70      /**
  71       * Constructor for internally instantiated objects sets project.
  72       * @param Project $project
  73       * @param string $path (for use by IntrospectionHelper)
  74       */
  75      public function __construct($project = null, $path = null) {
  76          if ($project !== null) {
  77              $this->setProject($project);
  78          }
  79          if ($path !== null) {
  80              $this->createPathElement()->setPath($path);
  81          }        
  82      }
  83  
  84      /**
  85       * Adds a element definition to the path.
  86       * @param $location the location of the element to add (must not be
  87       * <code>null</code> nor empty.
  88       * @throws BuildException
  89       */
  90      public function setDir(PhingFile $location) {
  91          if ($this->isReference()) {
  92              throw $this->tooManyAttributes();
  93          }        
  94          $this->createPathElement()->setDir($location);
  95      }
  96  
  97      /**
  98       * Parses a path definition and creates single PathElements.
  99       * @param path the path definition.
 100       * @throws BuildException
 101       */
 102      public function setPath($path) {
 103          if ($this->isReference()) {
 104              throw $this->tooManyAttributes();
 105          }
 106          $this->createPathElement()->setPath($path);
 107      }
 108  
 109      /**
 110       * Makes this instance in effect a reference to another Path instance.
 111       *
 112       * <p>You must not set another attribute or nest elements inside
 113       * this element if you make it a reference.</p>
 114       * @throws BuildException
 115       */
 116      public function setRefid(Reference $r)  {
 117          if (!empty($this->elements)) {
 118              throw $this->tooManyAttributes();
 119          }
 120          $this->elements[] = $r;
 121          parent::setRefid($r);
 122      }
 123  
 124      /**
 125       * Creates the nested <code>&lt;pathelement&gt;</code> element.
 126       * @throws BuildException 
 127       */
 128      public function createPathElement() {
 129          if ($this->isReference()) {
 130              throw $this->noChildrenAllowed();
 131          }
 132          $pe = new PathElement($this);
 133          $this->elements[] = $pe;
 134          return $pe;
 135      }
 136  
 137      /**
 138       * Adds a nested <code>&lt;fileset&gt;</code> element.
 139       * @throws BuildException 
 140       */
 141      public function addFileset(FileSet $fs) {
 142          if ($this->isReference()) {
 143              throw $this->noChildrenAllowed();
 144          }
 145          $this->elements[] = $fs;
 146          $this->checked = false;
 147      }
 148  
 149      /**
 150       * Adds a nested <code>&lt;dirset&gt;</code> element.
 151       * @throws BuildException 
 152       */
 153      public function addDirset(DirSet $dset) {
 154          if ($this->isReference()) {
 155              throw $this->noChildrenAllowed();
 156          }
 157          $this->elements[] = $dset;
 158          $this->checked = false;
 159      }
 160  
 161      /**
 162       * Creates a nested <code>&lt;path&gt;</code> element.
 163       * @throws BuildException
 164       */
 165      public function createPath() {
 166          if ($this->isReference()) {
 167              throw $this->noChildrenAllowed();
 168          }
 169          $p = new Path($this->project);
 170          $this->elements[] = $p;
 171          $this->checked = false;
 172          return $p;
 173      }
 174  
 175      /**
 176       * Append the contents of the other Path instance to this.
 177       */
 178      public function append(Path $other) {
 179          if ($other === null) {
 180              return;
 181          }
 182          $l = $other->listPaths();
 183          foreach($l as $path) {
 184              if (!in_array($path, $this->elements, true)) {
 185                  $this->elements[] = $path;
 186              }
 187          }
 188      }
 189  
 190       /**
 191       * Adds the components on the given path which exist to this
 192       * Path. Components that don't exist, aren't added.
 193       *
 194       * @param Path $source - Source path whose components are examined for existence.
 195       */
 196      public function addExisting(Path $source) {
 197          $list = $source->listPaths();
 198          foreach($list as $el) {
 199              $f = null;
 200              if ($this->project !== null) {
 201                  $f = $this->project->resolveFile($el);
 202              } else {
 203                  $f = new PhingFile($el);
 204              }
 205  
 206              if ($f->exists()) {
 207                  $this->setDir($f);
 208              } else {
 209                  $this->log("dropping " . $f->__toString() . " from path as it doesn't exist", 
 210                      PROJECT_MSG_VERBOSE);
 211              }
 212          }
 213      }
 214  
 215      /**
 216       * Returns all path elements defined by this and nested path objects.
 217       * @return array List of path elements.
 218       */
 219      public function listPaths() {
 220          if (!$this->checked) {
 221              // make sure we don't have a circular reference here
 222              $stk = array();
 223              array_push($stk, $this);
 224              $this->dieOnCircularReference($stk, $this->project);
 225          }
 226  
 227          $result = array();
 228          for ($i = 0, $elSize=count($this->elements); $i < $elSize; $i++) {
 229              $o = $this->elements[$i];
 230              if ($o instanceof Reference) {
 231                  $o = $o->getReferencedObject($this->project);
 232                  // we only support references to paths right now
 233                  if (!($o instanceof Path)) {
 234                      $msg = $r->getRefId() . " doesn't denote a path";
 235                      throw new BuildException($msg);
 236                  }
 237              }
 238              
 239              if (is_string($o)) {
 240                  $result[] = $o;
 241              } elseif ($o instanceof PathElement) {
 242                  $parts = $o->getParts();
 243                  if ($parts === null) {
 244                      throw new BuildException("You must either set location or" 
 245                          . " path on <pathelement>");
 246                  }
 247                  foreach($parts as $part) {
 248                      $result[] = $part;
 249                  }
 250              } elseif ($o instanceof Path) {
 251                  $p = $o;
 252                  if ($p->getProject() === null) {
 253                      $p->setProject($this->getProject());
 254                  }
 255                  $parts = $p->listPaths();
 256                  foreach($parts as $part) {
 257                      $result[] = $part;
 258                  }
 259              } elseif ($o instanceof DirSet) {
 260                  $dset = $o;
 261                  $ds = $dset->getDirectoryScanner($this->project);
 262                  $dirstrs = $ds->getIncludedDirectories();
 263                  $dir = $dset->getDir($this->project);
 264                  $this->addUnlessPresent($result, $dir, $s);  
 265                  
 266                  foreach($dirstrs as $dstr) {
 267                      $d = new PhingFile($dir, $dstr);
 268                      $result[] = $d->getAbsolutePath();
 269                  }                
 270                       
 271              } elseif ($o instanceof FileList) {
 272                  $fl = $o;
 273                  $dirstrs = $fl->getFiles($this->project);
 274                  $dir = $fl->getDir($this->project);
 275                  foreach($dirstrs as $dstr) {
 276                      $d = new PhingFile($dir, $dstr);
 277                      $result[] = $d->getAbsolutePath();
 278                  }
 279              }
 280          }
 281          
 282          return array_unique($result);
 283      }
 284  
 285  
 286      /**
 287       * Returns a textual representation of the path, which can be used as
 288       * CLASSPATH or PATH environment variable definition.
 289       * @return string A textual representation of the path.
 290       */
 291      public function __toString() {
 292          
 293          $list = $this->listPaths();
 294  
 295          // empty path return empty string
 296          if (empty($list)) {
 297              return "";
 298          }
 299          
 300          return implode(PATH_SEPARATOR, $list);
 301      }
 302  
 303      /**
 304       * Splits a PATH (with : or ; as separators) into its parts.
 305       * @param Project $project
 306       * @param string $source
 307       */
 308      public static function translatePath(Project $project, $source) {
 309          $result = array();
 310          if ($source == null) {
 311            return "";
 312          }
 313  
 314          $tok = new PathTokenizer($source);
 315          $element = "";
 316          while ($tok->hasMoreTokens()) {            
 317              $pathElement = $tok->nextToken();
 318              try {
 319                  $element .= self::resolveFile($project, $pathElement);
 320              } catch (BuildException $e) {
 321                  $this->project->log("Dropping path element " . $pathElement 
 322                      . " as it is not valid relative to the project", 
 323                      PROJECT_MSG_VERBOSE);
 324              }
 325              
 326              for ($i = 0, $_i=strlen($element); $i < $_i; $i++) {
 327                  self::translateFileSep($element, $i);
 328              }
 329              $result[] = $element;
 330          }
 331          
 332          return $result;
 333      }
 334  
 335      /**
 336       * Returns its argument with all file separator characters
 337       * replaced so that they match the local OS conventions.  
 338       */
 339      public static function translateFile($source) {
 340          if ($source == null) {
 341            return "";
 342          }
 343  
 344          $result = $source;
 345          for ($i = 0, $_i=strlen($source); $i < $_i; $i++) {
 346              self::translateFileSep($result, $i);
 347          }
 348          
 349          return $result;
 350      }
 351  
 352      /**
 353       * Translates all occurrences of / or \ to correct separator of the
 354       * current platform and returns whether it had to do any
 355       * replacements.  
 356       */
 357      protected static function translateFileSep(&$buffer, $pos) {
 358          if ($buffer{$pos} == '/' || $buffer{$pos} == '\\') {
 359              $buffer{$pos} = DIRECTORY_SEPARATOR;
 360              return true;
 361          }
 362          return false;
 363      }
 364  
 365      /**
 366       * How many parts does this Path instance consist of.
 367       * DEV NOTE: expensive call! list is generated, counted, and then
 368       * discareded.
 369       * @return int
 370       */
 371      public function size() {
 372          return count($this->listPaths());
 373      }
 374  
 375      /**
 376       * Return a Path that holds the same elements as this instance.
 377       */
 378      public function __clone() {
 379          $p = new Path($this->project);
 380          $p->append($this);
 381          return $p;
 382      }
 383  
 384      /**
 385       * Overrides the version of DataType to recurse on all DataType
 386       * child elements that may have been added.  
 387       * @throws BuildException
 388       */
 389      public function dieOnCircularReference(&$stk, Project $p) {
 390  
 391          if ($this->checked) {
 392              return;
 393          }
 394      
 395          // elements can contain strings, FileSets, Reference, etc.
 396          foreach($this->elements as $o) {
 397              
 398              if ($o instanceof Reference) {
 399                  $o = $o->getReferencedObject($p);
 400              }
 401  
 402              if ($o instanceof DataType) {
 403                  if (in_array($o, $stk, true)) {
 404                      throw $this->circularReference();
 405                  } else {
 406                      array_push($stk, $o);
 407                      $o->dieOnCircularReference($stk, $p);
 408                      array_pop($stk);
 409                  }
 410              }
 411          }
 412          
 413          $this->checked = true;
 414      }
 415  
 416      /**
 417       * Resolve a filename with Project's help - if we know one that is.
 418       *
 419       * <p>Assume the filename is absolute if project is null.</p>
 420       */
 421      private static function resolveFile(Project $project, $relativeName) {
 422          if ($project !== null) {
 423              $f = $project->resolveFile($relativeName);
 424              return $f->getAbsolutePath();
 425          }
 426          return $relativeName;
 427      }    
 428  
 429  }
 430  
 431  
 432  /**
 433   * Helper class, holds the nested <code>&lt;pathelement&gt;</code> values.
 434   */
 435  class PathElement {
 436  
 437      private $parts = array();
 438      private $outer;
 439      
 440      public function __construct(Path $outer) {
 441          $this->outer = $outer;
 442      }
 443      
 444      public function setDir(PhingFile $loc) {
 445          $this->parts = array(Path::translateFile($loc->getAbsolutePath()));
 446      }
 447  
 448      public function setPath($path) {
 449          $this->parts = Path::translatePath($this->outer->getProject(), $path);
 450      }
 451  
 452      public function getParts() {
 453          return $this->parts;
 454      }
 455  }
 456  ?>


Généré le : Fri Mar 16 22:42:14 2007 par Balluche grâce à PHPXref 0.7