[ Index ]
 

Code source de Symfony 1.0.0

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

title

Body

[fermer]

/lib/vendor/propel-generator/classes/propel/engine/database/transform/ -> XmlToAppData.php (source)

   1  <?php
   2  
   3  /*
   4   *  $Id: XmlToAppData.php 337 2006-02-15 14:41:54Z hans $
   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://propel.phpdb.org>.
  21   */
  22  
  23  include_once 'propel/engine/database/model/AppData.php';
  24  
  25  // Phing dependencies
  26  require_once 'phing/parser/AbstractHandler.php';
  27  include_once 'phing/system/io/FileReader.php';
  28  
  29  /**
  30   * A class that is used to parse an input xml schema file and creates an AppData
  31   * PHP object.
  32   *
  33   * @author Hans Lellelid <hans@xmpl.org> (Propel)
  34   * @author Leon Messerschmidt <leon@opticode.co.za> (Torque)
  35   * @author Jason van Zyl <jvanzyl@apache.org> (Torque)
  36   * @author Martin Poeschl <mpoeschl@marmot.at> (Torque)
  37   * @author Daniel Rall <dlr@collab.net> (Torque)
  38   * @version $Revision: 337 $
  39   * @package propel.engine.database.transform
  40   */
  41  class XmlToAppData extends AbstractHandler {
  42  
  43      /** enables debug output */
  44      const DEBUG = false;
  45  
  46      private $app;
  47      private $platform;
  48      private $currDB;
  49      private $currTable;
  50      private $currColumn;
  51      private $currFK;
  52      private $currIndex;
  53      private $currUnique;
  54      private $currValidator;
  55      private $currVendorObject;
  56  
  57      private $isForReferenceOnly;
  58      private $currentPackage;
  59      private $currentXmlFile;
  60      private $defaultPackage;
  61  
  62      private $encoding;
  63  
  64      /** two-dimensional array,
  65          first dimension is for schemas(key is the path to the schema file),
  66          second is for tags within the schema */
  67      private $schemasTagsStack = array();
  68  
  69      public $parser;
  70  
  71      /**
  72       * Creates a new instance for the specified database type.
  73       *
  74       * @param Platform $platform The type of database for the application.
  75       * @param string $defaultPackage the default PHP package used for the om
  76       * @param string $encoding The database encoding.
  77       */
  78  	public function __construct(Platform $platform, $defaultPackage, $encoding = 'iso-8859-1')
  79      {
  80          $this->app = new AppData($platform);
  81          $this->platform = $platform;
  82          $this->defaultPackage = $defaultPackage;
  83          $this->firstPass = true;
  84          $this->encoding = $encoding;
  85      }
  86      
  87      /**
  88       * Parses a XML input file and returns a newly created and
  89       * populated AppData structure.
  90       *
  91       * @param string $xmlFile The input file to parse.
  92       * @return AppData populated by <code>xmlFile</code>.
  93       */
  94  	public function parseFile($xmlFile)
  95      {
  96          // we don't want infinite recursion
  97          if($this->isAlreadyParsed($xmlFile)) {
  98              return;
  99          }
 100  
 101          $domDocument = new DomDocument('1.0', 'UTF-8');
 102          $domDocument->load($xmlFile);
 103  
 104          // store current schema file path
 105          $this->schemasTagsStack[$xmlFile] = array();
 106  
 107          $this->currentXmlFile = $xmlFile;        
 108  
 109          try {
 110              $fr = new FileReader($xmlFile);
 111          } catch (Exception $e) {
 112              $f = new PhingFile($xmlFile);
 113              throw new Exception("XML File not found: " . $f->getAbsolutePath());
 114          }
 115  
 116          $br = new BufferedReader($fr);
 117  
 118          $this->parser = new ExpatParser($br);
 119          $this->parser->parserSetOption(XML_OPTION_CASE_FOLDING, 0);
 120          $this->parser->setHandler($this);
 121  
 122          try {
 123              $this->parser->parse();
 124          } catch (Exception $e) {
 125              $br->close();
 126              throw $e;
 127          }
 128          $br->close();
 129  
 130          array_pop($this->schemasTagsStack);
 131  
 132          return $this->app;
 133      }
 134  
 135      /**
 136       * Handles opening elements of the xml file.
 137       *
 138       * @param string $uri
 139       * @param string $localName The local name (without prefix), or the empty string if
 140       *         Namespace processing is not being performed.
 141       * @param string $rawName The qualified name (with prefix), or the empty string if
 142       *         qualified names are not available.
 143       * @param string $attributes The specified or defaulted attributes
 144       */
 145  	public function startElement($name, $attributes) {
 146  
 147          try {
 148  
 149        $parentTag = $this->peekCurrentSchemaTag();
 150  
 151        if ($parentTag === false) {
 152  
 153                  switch($name) {
 154                      case "database":
 155                          if ($this->isExternalSchema()) {
 156                              $this->currentPackage = @$attributes["package"];
 157                              if ($this->currentPackage === null) {
 158                                  $this->currentPackage = $this->defaultPackage;
 159                              }
 160                          } else {
 161                              $this->currDB = $this->app->addDatabase($attributes);
 162                          }
 163                      break;
 164  
 165                      default:
 166                          $this->_throwInvalidTagException($name);
 167                  }
 168  
 169              } elseif  ($parentTag == "database") {
 170  
 171                  switch($name) {
 172  
 173                      case "external-schema":
 174                          $xmlFile = @$attributes["filename"];
 175  
 176                          //"referenceOnly" attribute is valid in the main schema XML file only,
 177                          //and it's ingnored in the nested external-schemas
 178                          if(!$this->isExternalSchema()) {
 179                              $isForRefOnly = @$attributes["referenceOnly"];
 180                              $this->isForReferenceOnly = ($isForRefOnly !== null ? (strtolower($isForRefOnly) === "true") : true); // defaults to TRUE
 181                          }
 182  
 183                          if ($xmlFile{0} != '/') {
 184                              $f = new PhingFile($this->currentXmlFile);
 185                              $xf = new PhingFile($f->getParent(), $xmlFile);
 186                              $xmlFile = $xf->getPath();
 187                          }
 188  
 189                          $this->parseFile($xmlFile);
 190                      break;
 191  
 192            case "domain":
 193                        $this->currDB->addDomain($attributes);
 194                    break;
 195  
 196                      case "table":
 197                          $this->currTable = $this->currDB->addTable($attributes);
 198                          if ($this->isExternalSchema()) {
 199                              $this->currTable->setForReferenceOnly($this->isForReferenceOnly);
 200                              $this->currTable->setPackage($this->currentPackage);
 201                          }
 202                      break;
 203  
 204                      case "vendor":
 205                          $this->currVendorObject = new ObjectWithVendorSpecificData($this->currDB, $attributes['type']);
 206                      break;
 207  
 208                      default:
 209                          $this->_throwInvalidTagException($name);
 210                  }
 211  
 212              } elseif  ($parentTag == "table") {
 213  
 214                  switch($name) {
 215                      case "column":
 216                          $this->currColumn = $this->currTable->addColumn($attributes);
 217                      break;
 218  
 219                      case "foreign-key":
 220                          $this->currFK = $this->currTable->addForeignKey($attributes);
 221                      break;
 222  
 223                      case "index":
 224                          $this->currIndex = $this->currTable->addIndex($attributes);
 225                      break;
 226  
 227                      case "unique":
 228                          $this->currUnique = $this->currTable->addUnique($attributes);
 229                      break;
 230  
 231                      case "vendor":
 232                          $this->currVendorObject = new ObjectWithVendorSpecificData($this->currTable, $attributes['type']);
 233                      break;
 234  
 235            case "validator":
 236                        $this->currValidator = $this->currTable->addValidator($attributes);
 237            break;
 238  
 239            case "id-method-parameter":
 240              $this->currTable->addIdMethodParameter($attributes);
 241                      break;
 242  
 243                      default:
 244                          $this->_throwInvalidTagException($name);
 245                  }
 246  
 247              } elseif  ($parentTag == "column") {
 248  
 249                  switch($name) {
 250                      case "inheritance":
 251                          $this->currColumn->addInheritance($attributes);
 252                      break;
 253  
 254                      case "vendor":
 255                          $this->currVendorObject = new ObjectWithVendorSpecificData($this->currColumn, $attributes['type']);
 256                      break;
 257  
 258                      default:
 259                          $this->_throwInvalidTagException($name);
 260                  }
 261  
 262              } elseif ($parentTag == "foreign-key") {
 263  
 264                  switch($name) {
 265                      case "reference":
 266                          $this->currFK->addReference($attributes);
 267                      break;
 268  
 269                      case "vendor":
 270                          $this->currVendorObject = new ObjectWithVendorSpecificData($this->currFK, $attributes['type']);
 271                      break;
 272  
 273                      default:
 274                          $this->_throwInvalidTagException($name);
 275                  }
 276  
 277              } elseif  ($parentTag == "index") {
 278  
 279                  switch($name) {
 280                      case "index-column":
 281                          $this->currIndex->addColumn($attributes);
 282                      break;
 283  
 284                      case "vendor":
 285                          $this->currVendorObject = new ObjectWithVendorSpecificData($this->currIndex, $attributes['type']);
 286                      break;
 287  
 288                      default:
 289                          $this->_throwInvalidTagException($name);
 290                  }
 291  
 292              } elseif ($parentTag == "unique") {
 293  
 294                  switch($name) {
 295                      case "unique-column":
 296                          $this->currUnique->addColumn($attributes);
 297                      break;
 298  
 299                      case "vendor":
 300                          $this->currVendorObject = new ObjectWithVendorSpecificData($this->currUnique, $attributes['type']);
 301                      break;
 302  
 303                      default:
 304                          $this->_throwInvalidTagException($name);
 305                  }
 306        } elseif ($parentTag == "validator") {
 307          switch($name) {
 308            case "rule":
 309                        $this->currValidator->addRule($attributes);
 310            break;
 311            default:
 312              $this->_throwInvalidTagException($name);
 313          }
 314              } elseif ($parentTag == "vendor") {
 315  
 316                  switch($name) {
 317                      case "parameter":
 318                          if($this->currVendorObject->isCompatible($this->platform->getDatabaseType())) {
 319                              $this->currVendorObject->setVendorParameter($attributes['name'], iconv('utf-8',$this->encoding, $attributes['value']));
 320                          }
 321                      break;
 322  
 323                      default:
 324                          $this->_throwInvalidTagException($name);
 325                  }
 326  
 327              } else {
 328                  // it must be an invalid tag
 329          $this->_throwInvalidTagException($name);
 330        }
 331  
 332              $this->pushCurrentSchemaTag($name);
 333  
 334          } catch (BuildException $e) {
 335              throw $e;
 336          } catch (Exception $e) {
 337              echo $e;
 338              echo "\n";
 339              throw $e;
 340          }
 341      }
 342  
 343  	function _throwInvalidTagException($tag_name)
 344      {
 345          throw new BuildException("Unexpected tag <" . $tag_name . ">", $this->parser->getLocation());
 346      }
 347  
 348      /**
 349       * Handles closing elements of the xml file.
 350       *
 351       * @param uri
 352       * @param localName The local name (without prefix), or the empty string if
 353       *         Namespace processing is not being performed.
 354       * @param rawName The qualified name (with prefix), or the empty string if
 355       *         qualified names are not available.
 356       */
 357  	public function endElement($name)
 358      {
 359          if (self::DEBUG) {
 360              print("endElement(" . $name . ") called\n");
 361          }
 362  
 363          $this->popCurrentSchemaTag();
 364      }
 365  
 366  	protected function peekCurrentSchemaTag()
 367      {
 368                  $keys = array_keys($this->schemasTagsStack);
 369          return end($this->schemasTagsStack[end($keys)]);
 370      }
 371  
 372  	protected function popCurrentSchemaTag()
 373      {
 374                  $keys = array_keys($this->schemasTagsStack);
 375          array_pop($this->schemasTagsStack[end($keys)]);
 376      }
 377  
 378  	protected function pushCurrentSchemaTag($tag)
 379      {
 380                  $keys = array_keys($this->schemasTagsStack);
 381          $this->schemasTagsStack[end($keys)][] = $tag;
 382      }
 383  
 384  	protected function isExternalSchema()
 385      {
 386          return (sizeof($this->schemasTagsStack) > 1);
 387      }
 388  
 389  	protected function isAlreadyParsed($filePath)
 390      {
 391          return isset($this->schemasTagsStack[$filePath]);
 392      }
 393  }
 394  
 395  /**
 396   * Utility class used for objects with vendor data.
 397   *
 398   * @package propel.engine.database.transform
 399   */
 400  class ObjectWithVendorSpecificData
 401  {
 402      protected $object;
 403      protected $vendorType;
 404  
 405  	public function __construct($object, $vendorType)
 406      {
 407          $this->object = $object;
 408          $this->vendorType = $vendorType;
 409      }
 410  
 411  	public function isCompatible($type)
 412      {
 413          return ($this->vendorType == $type);
 414      }
 415  
 416  	public function setVendorParameter($name, $value)
 417      {
 418          $this->object->setVendorParameter($name, $value);
 419      }
 420  }


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