RemoteParamManager.php 8.14 KB
<?php
/**
 * @class RemoteParamManager 
 * @brief Manage Remote Data Centers via DDServer  
 */

class RemoteParamManager
{ 
	protected $Bases, $basesDom;	 	
	protected $baseDom;
	
	protected $center;
	
	public $xmlDom, $xmlName;
	public $paramId, $remoteViId, $localInfo, $paramDom, $paramXML;
 
	function __construct() 
	{
		if (!file_exists(RemoteData."Bases.xml"))
				return array("err" => "No Remote Data Bases");

		$this->basesDom = new DomDocument("1.0");
		if (!$this->basesDom->load(RemoteData."Bases.xml"))
				return array("err" => "Can not load Remote Data Bases definitions");
		$bases = $this->basesDom->getElementsByTagName('dataCenter');
		
		foreach ($bases as $base) 
			$this->Bases[] = $base->getAttribute('xml:id');
		
		if (!file_exists(USERWSDIR."RemoteParams.xml"))
				return array("err" => "No RemoteParams.xml");
				
		$this->xmlName = USERWSDIR."RemoteParams.xml";
		$this->xmlDom = new DomDocument("1.0");
		$this->xmlDom->load($this->xmlName);
	}

	/*
	*  get baseId from parameter descriptor
	*/
	protected function setBaseId($id) 
	{ 
		foreach ($this->Bases as $base) {
			// Special Themis case
			if (substr($id,0,2) == "th") {
				$baseId = "THEMIS";
				break;
			}
			if (strncmp($id, $base, strlen($base)) === 0) 
			{
				$baseId = $base;
				break;
			}
		}
		
		$this->center = new $baseId();         
	}
 
// <param xml:id="ace_r"><get><vi name="ace:orb:all"><baseParam name="R"/></vi></get>
// <process>$ace_orb_all_R/RADIUS_EARTH</process>
// <output/></param>
	public function makeInternalParamXml()
	{
		if (!$this->center->ViId) return false;
		if (!$this->center->ParamId) return false;
		
		$this->paramId = strtolower($this->center->baseID."_".$this->center->ViId."_".$this->center->ParamId);
		$xml = new DomDocument("1.0");
		$paramNode = $xml->createElement("param");
		$xml->appendChild($paramNode);
    
		$paramNode->setAttribute("xml:id", $this->paramId);
		$getNode =  $xml->createElement("get");
		$viNode =  $xml->createElement("vi");
		$baseParamNode = $xml->createElement("baseParam");
		$baseParamNode->setAttribute("name", $this->center->ParamId);
		$viNode->setAttribute("name", strtolower(strtr($this->center->ViId,"_", ":")));
		$viNode->appendChild($baseParamNode);
		$getNode->appendChild($viNode);		
		$paramNode->appendChild($getNode);
		$paramNode->appendChild($xml->createElement("process"));
		$paramNode->appendChild($xml->createElement("output"));
		 
		return $xml->save(RemoteData.$this->center->baseID."/".$this->paramId.".xml");
	}
	
	// TODO not used - too complicated
	protected function makeParamArgs()
	{
		$CURR_DIR = getcwd();
		rename($CURR_DIR ."/".$this->paramId.".xml", "/home/budnik/NEWMETA/final/".$this->paramId.".xml");		 
		chdir(NEWKERNEL_BASE_PATH."/app-generate-paraminfo");
	   $cmd = NEWKERNEL_INSTALL_DIR."/bin/DDLogin budnik Sacre-Cour";
	   $res = system($cmd);
		$cmd = NEWKERNEL_INSTALL_DIR."/bin/amdaParameterInfo -p ".$this->paramId;
		system($cmd, $res);
		$info_name = "info_".$this->paramId.".xml";
		rename($info_name, $CURR_DIR."/".$info_name);
		chdir($CURR_DIR);
		
		return $info_name;
	}
	
// 	protected function makeComponentsFromArgsFile($node, $info_file_name)
// 	{
// 		$xml = new DomDocument();
// 		$xml->load($info_file_name);
// 		
// 		$components = $xml->getElementsByTagName('component');
// 		if ($components->length > 0)
// 		{
// 			foreach ($components as $component)
// 			{
// 				$compNode = $this->xmlDom->createElement("component");
// 				$compNode->setAttribute('xml:id',$this->paramId.'('.$component->getAttribute("index_1").')');
// 				$component->setAttribute('name',$component->getAttribute("name")); // LABEL
// 				
// 				$node->appendChild($compNode);
// 			}
// 		}
// 	}

	protected function makeComponents($node, $size, $components)
 	{
		$compArray = explode(";",$components);
		
		for ($i = 0; $i < $size; $i++)
		{
			$compNode = $this->xmlDom->createElement("component");			
			$compNode->setAttribute('xml:id',$this->paramId."($i)");		
			$compNode->setAttribute('name',strtolower($compArray[$i])); // LABEL

			$node->appendChild($compNode);
		}
 	}
 	
