PageRenderTime 43ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel-generator/classes/propel/engine/database/transform/XmlToAppData.php

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