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 / parser / ProjectConfigurator.php < prev    next >
Encoding:
PHP Script  |  2007-02-06  |  9.3 KB  |  246 lines

  1. <?php
  2. /*
  3.  * $Id: ProjectConfigurator.php 147 2007-02-06 20:32:22Z hans $
  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. include_once 'phing/system/io/BufferedReader.php';
  23. include_once 'phing/system/io/FileReader.php';
  24. include_once 'phing/BuildException.php';
  25. include_once 'phing/system/lang/FileNotFoundException.php';
  26. include_once 'phing/system/io/PhingFile.php';
  27.  
  28. /**
  29.  * The datatype handler class.
  30.  *
  31.  * This class handles the occurance of registered datatype tags like
  32.  * FileSet
  33.  *
  34.  * @author      Andreas Aderhold <andi@binarycloud.com>
  35.  * @copyright ∩┐╜ 2001,2002 THYRELL. All rights reserved
  36.  * @version   $Revision: 1.17 $ $Date: 2007-02-06 21:32:22 +0100 (Tue, 06 Feb 2007) $
  37.  * @access    public
  38.  * @package   phing.parser
  39.  */
  40. class ProjectConfigurator {
  41.  
  42.     public $project;
  43.     public $locator;
  44.     
  45.     public $buildFile;
  46.     public $buildFileParent;
  47.         
  48.     /**
  49.      * Static call to ProjectConfigurator. Use this to configure a
  50.      * project. Do not use the new operator.
  51.      *
  52.      * @param  object  the Project instance this configurator should use
  53.      * @param  object  the buildfile object the parser should use
  54.      * @access public
  55.      */
  56.     public static function configureProject(Project $project, PhingFile $buildFile) {
  57.         $pc = new ProjectConfigurator($project, $buildFile);
  58.         $pc->parse();
  59.     }
  60.  
  61.     /**
  62.      * Constructs a new ProjectConfigurator object
  63.      * This constructor is private. Use a static call to
  64.      * <code>configureProject</code> to configure a project.
  65.      *
  66.      * @param  object  the Project instance this configurator should use
  67.      * @param  object  the buildfile object the parser should use
  68.      * @access private
  69.      */
  70.     function __construct(Project $project, PhingFile $buildFile) {
  71.         $this->project = $project;
  72.         $this->buildFile = new PhingFile($buildFile->getAbsolutePath());
  73.         $this->buildFileParent = new PhingFile($this->buildFile->getParent());
  74.     }
  75.  
  76.     /**
  77.      * Creates the ExpatParser, sets root handler and kick off parsing
  78.      * process.
  79.      *
  80.      * @throws BuildException if there is any kind of execption during
  81.      *         the parsing process
  82.      * @access private
  83.      */
  84.     protected function parse() {
  85.         try {
  86.             $reader = new BufferedReader(new FileReader($this->buildFile));
  87.             $parser = new ExpatParser($reader);
  88.             $parser->parserSetOption(XML_OPTION_CASE_FOLDING,0);
  89.             $parser->setHandler(new RootHandler($parser, $this));
  90.             $this->project->log("parsing buildfile ".$this->buildFile->getName(), Project::MSG_VERBOSE);
  91.             $parser->parse();
  92.             $reader->close();
  93.         } catch (Exception $exc) {
  94.             throw new BuildException("Error reading project file", $exc);
  95.         }
  96.     }
  97.  
  98.     /**
  99.      * Configures an element and resolves eventually given properties.
  100.      *
  101.      * @param  object  the element to configure
  102.      * @param  array   the element's attributes
  103.      * @param  object  the project this element belongs to
  104.      * @throws Exception if arguments are not valid
  105.      * @throws BuildException if attributes can not be configured
  106.      * @access public
  107.      */
  108.     public static function configure($target, $attrs, Project $project) {               
  109.  
  110.         if ($target instanceof TaskAdapter) {
  111.             $target = $target->getProxy();
  112.         }
  113.         
  114.         // if the target is an UnknownElement, this means that the tag had not been registered
  115.         // when the enclosing element (task, target, etc.) was configured.  It is possible, however, 
  116.         // that the tag was registered (e.g. using <taskdef>) after the original configuration.
  117.         // ... so, try to load it again:
  118.         if ($target instanceof UnknownElement) {
  119.             $tryTarget = $project->createTask($target->getTaskType());
  120.             if ($tryTarget) {
  121.                 $target = $tryTarget;
  122.             }
  123.         }
  124.  
  125.         $bean = get_class($target);
  126.         $ih = IntrospectionHelper::getHelper($bean);
  127.  
  128.         foreach ($attrs as $key => $value) {
  129.             if ($key == 'id') {
  130.                 continue;
  131.                 // throw new BuildException("Id must be set Extermnally");
  132.             }            
  133.             $value = self::replaceProperties($project, $value, $project->getProperties());
  134.             try { // try to set the attribute
  135.                 $ih->setAttribute($project, $target, strtolower($key), $value);
  136.             } catch (BuildException $be) {
  137.                 // id attribute must be set externally
  138.                 if ($key !== "id") {
  139.                     throw $be;
  140.                 }
  141.             }
  142.         }
  143.     }
  144.  
  145.     /**
  146.      * Configures the #CDATA of an element.
  147.      *
  148.      * @param  object  the project this element belongs to
  149.      * @param  object  the element to configure
  150.      * @param  string  the element's #CDATA
  151.      * @access public
  152.      */
  153.     public static function addText($project, $target, $text = null) {
  154.         if ($text === null || strlen(trim($text)) === 0) {
  155.             return;
  156.         }    
  157.         $ih = IntrospectionHelper::getHelper(get_class($target));
  158.         $text = self::replaceProperties($project, $text, $project->getProperties());
  159.         $ih->addText($project, $target, $text);
  160.     }
  161.  
  162.     /**
  163.      * Stores a configured child element into its parent object
  164.      *
  165.      * @param  object  the project this element belongs to
  166.      * @param  object  the parent element
  167.      * @param  object  the child element
  168.      * @param  string  the XML tagname
  169.      * @access public
  170.      */
  171.     public static function storeChild($project, $parent, $child, $tag) {
  172.         $ih = IntrospectionHelper::getHelper(get_class($parent));
  173.         $ih->storeElement($project, $parent, $child, $tag);
  174.     }
  175.  
  176.     // The following two properties are a sort of hack
  177.     // to enable a static function to serve as the callback
  178.     // for preg_replace_callback().  Clearly we cannot use object
  179.     // variables, since the replaceProperties() is called statically.
  180.     // This is IMO better than using global variables in the callback.
  181.     
  182.     private static $propReplaceProject;
  183.     private static $propReplaceProperties;
  184.          
  185.     /**
  186.      * Replace ${} style constructions in the given value with the
  187.      * string value of the corresponding data types. This method is
  188.      * static.
  189.      *
  190.      * @param  object  the project that should be used for property look-ups
  191.      * @param  string  the string to be scanned for property references
  192.      * @param  array   proeprty keys
  193.      * @return string  the replaced string or <code>null</code> if the string
  194.      *                 itself was null
  195.      */
  196.     public static function replaceProperties(Project $project, $value, $keys) {
  197.         
  198.         if ($value === null) {
  199.             return null;
  200.         }
  201.         
  202.         // These are a "hack" to support static callback for preg_replace_callback()
  203.         
  204.         // make sure these get initialized every time        
  205.         self::$propReplaceProperties = $keys;
  206.         self::$propReplaceProject = $project;
  207.         
  208.         // Because we're not doing anything special (like multiple passes),
  209.         // regex is the simplest / fastest.  PropertyTask, though, uses
  210.         // the old parsePropertyString() method, since it has more stringent
  211.         // requirements.
  212.         
  213.         $sb = preg_replace_callback('/\$\{([^}]+)\}/', array('ProjectConfigurator', 'replacePropertyCallback'), $value);
  214.         return $sb;        
  215.     }
  216.     
  217.     /**
  218.      * Private [static] function for use by preg_replace_callback to replace a single param.
  219.      * This method makes use of a static variable to hold the 
  220.      */
  221.     private static function replacePropertyCallback($matches)
  222.     {
  223.         $propertyName = $matches[1];
  224.         if (!isset(self::$propReplaceProperties[$propertyName])) {
  225.                     self::$propReplaceProject->log('Property ${'.$propertyName.'} has not been set.', Project::MSG_VERBOSE);
  226.                     return $matches[0];
  227.         } else {
  228.             self::$propReplaceProject->log('Property ${'.$propertyName.'} => ' . self::$propReplaceProperties[$propertyName], Project::MSG_DEBUG);
  229.         }
  230.         return self::$propReplaceProperties[$propertyName];
  231.     }           
  232.  
  233.     /**
  234.      * Scan Attributes for the id attribute and maybe add a reference to
  235.      * project.
  236.      *
  237.      * @param object the element's object
  238.      * @param array  the element's attributes
  239.      */
  240.     public function configureId($target, $attr) {
  241.         if (isset($attr['id']) && $attr['id'] !== null) {
  242.             $this->project->addReference($attr['id'], $target);
  243.         }
  244.     }
  245. }
  246.