	protected function addNode($id)
	{
		// Node exists already 
		if ($this->xmlDom->getElementById($id)) return true;

		// Node to be added
		$nodeRemote = $this->center->baseDom->getElementById($id);

		// No such node in base.xml
		if (!$nodeRemote) return false;

		if ($nodeRemote->tagName == 'dataset') 
		{
			$this->center->setViId($nodeRemote->getAttribute('name'));
			$status = $this->center->addViToDD();
		   // echo "STATUS $status".PHP_EOL;
			if (!$status) return false;
			$remoteDatasetInfo = "/home/budnik/DDBASE/INFO/bases/".$this->center->baseID."/".$this->center->infoFile; //TODO "http://apus.irap.omp.eu/
			$localDatasetInfo = RemoteData.$this->center->baseID."/".$this->center->infoFile;
			
			if (!copy($remoteDatasetInfo,$localDatasetInfo)) return false;
		}

		$node = $this->xmlDom->importNode($nodeRemote);

		if ($nodeRemote->tagName == 'parameter') 
		{
			$this->center->setParamId($nodeRemote->getAttribute('name'));
			$this->center->setViId($nodeRemote->parentNode->getAttribute('name'));
			$this->center->setInfoFile();
			
			if (!$this->makeInternalParamXml()) return false;
		 
			if (($size = $this->center->getParamSize()) > 1)
			{	
				// make components and args
				$components = $this->center->getParamComponents();	
				$this->makeComponents($node, $size, $components); // return false;							
			}
			 
// 			if ($res)
// 				$info_file_name = $this->makeParamArgs();
// 				
// 			if (!$this->makeComponentsFromArgsFile($node, $info_file_name)) return false;

		}
	
		$parentRemote= $nodeRemote->parentNode;		  
		$parentRemoteId = $parentRemote->getAttribute('xml:id');

		$parent = $this->xmlDom->getElementById($parentRemoteId);
		
		if (!$parent) 
		{
			$parent = $this->xmlDom->importNode($parentRemote); 		      
		}
		
		$parent->appendChild($node); 
                 
		$toAddDataCentertToDoc = false;

		while ($parent->tagName != 'dataCenter') 
		{
			$node = $parent;	
			$parentRemote = $parentRemote->parentNode;        
			$parentRemoteId = $parentRemote->getAttribute('xml:id');
			$parent = $this->xmlDom->getElementById($parentRemoteId);

			if (!$parent) 
			{
				if ($parentRemote->tagName == 'dataCenter') 
					$toAddDataCenterToDoc = true;
				$parent = $this->xmlDom->importNode($parentRemote);			   
				$parent->appendChild($node); 		      
			}          		        		     
		}	

		if ($toAddDataCenterToDoc) 
		{
			//TODO if this is necessary ???
			// special bases 'hand-made' descriptions
			$basesDom = new DomDocument("1.0");
			$basesDom -> load(RemoteData.'Bases.xml');
			$theBase = $basesDom->getElementById($parent->getAttribute('xml:id'));

			if ($theBase) $parent -> setAttribute('name', $theBase->getAttribute('name'));
			$this->xmlDom->documentElement->appendChild($parent);
		}
		
		return true;
	}
	
/*
*         PUBLIC FUNCTIONS
*/
	public function saveTree($obj) 
	{
	   $r = print_r($obj, true);
		if (count($obj) == 1) 
		{	    
			$id = $obj->id;
			
			if ($id == 'root') return array('res' => 'ok');

			$this->setBaseId($id);			
			$res = $this->addNode($id);	
			
			if ($res === false) return array("err" => "Cannot add node : $id");
		}
		else 
		{ 
			foreach ($obj as $o) 
			{
				$id = $o->id;	
				
				if ($id == 'root') continue;
				
				if (!$this->baseId) $this->setBaseId($id);				
				$res = $this->addNode($id);
				
				if ($res === false) return array("err" => "Cannot add node : $id");

			}
		}

		if (!$this->xmlDom->save($this->xmlName))
			return array("err" => "Cannot save RemoteParams.xml");
			
		return array('res' => 'ok');
	}
	
	public function deleteFromTree($obj) 
	{
		$id = $obj->id;
		$nodeToDelete = $this->xmlDom->getElementById($id);
		
		if (!$nodeToDelete) 
			return array("err" => "No such id : $id");
		
		$tagName = $nodeToDelete->tagName;
		
		while ( $tagName != "dataRoot" ) // "dataCenter" ?
		{
			$parentNode = $nodeToDelete->parentNode;
			$parentNode->removeChild($nodeToDelete);
			$otherChildren = $parentNode->getElementsByTagName($tagName);
			
			if ( $otherChildren->length > 0 ) 
					break;
					
			 $nodeToDelete = $parentNode;
			 $tagName = $nodeToDelete->tagName;
		}
		$this->xmlDom->save($this->xmlName);

		return array('res'=> $obj->id);
	}
}
?>