IHMInputOutputParamsAbstractClass.php 8.73 KB
<?php

/**
 * @class IHMInputOutputParamsAbstractClass
 * @brief Abstract class that's implement an InputOutputInterface used to treat input/output of a "param" (ie. download, data mining, plot, ...) request
 * @details
 */
abstract class IHMInputOutputParamsAbstractClass implements InputOutputInterface
{
	protected $paramManager      = null;
	protected $jobsManager       = null;
	
	protected $paramsData        = null;
	protected $requestID         = "";
	protected $requestDirPrefix  = "";
	protected $input             = null;
	protected $sendToSamp        = FALSE;

	/*
	 * @brief Constructor
	*/
	function __construct()
	{
		$this->paramManager     = new IHMParamManagerClass();
		$this->jobsManager      = new IHMJobsManagerClass();
	}

	/*
	 * @brief Generate a unique ID for the current request
	*/
	protected function generateNewRequestId()
	{
		$this->requestID = CommonClass::generateRandomString(6);
	}

	/*
	 * @brief Get working dir name
	*/
	protected function getWorkingDirName()
	{
		return $this->requestDirPrefix.$this->requestID."_";
	}

	/*
	 * @brief Get full working dir path
	*/
	protected function getWorkingPath()
	{
		return IHMConfigClass::getRequestPath().$this->getWorkingDirName().'/';
	}

	/*
	 * @brief Get Task
	 */
	protected function getTask($input)
	{
		if (isset($input->nodeType))
			return $input->nodeType;
		return NULL;
	}

	/*
	 * @brief Unmarshall the time definition from the IHM request
	*/
	protected function unmarshallTimeDefinition($input, $requestIndex, $ttFileIndex = -1, $ttIntIndex = -1)
	{
		$requestNodes = $this->paramsData->getRequestNodes();
		$timesNode = $requestNodes[$requestIndex]->getTimesNode();

		

		switch ($input->timesrc)
		{
			case "TimeTable" :
				if ($ttIntIndex >= 0) {
					if (($ttFileIndex >= 0) && ($ttFileIndex >= count($input->timeTables)))
							$ttFileIndex = 0;
					if($ttFileIndex < 0)
							$ttFileIndex =  count($input->timeTables) -1; 
				}

				$crtIndex = 0;
				foreach ($input->timeTables as $tt)
				{
					if (($ttFileIndex >= 0 ) && ($ttFileIndex != $crtIndex))
					{
						// Do not plot this TT
						++$crtIndex;
						continue;
					}
						
					if (strpos($tt->id, "sharedtimeTable_") === 0) {
						$result = IHMSharedObjectsClass::getPath("timeTable", $tt->id);
						if (!$result['success'])
							throw new Exception($result['message']);
						$ttPath = $result['path'];
					}
					else if (strpos($tt->id, "sharedcatalog_") === 0) {
						$result = IHMSharedObjectsClass::getPath("catalog", $tt->id);
						if (!$result['success'])
							throw new Exception($result['message']);
						$ttPath = $result['path'];
					}
					else {
						$ttPath = IHMConfigClass::getUserTTPath();
						$ttPath .= ($tt->id.".xml");
					}
					
					if ((strpos($tt->id, "cat_") === 0) || (strpos($tt->id, "sharedcatalog_") === 0))
						$timesNode->addCatalog($ttPath, $tt->{'timeTableName'}, $ttIntIndex);
					else
						$timesNode->addTimeTable($ttPath, $tt->{'timeTableName'}, $ttIntIndex);
					++$crtIndex;
				}
				break;
			case "Interval" :
				date_default_timezone_set('UTC');
				$start = CommonClass::strTimeToDDTime($input->startDate);
				$duration = CommonClass::getDurationDDTime($input->stopDate, $input->startDate);
				$timesNode->addInterval($start, $duration);
				break;
			default :
				throw new Exception('Time source type not implemented.');
		}
	}

	/*
	 * @brief Add a job to the job manager
	*/
	protected function addToJobsFile($data,$resultKey)
	{
		$waitingResult = $data->getWaitingResult($resultKey);
		if ($this->sendToSamp && ($data->getStatus() == ProcessStatusEnumClass::DONE)) {
			$waitingResult = explode("\n", file_get_contents(IHMConfigClass::getRequestPath()."/".$this->getWorkingDirName()."/".$waitingResult));
			$waitingResult = implode(',', $waitingResult);
			$waitingResult = rtrim($waitingResult, ',');
		}

		return $this->jobsManager->addJob(
				$this->input,
				$data->getId(),
				$this->getWorkingDirName(),
				$data->getStatus() == ProcessStatusEnumClass::RUNNING,
				$data->getStart(),
				$waitingResult,
				$data->getErrorCode(),
				$data->getExecTime());
	}
	
