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

class RemoteParamManager
{ 
	protected $Bases, $basesDom;	 	
	protected $baseDom;
	
	protected $center;
	
	public $xmlDom, $xmlName;
	public $baseId, $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");
				
		if (!is_dir(RemoteData."/PARAMS"))
				mkdir(RemoteData."/PARAMS", 0755, true);
				
		if (!is_dir(RemoteData."/PARAMS_INFO"))
				mkdir(RemoteData."/PARAMS_INFO", 0755, true);
				
		$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="imf">
//   <info>
//     <name>imf</name>
//     <short_name>b_gse</short_name>
//     <components>bx,by,bz</components>
//     <units>nT</units>
//     <coordinates_system>GSE</coordinates_system>
//     <tensor_order/>
//     <si_conversion>1e-9&gt;T</si_conversion>
//     <fill_value>-1.0E31</fill_value>
//     <ucd>phys.magField</ucd>
//     <dataset_id>ace-imf-all</dataset_id>
//     <instrument_id>ACE_MAG</instrument_id>
//   </info>
//   <get>
//      <vi name="ace:imf:all">
//         <baseParam name="IMF"/>
//     </vi>
//   </get>
//   <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);
		
		$xmlNameRemote = RemoteData."/PARAMS/".$this->paramId.".xml";
		$xmlNameTemp = PARAMS_LOCALDB_DIR."/".$this->paramId.".xml";
		
		if (file_exists($xmlNameRemote)) {
					return copy($xmlNameRemote, $xmlNameTemp);
		}
		
		$xml = new DomDocument("1.0");
		$paramNode = $xml->createElement("param");
		$xml->appendChild($paramNode);
    
		$paramNode->setAttribute("xml:id", $this->paramId);
		
		$infoNode = $xml->createElement("info");
		$infoNode->appendChild($xml->createElement("name",strtolower($this->center->ParamId)));
		$infoNode->appendChild($xml->createElement("short_name",strtolower($this->center->ParamId)));
		
		$size = $this->center->getParamSize();
		//TODO spectra components 
		if ($size > 1) 
		{	
			$components = strtolower($this->center->getParamComponents());	
		}
		else {
			$components = null;
		}
		
		$fillValue = $this->center->getParamFillValue();
		
		if (!$fillValue) 
				$fillValue = null;
				
		$infoNode->appendChild($xml->createElement("components",$components));
		$infoNode->appendChild($xml->createElement("units",$this->center->getParamUnits()));
		$infoNode->appendChild($xml->createElement("coordinates_system"));
		$infoNode->appendChild($xml->createElement("tensor_order"));
		$infoNode->appendChild($xml->createElement("si_conversion"));
		$infoNode->appendChild($xml->createElement("fill_value", $fillValue));
		$infoNode->appendChild($xml->createElement("ucd"));
		$infoNode->appendChild($xml->createElement("dataset_id",strtolower($this->center->ViId)));
		$infoNode->appendChild($xml->createElement("instrument_id",strtolower($this->center->baseID." ".$this->center->ViId)));
		
		$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($infoNode);
		$paramNode->appendChild($getNode);
		$paramNode->appendChild($xml->createElement("process"));
		$paramNode->appendChild($xml->createElement("output"));
		 
		$res = $xml->save($xmlNameRemote);
		if ($res) 
				return copy($xmlNameRemote, $xmlNameTemp);
		
		return $res;
	}
	
	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 
		$this->paramId = strtr(strtolower($id),":","_");
		
		if ($this->xmlDom->getElementById($this->paramId)) 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();
			
			if (!$status) return false;

			$remoteDatasetInfo = INFOSITE."/INFO/bases/".$this->center->baseID."/".$this->center->infoFile; 
			$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;							
			}
			
			// convert remote paramID into AMDA paramID			
			$node->setAttribute("xml:id", strtr(strtolower($node->getAttribute("xml:id")), ":","_"));
		}
	
		$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) 
	{	   
		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);
	}
	
	public function getInfoName($datasetId) {
	  
// 	      if ($this->baseId == 'CDAWEB')
// 				return  strtolower($datasetId)."_00000000_v01.cdf";
		return  $datasetId.'.xml';

	}
}
?>