Piotr Labudda il y a 6 ans
Parent
commit
204faebb53
2 fichiers modifiés avec 212 ajouts et 4 suppressions
  1. 196 3
      SE/se-lib/Route/Ant.php
  2. 16 1
      SE/se-lib/Route/UrlAction/Ant.php

+ 196 - 3
SE/se-lib/Route/Ant.php

@@ -104,16 +104,30 @@ class Route_Ant extends RouteBase {
 				// $pathUrlActions = '/Users/plabudda/rsync.se.master/SE/schema/ant-url_action'
 				// 0 => '/Users/plabudda/rsync.se.master/SE/schema/ant-url_action/default_db.in7_dziennik_koresp/etykieta/build.xml',
 				// 0 => 'default_db.in7_dziennik_koresp/etykieta/build.xml',
-				list($ns, $folderName, $buildXml) = explode('/', str_replace($pathUrlActions . '/', '', $filePath));
+				list($ns, $projectFolder, $buildXml) = explode('/', str_replace($pathUrlActions . '/', '', $filePath));
 				return [
 					'ns' => $ns,
-					'folderName' => $folderName,
+					'project' => $projectFolder,
 					'mtime' => filemtime($filePath),
 				];
 			}, $antFileList);
 			DBG::log($antMtimeFileList, 'array', "DBG::getAntUrlActionList glob + mtime");
 
-			throw new Exception("TODO: DBG: END.");
+			$forceUpdate = ('1' === V::get('forceUpdate', '', $_POST));
+			$antInfoList = array_map(function ($fileInfo) use ($forceUpdate) {
+				return $this->fetchProjectInfo($fileInfo, $forceUpdate);
+			}, $antMtimeFileList);
+			DBG::log($antInfoList, 'array', "DBG::getAntUrlActionList antInfoList");
+
+			$this->_antUrlProjects = array();
+			foreach ($antInfoList as $antInfo) {
+				$path = "{$antInfo['ns']}/{$antInfo['project']}";
+				$this->_antUrlProjects[$path] = $antInfo['label'];
+				foreach ($antInfo['main_targets'] as $targetInfo) {
+					$this->_antUrlProjectTemplates[$path][$targetInfo['target']] = $targetInfo['label'];
+				}
+			}
+			return $this->_antUrlProjects;
 		}
 
 		$this->_antUrlProjects = array();
