<?php
/* --------------------------------------------------------------------------
* XIRE - eXtendable Information Rendering Engine
* --------------------------------------------------------------------------
* LICENSE
* Copyright (C) 2006 David Duong
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* -------------------------------------------------------------------------- */
require_once 'PluginManager.class.php';
/**
* A process that performs a breadth first traversal processing any XIRL nodes found. There
* can be multiple processes created by one template. Should only be created by
* {@see XIRE_Template::createProcess}.
*/
class XIRE_Process {
private $id;
private $template;
private $queue;
private static $pluginManager;
private static $lastId = 0;
public function __construct (XIRE_Template $template) {
isset(self::$pluginManager) or self::$pluginManager = new XIRE_PluginManager;
$this->id = self::$lastId++; // Generate process id
$this->template = $template;
$this->queue = array(); // Initiate queue
}
public function __get ($name) {
if ($name === 'template') {
return $this->template;
}
}
/**
* Adds a node to the processor's queue
* @throws DOM_WRONG_DOCUMENT_ERR if the given node does not belong to the template's
* document
*/
public function enqueue (DOMNode $node) {
if ($node->ownerDocument !== $this->template->document) {
throw new DOM_WRONG_DOCUMENT_ERR;
}
$this->queue[] = $node;
}
/**
* Performs breadth-first traversal on DOM and search for translatable elements, ie.
* those with the xire namespace, and calls the plugin that corresponds with the node's
* local name, ie. the name without the prefix. This will let the plugin deal with the
* child nodes so they will not be processed. Note: attributes are also considered
* nodes.
*
* This does not check for loops (which should not exist).
*/
public function process () {
while (!empty($this->queue)) {
$node = array_shift($this->queue);
if ($node->parentNode !== null) {
if ($node->namespaceURI === XIRL_NAMESPACE) {
self::$pluginManager->call($node, $this);
} else {
if ($node->childNodes instanceof DOMNodelist) {
foreach ($node->childNodes as $child) {
$this->queue[] = $child;
}
}
if ($node->attributes instanceof DOMNodelist) {
foreach ($node->attributes as $child) {
$this->queue[] = $child;
}
}
}
}
}
}
}
/**
* An exception that occured during the processing of the template
*/
class XIRE_ProcessingNodeException extends XIRE_Exception {
private $node;
public function __construct($message = 'Node processing exception', DOMNode $node = null, $code = 0) {
$this->node = $node;
parent::__construct($message, $code);
}
/**
* @return the node that caused the processing error
*/
public function getNode () {
return $this->node;
}
}
?>
|