29 #include "../data_structure/Application.h"
30 #include "../data_structure/ApplicationInstance.h"
50 #define SCENARIOMIMETYPE ".scx"
54 using namespace Data_Structure;
55 using namespace Parser;
64 tstruct = *localtime(&now);
67 ss << std::put_time(&tstruct,
"%Y-%m-%d.%X");
73 auto sctp = std::chrono::time_point_cast<std::chrono::system_clock::duration>(chronotp - T::clock::now()
74 + std::chrono::system_clock::now());
75 time_t time = std::chrono::system_clock::to_time_t(sctp);
77 tstruct = *localtime(&time);
80 ss << std::put_time(&tstruct,
"%Y-%m-%d.%X");
84 std::vector<std::string> XMLScenarioParser::getScenariosFromFolder(
const std::string& folder)
86 namespace fs = std::filesystem;
88 std::vector<std::string> result;
89 if (exists(scenarioDir))
93 for (std::filesystem::recursive_directory_iterator end, dir(scenarioDir);
96 if (dir->path().extension() ==
".scx")
98 result.push_back(fs::relative(dir->path(), scenarioDir).parent_path().string());
102 catch (std::exception& e)
111 ScenarioPtr XMLScenarioParser::parseScenario(
PackagePtr package, std::string scenName, std::string subfolder)
113 if (package ==
nullptr)
119 std::string appFolder = package->getScenarioPath();
120 appFolder.append(
"/");
121 if (!subfolder.empty())
123 appFolder.append(subfolder +
"/");
125 appFolder.append(scenName);
126 appFolder.append(
"/");
128 std::string path = appFolder;
129 path.append(scenName);
132 if (!std::filesystem::exists(std::filesystem::path(path)))
143 std::string globalConfigName;
150 globalConfigName =
"./config/global.cfg";
165 std::string lastWriteTime =
formatTTime(std::filesystem::last_write_time(std::filesystem::path(path)));
168 std::map<std::string, std::string> iceEnvVariables;
169 if (root_node.
has_node(
"iceEnvVariablesNode"))
175 std::string
value = iceEnvVariableNode.value();
176 iceEnvVariables[varName] =
value;
180 ScenarioPtr result(
new Scenario(name, creation, lastWriteTime, package, globalConfigName, subfolder, deploymentType, iceEnvVariables));
183 std::string appInstanceStr = application_node.attribute_value(
"instance");
184 std::string appName = application_node.attribute_value(
"name");
185 std::string packageName = application_node.attribute_value(
"package");
186 std::string nodeName;
189 nodeName = application_node.attribute_value(
"nodeName");
199 enabled = application_node.attribute_as_bool(
"enabled",
"true",
"false");
209 iceAutoRestart = application_node.attribute_as_bool(
"iceAutoRestart",
"true",
"false");
213 iceAutoRestart =
false;
216 CMakePackageFinder pFinder = CMakePackageFinderCache::GlobalCache.findPackage(packageName);
218 namespace fs = std::filesystem;
223 const std::string appExecutableName = [&]() -> std::string {
225 std::string executableName = application_node.attribute_value(
"executableName");
226 return executableName;
229 if(fs::exists(executableDir / (appName +
"Run")))
231 return appName +
"Run";
234 if(fs::exists(executableDir / (appName +
"AppRun")))
236 return appName +
"AppRun";
239 if(fs::exists(executableDir / (appName +
"_run")))
241 return appName +
"_run";
244 ARMARX_WARNING <<
"Scenario '" + name +
"': App `" + appName +
"` could not be found.";
253 if (appInstanceStr.empty())
255 appInstance = std::make_shared<ApplicationInstance>(*application, appInstanceStr, appFolder +
"config/" + appName +
".cfg", result, nodeName,
enabled, iceAutoRestart);
259 appInstance = std::make_shared<ApplicationInstance>(*application, appInstanceStr, appFolder +
"config/" + appName +
"." + appInstanceStr +
".cfg", result, nodeName,
enabled, iceAutoRestart);
261 appInstance->setNodeName(nodeName);
263 appInstance->updateFound();
264 result->addApplication(appInstance);
272 if (result->isGlobalConfigFileexistent())
274 cfgProperties->load(result->getGlobalConfigPath());
277 Ice::PropertyDict dict = cfgProperties->getPropertiesForPrefix(
"");
279 for (
auto const& property : dict)
281 result->getGlobalConfig()->defineOptionalProperty<std::string>(
property.first,
"::NOT_DEFINED::",
"Custom Property");
282 result->getGlobalConfig()->getProperties()->setProperty(property.first, property.second);
290 return parseScenario(scenario->getPackage(), scenario->getName(), scenario->getSubfolder());
293 bool XMLScenarioParser::isScenarioexistent(
const std::string &name,
PackagePtr package,
const std::string& subPath)
295 std::vector<std::string> paths = getScenariosFromFolder(package->getScenarioPath());
297 return std::find(paths.begin(), paths.end(), subPath + name) != paths.end();
302 std::string scenarioDir = package->getScenarioPath();
303 if (scenarioDir.empty())
305 throw LocalException(
"The scenarios directory variable of " + package->getName() +
" is empty - did you run CMake successfully?");
307 if (!package->isScenarioPathWritable())
309 ARMARX_WARNING_S <<
"Warning: Scenario Path is not writable. Unable to create a new Scenario.";
325 if (!std::filesystem::create_directories(scenarioDir.append(
"/").append(name)) ||
326 !std::filesystem::create_directories(scenarioDir +
"/config"))
328 ARMARX_ERROR_S <<
"Can not create Scenario in package " << package->getName();
337 std::ofstream out2(scenarioDir.append(
"/config/global.cfg"));
341 return parseScenario(package, name);
356 scenario->setLastChangedTime(currentDateStr);
359 scenarioNode.
append_attribute(
"globalConfigName", scenario->getGlobalConfigName());
360 scenarioNode.
append_attribute(
"package", scenario->getPackage()->getName());
365 std::map<std::string, std::string> iceEnvVariables = scenario->getIceEnviromentVariables();
366 if (!iceEnvVariables.empty())
369 for (
const auto& var : iceEnvVariables)
378 saveScenarioApplications(scenario, scenarioNode);
381 std::string path = scenario->getPath();
382 if (scenario->isScenarioFileWriteable())
388 saveScenarioGlobalConfig(scenario);
393 for (
auto package : *packages)
395 CMakePackageFinder pFinder = CMakePackageFinderCache::GlobalCache.findPackage(package->getName());
397 if (scenario->getPath().find(scenarioDir) != std::string::npos)
405 std::string XMLScenarioParser::getPackageNameFromScx(
const std::string& path)
409 if (!reader->getRoot(
"scenario").has_attribute(
"package"))
414 return reader->getRoot(
"scenario").attribute_value(
"package");
419 std::vector<ApplicationInstancePtr> applicationInstances = *scenario->getApplications();
420 for (
const auto &app : applicationInstances)
422 if (app->isConfigWritable())
438 void XMLScenarioParser::saveScenarioGlobalConfig(
ScenarioPtr scenario)
441 if (std::filesystem::is_symlink(scenario->getGlobalConfigPath()))
450 std::string resultStr;
454 pdcFormatter.setProperties(props->getProperties());
456 resultStr += pdcFormatter.formatPropertyDefinitionContainer(props);
459 size_t begin = resultStr.rfind(
"# Ice.Config:");
460 std::string ice_set_value =
"Ice.Config = <set value!>";
461 std::string ice_not_defined =
"Ice.Config = ::NOT_DEFINED::";
462 size_t end = resultStr.rfind(ice_set_value) + ice_set_value.length();
464 if (begin != std::string::npos)
466 if (end - ice_set_value.length() != std::string::npos)
468 resultStr.erase(begin, end - begin);
472 end = resultStr.rfind(ice_not_defined) + ice_not_defined.length();
473 if (end - ice_not_defined.length() != std::string::npos)
475 resultStr.erase(begin, end - begin);
480 std::ofstream cfgFile;
481 cfgFile.open(scenario->getGlobalConfigPath(), std::ofstream::out | std::ofstream::trunc);
482 if (cfgFile.fail() && scenario->isGlobalConfigWritable())
484 ARMARX_INFO_S <<
"Failed to write to Global Cfg file at " << scenario->getGlobalConfigPath();
487 cfgFile << resultStr;