<?php

/*******************************************************************************
 * Copyright (c) 2006 Eclipse Foundation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Wayne Beaton (Eclipse Foundation)- initial API and implementation
 *******************************************************************************/

#*****************************************************************************
#
# ** THIS FUNCTIONALITY IN THIS FILE IS DEPRECATED.
# ** USE THE XML_SIMPLE APIS INSTEAD.
#
# news.php
#
# Author: 		Wayne Beaton
# Date:			2005-11-07
#
# Description: This file contains code to assist with using a SAX parser
# on an XML file. Beware: it's weird.
#
#****************************************************************************

/*
 * This function does the actual work of parsing the RSS
 * file into an object representation. We use a SAX parser
 * to do this.
 * 
 * Note that this function is intended to be used with relatively
 * short files (the entire file contents are loaded into memory).
 * If the RSS files start to get too large, this method will need
 * to be updated.
 * @deprecated
 */
function parse_xml_file($file_name, & $file_handler) {
	$file_handler->initialize();
	
	// Read the entire file contents in to memory.
	// If file sizes get too large, we'll have to be smarter here.
	$file = fopen($file_name, "r");
	$xml = fread($file, filesize($file_name));
	fclose($file);
	
	parse_xml_string($xml, $file_handler);
}

function parse_xml_string($xml, & $file_handler) {
	$GLOBALS['handler'] = $file_handler;
	$parser = xml_parser_create();
	xml_set_element_handler($parser, 'sax_start_handler', 'sax_end_handler');
	xml_set_character_data_handler($parser, 'sax_data_handler');
	xml_parse($parser, $xml);
	if (xml_get_error_code($parser)) throw new SaxParsingException(xml_error_string($parser));
}

class SaxParsingException extends Exception {
	public function __construct($message, $code = 0) {
		parent::__construct($message, $code);
	}
}


/*
 * The $handler variable is global. It manages all the call backs
 * that come (indirectly) from the SAX parser.
 */
$handler = null;

/*
 * SAX parser callback method to handle the start of an element.
 * This method just defers to the global handler to do the actual
 * work.
 */
function sax_start_handler($parser, $name, $attributes) {
	global $handler;
	$handler->start($name, $attributes);
}

/*
 * SAX parser callback method to handle the text for an element.
 * This method just defers to the global handler to do the actual
 * work.
 */
function sax_data_handler($parser, $data) {
	global $handler;
	$handler->data($data);
}

/*
 * SAX parser callback method to handle the end of an element.
 * This method just defers to the global handler to do the actual
 * work.
 */
function sax_end_handler($parser, $name) {
	global $handler;
	$handler->end($name);
}

/*
 * The XmlHandler class is the focal point of the SAX parser callbacks.
 * It keeps track of a stack of element handlers. The element handlers
 * are used to handle whatever elements come in.
 */
class XmlFileHandler {
	var $stack;

	function XmlFileHandler() {
		$this->stack = array ();
	}
	
	function initialize() {
		$element_handler = $this->get_root_element_handler();
		array_push($this->stack, $element_handler);
	}
	
	function get_root_element_handler() {
		return new DoNothingHandler();
	}
	
	function end_root_element_handler($handler) {
	}

	/*
	 * Handle the start callback. Here, we get the current element handler
	 * from the top of the stack and ask it what to do. The element handler
	 * is asked to provide a new handler to handle the new element. That new
	 * handler is put on the top of the stack and will handle all future
	 * callbacks until it is removed (by the end method).
	 */
	function start($name, $attributes) {
		$handler = & array_last($this->stack);
		$next = & $handler->get_next($name, $attributes);
		array_push($this->stack, $next);
	}

	/*
	 * Data has been encountered, send the data to the current element handler
	 * to sort out what needs to be done.
	 */
	function data($data) {
		$handler = & array_last($this->stack);
		$handler->data($data);
	}

	/*
	 * The end of an element has occurred. Pop the current element handler
	 * from the top of the stack and tell it that it's work is done.
	 */
	function end($name) {
		$handler = & array_pop($this->stack);
		$handler->end($name);
		
		$next_handler = & array_last($this->stack);
		$next_handler->end_handler($name, $handler);
		
		// If we've just popped off the last actual element handler, leaving
		// only the root handler at the top of the stack, send it the end message.
		if (count($this->stack) == 1) 
			$this->end_root_element_handler($handler);
	}
}

class XmlElementHandler {
	function & get_next($name, $attributes) {
		$method_name = "get_" . str_replace("-", "_", $name) . "_handler";
		if (method_exists($this, $method_name)) {
			return $this->$method_name($attributes);
		} else {
			return new DoNothingHandler();
		}
	}

	function end_handler($name, $handler) {
		$method_name = "end_" . str_replace("-", "_", $name) . "_handler";
		if (method_exists($this, $method_name)) {
			return $this->$method_name($handler);
		} 
	}
	
	function initialize() {
	}
	
	/*
	 * Ignore data for this element.
	 */
	function data($data) {
	}

	function start($name) {
	}
	
	/*
	 * Ignore data for this element.
	 */
	function end($name) {
	}
}

class SimpleTextHandler extends XmlElementHandler {
	var $text;

	function & get_next($name, $attributes) {
		return new DoNothingHandler();
	}

	function data($data) {
		$this->text .= $data;
	}
	
	function end($name) {
		$this->text = html_entity_decode($this->text);
	}
}

class SimplePropertyHandler extends SimpleTextHandler {
	var $owner;
	var $property;

	function SimplePropertyHandler(& $owner, $property) {
		$this->owner = & $owner;
		$this->property = $property;
	}

	function end($name) {
		parent::end($name);
		$this->set_property_value($this->text);
	}

	function set_property_value(& $value) {
		$property = $this->property;
		$this->owner-> $property = $value;
	}
}

class DoNothingHandler extends XmlElementHandler {
	function & get_next($name, $attributes) {
		return $this;
	}
}

function & array_last(& $array) {
	return $array[count($array) - 1];
}

?>


