<?php

/**
 * A simple way to implement a web service that leverages BioMOBY. It is assumed that the service has 
 * already been registered via the BioMOBY dashboard.
 * 
 * This class really doesn't do much at the moment and could be compressed down to a single function
 * but in the future, it is anticipated that it will play more of a role in the construction and 
 * parsing of BioMOBY XML. 
 * 
 * @author: Julian Tonti-Filippini
 * @email: tontij01@student.uwa.edu.au
 * @version: 0.0
 * @date: 23-May-2007
 */
class moby_soap_factory {
	var $registry_endpoint = '';
	var $registry_uri = '';
	var $service_name = '';
	var $authority = '';
	var $wsdl_file = '';
	
	/**
	 * Constructor for a soap factory. Empty constructor for the time being
	 */
	function moby_soap_factory() {
	}
	
	/**
	 * Construct a new SOAP object using the specified parameters. Note that if the path to the WSDL file is 
	 * not provided or the file cannot be found, then it will be pulled down from the specified BioMOBY 
	 * registry.
	 * 
	 * @param string $type Either 'server' for a SOAP server or 'client' for a SOAP client
	 * @param string $registry_endpoint The location of the BioMOBY registry handler
	 * @param string $registry_uri The URI of the BioMOBY registry
	 * @param string $service_name The name of your service as registered with the BioMOBY registry
	 * @param string $authority The name of your authority as registered with the BioMOBY registry
	 * @param string $wsdl_file The path to the WSDL file that defines your service (default is empty).
	 * @return SoapServer|SoapClient A PHP SOAP server or SOAP client object depending on what was requested
	 * @exception on inability to retrieve WSDL from BioMOBY server
	 * @exception on inadequate filesystem permissions
 	 * @exception on inability to construct SOAP server/client
	 */
	function generate($type, $registry_endpoint, $registry_uri, $service_name, $authority, $wsdl_file='') {
		if ($type!='server' && $type!='client') throw new Exception('Error: invalid type. Legal values are \'server\' or \'client\'');
		if (!$registry_endpoint) throw new Exception('Error: missing registry endpoint at construction');
		if (!$registry_uri) throw new Exception('Error: missing registry uri at construction');
		if (!$service_name) throw new Exception('Error: missing service name at construction');
		if (!$authority) throw new Exception('Error: missing authority at construction');

		$this->registry_endpoint = $registry_endpoint;
		$this->registry_uri = $registry_uri;
		$this->service_name = $service_name;
		$this->authority = $authority;
		$this->wsdl_file = $wsdl_file;
		$this->load_wsdl();
 		
		return ($type=='server') ? new SoapServer($this->wsdl_file) : new SoapClient($this->wsdl_file);
	}
	
	/**
	 * Fetch a WSDL file from the BioMOBY server
	 * @return void
	 * @exception on inability to retrieve WSDL from BioMOBY server
	 * @exception on inadequate filesystem permissions 
	 */
	function load_wsdl() {
		if (!$this->wsdl_file) $this->wsdl_file = $this->service_name . '.wsdl';
		
		//If the WSDL file already exists, ensure that it is readable
		if (file_exists($this->wsdl_file)) {
			if (!is_readable($this->wsdl_file)) {
				throw new Exception('Error: unable to read WSDL file: ' . $this->wsdl_file);
			}
			return;
		}
		//Retrieve the WSDL from the BioMOBY server.
		try {
			$client = new SoapClient(null, array(
				'location' => $this->registry_endpoint,
				'uri'      => $this->registry_uri
			));
		
			$request = '<retrieveService><Service authURI="' . $this->authority . '" serviceName="' . $this->service_name . 
'"/></retrieveService>';
		
			$wsdl_string = $client->__soapCall('retrieveService', array($request), array(
				'soapaction' => $this->registry_uri . '#retrieveService',
				'uri' => $this->registry_uri
			));
			
			//Remove problematic wrapping
			$wsdl_string = ereg_replace('\<Service.*\<!\[CDATA\[', '', $wsdl_string);
			$wsdl_string = str_replace(']]></Service>', '', $wsdl_string);
		}
		catch (Exception $ex) {
			$ex->message .= '\nError: unable to retreive WSDL from BioMOBY registry';
			throw $ex;
		}
		
		//Cache the WSDL
		if  (!file_put_contents($this->wsdl_file, $wsdl_string)) {
			throw new Exception('Error: unable to write WSDL file: ' . $this->wsdl_file);
		}
	}	
}

?>