	/*
	 * @brief Delete current working dir + delete jobs that use this working dir + delete process
	 */
	protected function deleteWorkingDir()
	{
		$res = $this->jobsManager->getJobsByWorkingDir($this->getWorkingDirName());
		
		if (!$res['success'])
			return;
		
		foreach ($res['jobs'] as $jobId)
		{
			//delete process
			$deleteData = new ProcessRequestDataClass();
			$deleteData->setManagerFilePath(IHMConfigClass::getProcessManagerFilePath());
			$deleteData->setType(ProcessTypeEnumClass::DELETE);
			$deleteData->setId($jobId);
			$deleteData->setUser(IHMConfigClass::getUserName());
				
			$processRequest = new ProcessRequestClass();
			$processRequest->setData($deleteData);

			if ($processRequest->init())
				$processRequest->run();
			
			//delete job and working dir
			$this->jobsManager->deleteJob($jobId);
		}
	}
	/*
	 * @brief Marshall request result for the IHM client
	*/
	protected function commonMarshallResult($data,$resultKey)
	{
		if (!$data->getSuccess())
			return array(
					'success' => false,
					'message' => $data->getLastErrorMessage());

		switch ($data->getStatus())
		{
			case ProcessStatusEnumClass::ERROR :
			case ProcessStatusEnumClass::RUNNING :
			case ProcessStatusEnumClass::DONE :
				return $this->addToJobsFile($data,$resultKey);
			default :
				return array(
				'success' => false,
				'message'   => 'Unknown Process Status');
		}
	}

	/*
	 * @brief translate input data from IHM client to AMDA_Integration module for a "param" request
	*/
	public function getInputData($input,$function,$requestId = "")
	{
		if (isset($this->paramsData))
			unset($this->paramsData);

		$this->paramsData = new ParamsRequestDataClass();
		if ($requestId == "")
		{
			$this->requestDirPrefix = "DD";
			$this->generateNewRequestId();
		}
		else
		{
			$this->requestDirPrefix = "";
			$this->requestID = $requestId;
		}
		$this->paramsData->setWorkingPath($this->getWorkingPath());
		$this->paramsData->setCompilationPath(IHMConfigClass::getCompilationPath());
		$this->paramsData->setLocalBasePath(IHMConfigClass::getLocalBasePath());
		$this->paramsData->setManagerFilePath(IHMConfigClass::getProcessManagerFilePath());
		$this->paramsData->setTask($this->getTask($input));
		$this->paramsData->setUser(IHMConfigClass::getUserName());
		$this->input = $input;

		$this->unmarshallRequest($input);

		$this->checkLocalParamsRestriction();
		
		return $this->paramsData;
	}

	/*
	 * @brief translate output data from AMDA_Integration module to IHM client for a "param" request
	*/
	public function getOutput($data)
	{
		return $this->marshallResult($data);
	}

	/*
	 * @brief check restriction access to local parameters
	 */
	private function checkLocalParamsRestriction()
	{
		$userLocalTreePath = IHMConfigClass::getUserLocalTreePath();
		if (!file_exists($userLocalTreePath)) {
			throw new Exception('Cannot retrieve user local tree.');
		}

		$xml = new DOMDocument();
		$xml->preserveWhiteSpace = TRUE;
		if (!@$xml->load($userLocalTreePath)) {
			throw new Exception('Cannot load user local tree.');
		}

		$xp = new DOMXpath($xml);

		foreach ($this->paramsData->getParamsToCopy() as $key => $value) {
			$paramId = $key;
			if ($info = $this->paramManager->getTemplateParamsManager()->parseTemplatedParam($key)) {
				$paramId = $info['paramid'];
			}
			$paramNodes = $xp->query("//parameter[@xml:id='".$paramId."']");
			if ($paramNodes->length == 0) {
				continue;
			}
			$paramNode = $paramNodes->item(0);
			$datasetNode = $paramNode->parentNode;
			$inGroup = FALSE;
			if (isset($datasetNode)) {
				$crtNode = $datasetNode;
				do {
					if ($crtNode->hasAttribute("group") && ($crtNode->getAttribute("group") != "")) {
						$inGroup = TRUE;
					}
					$crtNode = $crtNode->parentNode;
				} while(isset($crtNode) && ($crtNode != $xml->documentElement) && !$inGroup);
			}
			if ($inGroup) {
				if ($datasetNode->hasAttribute("timeRestriction") && ($datasetNode->getAttribute("timeRestriction") != "")) {
					$timeRestriction = $datasetNode->getAttribute("timeRestriction");
					$this->paramsData->addParamTimeRestriction($key, $timeRestriction);
				}
				else {
					throw new Exception('Not allowed. Access to parameter '.$key.' is restricted');
				}
			}
		}
	}

	/*
	 * @brief Abstract method to unmarshall a "param" request
	*/
	abstract protected function unmarshallRequest($input);

	/*
	 * @brief Abstract method to marshall the result of a "param" request
	*/
	abstract protected function marshallResult($data);
}

?>