@@ -130,6 +144,7 @@ class Route_Ant extends RouteBase {
 			$this->_antUrlProjects[$path] = $path;
 			try {
 				V::exec("cd {$this->pathUrlActions}/{$path} && ant -p|grep -v '^Unable to locate'|grep -v '^Buildfile:'", $out, $ret);
+				// ant -p 2>/dev/null |grep -v '^Unable to locate'|grep -v '^Buildfile:' | grep 'URL_TASK\|^Default target:'
 				// Test WFS for actions given featureID   // TODO: first line - project description
 				// Main targets:
 				//
@@ -172,6 +187,184 @@ class Route_Ant extends RouteBase {
 		DBG::log((array)$this, 'array', "DBG::getAntUrlActionList END Ant projects and main targets");
 		return $this->_antUrlProjects;
 	}
+	function prepareCache($fileInfo) {
+		// 'ns' => $ns,
+		// 'project' => $projectFolder,
+		// 'mtime' => filemtime($filePath),
+		$sql = "
+			CREATE TABLE IF NOT EXISTS `ANT_TOOL_#CACHE_PROJECT` (
+				`ID` int(11) NOT NULL AUTO_INCREMENT,
+
+				`file_ns` varchar(255) NOT NULL,
+				`file_project` varchar(255) NOT NULL,
+				`file_mtime` int(11) unsigned NOT NULL DEFAULT 0,
+
+				`label` varchar(255) DEFAULT '',
+				`error` varchar(255) DEFAULT '',
+
+				`is_active` tinyint(1) NOT NULL DEFAULT 0,
+				`A_RECORD_CREATE_DATE` datetime NOT NULL,
+				`A_RECORD_UPDATE_DATE` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+
+				PRIMARY KEY (`ID`),
+				KEY (`is_active`),
+				UNIQUE KEY `uniq` (`file_ns`,`file_project`)
+			) ENGINE=MyISAM DEFAULT CHARSET=latin2;
+		";
+		DB::getPDO()->execSql($sql);
+		$sql = "
+			CREATE TABLE IF NOT EXISTS `ANT_TOOL_#CACHE_MAIN_TARGETS` (
+				`ID_ANT_PROJECT` int(11) NOT NULL,
+				`NAME` varchar(255) DEFAULT '',
+				`LABEL` varchar(255) DEFAULT '',
+				`A_RECORD_CREATE_DATE` datetime NOT NULL,
+				KEY `ID_ANT_PROJECT` (`ID_ANT_PROJECT`),
+				UNIQUE KEY `uniq` (`ID_ANT_PROJECT`,`NAME`)
+			) ENGINE=MyISAM DEFAULT CHARSET=latin2;
+		";
+		DB::getPDO()->execSql($sql);
+	}
+	function fetchProjectInfo($fileInfo, $forceUpdate = false) {
+		$cacheInfo = DB::getPDO()->tryHandleException([ $this, 'prepareCache' ], 'fetchFirst', $args = [
+			"
+				select c.ID
+					, c.file_ns
+					, c.file_project
+					, c.file_mtime
+					, c.label
+				from `ANT_TOOL_#CACHE_PROJECT` c
+				where c.file_ns = :ns
+					and c.file_project = :project
+			",
+			[
+				':ns' => $fileInfo['ns'],
+				':project' => $fileInfo['project'],
+			]
+		]);
+		$parsedAntInfo = null;
+		DBG::log($cacheInfo, 'array', "DBG:cacheInfo");
+		if (!$cacheInfo) {
+			$errorMsg = "";
+			try {
+				$parsedAntInfo = $this->parseAntOutput("{$this->pathUrlActions}/{$fileInfo['ns']}/{$fileInfo['project']}");
+				DBG::log($parsedAntInfo, 'array', "DBG:parsedAntInfo when !\$cacheInfo");
+			} catch (Exception $e) {
+				$errorMsg = $e->getMessage();
+			}
+			$idCache = DB::getPDO()->insert('ANT_TOOL_#CACHE_PROJECT', [
+				'file_ns' => $fileInfo['ns'],
+				'file_project' => $fileInfo['project'],
+				'file_mtime' => $fileInfo['mtime'],
+				'label' => ($parsedAntInfo) ? $parsedAntInfo['label'] : '',
+				'error' => ($parsedAntInfo) ? '' : ( ($errorMsg) ? $errorMsg : 'Error' ),
+				'is_active' => ($errorMsg || !$parsedAntInfo) ? 0 : 1,
+				'A_RECORD_CREATE_DATE' => "NOW()",
+			]);
+			DB::getPDO()->execSql(" delete from `ANT_TOOL_#CACHE_MAIN_TARGETS` where ID_ANT_PROJECT = :id ", [ ':id' => $idCache ]);
+			if ($parsedAntInfo) foreach ($parsedAntInfo['main_targets'] as $targetInfo) {
+				DB::getPDO()->insert('ANT_TOOL_#CACHE_MAIN_TARGETS', [
+					'ID_ANT_PROJECT' => $idCache,
+					'NAME' => $targetInfo['target'],
+					'LABEL' => $targetInfo['label'],
+					'A_RECORD_CREATE_DATE' => "NOW()",
+				]);
+			}
+		}
+		else if ($cacheInfo['file_mtime'] < $fileInfo['mtime'] || $forceUpdate) {
+			// select c.ID,
+			// 	c.file_ns,
+			// 	c.file_project,
+			// 	c.file_mtime,
+
+			$errorMsg = "Error";
+			try {
+				$parsedAntInfo = $this->parseAntOutput("{$this->pathUrlActions}/{$fileInfo['ns']}/{$fileInfo['project']}");
+			} catch (Exception $e) {
+				$errorMsg = $e->getMessage();
+			}
+			DBG::log($parsedAntInfo, 'array', "DBG:parsedAntInfo when file_mtime > cache || forceUpdate({$forceUpdate})");
+			DB::getPDO()->update('ANT_TOOL_#CACHE_PROJECT', 'ID', $cacheInfo['ID'], [
+				'label' => ($parsedAntInfo) ? $parsedAntInfo['label'] : '',
+				'error' => ($errorMsg || !$parsedAntInfo) ? $errorMsg : '',
+				'A_RECORD_CREATE_DATE' => "NOW()",
+			]);
+			DB::getPDO()->execSql(" delete from `ANT_TOOL_#CACHE_MAIN_TARGETS` where ID_ANT_PROJECT = :id ", [ ':id' => $cacheInfo['ID'] ]);
+			if ($parsedAntInfo) foreach ($parsedAntInfo['main_targets'] as $targetInfo) {
+				DB::getPDO()->insert('ANT_TOOL_#CACHE_MAIN_TARGETS', [
+					'ID_ANT_PROJECT' => $cacheInfo['ID'],
+					'NAME' => $targetInfo['target'],
+					'LABEL' => $targetInfo['label'],
+					'A_RECORD_CREATE_DATE' => "NOW()",
+				]);
+			}
+		} else {
+			$parsedAntInfo = [
+				'label' => $cacheInfo['label'],
+				'main_targets' => DB::getPDO()->fetchAll("
+					select t.NAME as target
+						, t.LABEL as label
+					from `ANT_TOOL_#CACHE_MAIN_TARGETS` t
+					where t.ID_ANT_PROJECT = :id
+				", [
+					':id' => $cacheInfo['ID'],
+				]),
+			];
+		}
+
+		return array_merge($fileInfo, $parsedAntInfo);
+	}
+	function parseAntOutput($antFolderPath) { // return [ label, main_targets => [ target, label ] ], throws Exception
+		try {
+			V::exec("cd {$antFolderPath} && ant -p|grep -v '^Unable to locate'|grep -v '^Buildfile:'", $out, $ret);
+			// ant -p 2>/dev/null |grep -v '^Unable to locate'|grep -v '^Buildfile:' | grep 'URL_TASK\|^Default target:'
+			// Test WFS for actions given featureID   // TODO: first line - project description
+			// Main targets:
+			//
+			//  DescribeFeatureType  URL_TASK Target DescribeFeatureType
+			//  GetFeature           URL_TASK Target GetFeature
+			// Default target: http_first_input
+			if (empty($out)) throw new Exception("Missing ant -p output");
+			$projectDesc = '';
+			$mainTargets = [];
+			$state = 'projectDesc'; // 'projectDesc', 'Main targets', 'Default target'
+			foreach ($out as $line) {
+				switch ($state) {
+					case 'projectDesc': {
+						if ('Main targets' == substr($line, 0, strlen('Main targets'))) {
+							$state = 'Main targets';
+						} else {
+							$line = trim($line);
+							if (!$projectDesc && $line) $projectDesc = $line;
+						}
+					} break;
+					case 'Main targets': {
+						if (false !== ($pos = strpos($line, 'URL_TASK'))) {
+							$templateName = trim(substr($line, 0, $pos));
+							$label = trim(substr($line, $pos + 9));
+							if (!empty($templateName)) $mainTargets[] = [
+								'target' => $templateName,
+								'label' => (!empty($label)) ? $label : $templateName,
+							];
+						}
+						if ('Default target' == substr($line, 0, strlen('Default target'))) {
+							$state = 'Default target';
+						}
+					} break;
+				}
+				if ('Default target' === $state) break;
+			}
+			if (empty($projectDesc)) throw new Exception("Missing project label (first line in ant -p)");
+			if (empty($mainTargets)) throw new Exception("Missing main targets with type URL_TASK");
+			return [
+				'label' => $projectDesc,
+				'main_targets' => $mainTargets,
+			];
+		} catch (Exception $e) {
+			DBG::log($e);
+			throw $e;
+		}
+	}
+
 	public function getAntUrlActionTemplates($path) {
 		if (!empty($this->_antUrlProjectTemplates[$path])) return $this->_antUrlProjectTemplates[$path];
 		$this->getAntUrlActionList();

+ 16 - 1
SE/se-lib/Route/UrlAction/Ant.php

@@ -19,6 +19,15 @@ class Route_UrlAction_Ant extends Route_Ant {// @doc @see Route_Ant
     UI::gora();
     UI::menu();
     UI::startContainer();
+    
+    echo UI::hButtonPost("odśwież", [
+      'class' => "btn btn-link",
+      'form.class' => "pull-right",
+      'title' => "Wczytaj ponownie listę dostępnych funkcji",
+      'data' => [
+        'forceUpdate' => '1',
+      ]
+    ]);
     UI::tag('h1', [], 'Ant');
     try {
       $taskList = $this->getAntUrlActionList();
@@ -133,12 +142,18 @@ class Route_UrlAction_Ant extends Route_Ant {// @doc @see Route_Ant
       $uniqID = date("Y-m-d-H_i_s") . substr(md5(time()), 0, 6);// TODO: uniq id for every request
       // $cmd = "{$this->pathUrlActions}/{$path}/do_build.sh";
       $cmd = "cd {$this->pathUrlActions}/{$path} && ant -S";
+      // ant    -silent, -S            print nothing but task outputs and build failures
+      // ant    -D<property>=<value>   use value for given property
+      // ant    -propertyfile <name>   load all properties from file with -D properties taking precedence
+
+      // TODO: mv to build.properties file @see https://dzone.com/tutorials/java/ant/ant-properties-file.html
+      //   ant -propertyfile build.properties
       $cmd .= " -DoutputFunctionUrl='{$outputFunctionUrl}'";
       $cmd .= " -DantFunctionUrl='{$antFunctionUrl}'";
       if( strlen($confirmAntfile) > 0 ) $cmd .= " -DconfirmAntfile={$confirmAntfile}";
       if( strlen($confirmAntfileTarget) > 0 ) $cmd .= " -DconfirmAntfileTarget={$confirmAntfileTarget}";
       $cmd .= " -DwebRootUrl='{$webRootUrl}'";
-//      $cmd .= " -Durl='{$testUrl}'";  nie mozna tego uzywac, bo nadpisuje property w funkcji build_get_wfs.xml
+      // $cmd .= " -Durl='{$testUrl}'";  nie mozna tego uzywac, bo nadpisuje property w funkcji build_get_wfs.xml
       $cmd .= " -DpasswordBase64Basic=\"{$cryptedPass}\"";
       $cmd .= " -Duuid=\"{$uniqID}\"";
       $cmd .= " -Dphp_session_id=\"" . session_id() . "\"";