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";
155 std::string lastWriteTime =
formatTTime(std::filesystem::last_write_time(std::filesystem::path(path)));
158 std::map<std::string, std::string> iceEnvVariables;
159 if (root_node.
has_node(
"iceEnvVariablesNode"))
165 std::string
value = iceEnvVariableNode.value();
166 iceEnvVariables[varName] =
value;
170 ScenarioPtr result(
new Scenario(name, creation, lastWriteTime, package, globalConfigName, subfolder));
173 std::string appInstanceStr = application_node.attribute_value(
"instance");
174 std::string appName = application_node.attribute_value(
"name");
175 std::string packageName = application_node.attribute_value(
"package");
176 std::string appNodeName;
179 appNodeName = application_node.attribute_value(
"appNodeName");
189 enabled = application_node.attribute_as_bool(
"enabled",
"true",
"false");
196 CMakePackageFinder pFinder = CMakePackageFinderCache::GlobalCache.findPackage(packageName);
198 namespace fs = std::filesystem;
203 const std::string appExecutableName = [&]() -> std::string {
205 std::string executableName = application_node.attribute_value(
"executableName");
206 return executableName;
209 if(fs::exists(executableDir / (appName +
"Run")))
211 return appName +
"Run";
214 if(fs::exists(executableDir / (appName +
"AppRun")))
216 return appName +
"AppRun";
219 if(fs::exists(executableDir / (appName +
"_run")))
221 return appName +
"_run";
224 ARMARX_WARNING <<
"Scenario '" + name +
"': App `" + appName +
"` could not be found.";
233 if (appInstanceStr.empty())
235 appInstance = std::make_shared<ApplicationInstance>(*application, appInstanceStr, appFolder +
"config/" + appName +
".cfg", result, appNodeName,
enabled);
239 appInstance = std::make_shared<ApplicationInstance>(*application, appInstanceStr, appFolder +
"config/" + appName +
"." + appInstanceStr +
".cfg", result, appNodeName,
enabled);
241 appInstance->setNodeName(appNodeName);
243 appInstance->updateFound();
244 result->addApplication(appInstance);
252 if (result->isGlobalConfigFileexistent())
254 cfgProperties->load(result->getGlobalConfigPath());
257 Ice::PropertyDict dict = cfgProperties->getPropertiesForPrefix(
"");
259 for (
auto const& property : dict)
261 result->getGlobalConfig()->defineOptionalProperty<std::string>(
property.first,
"::NOT_DEFINED::",
"Custom Property");
262 result->getGlobalConfig()->getProperties()->setProperty(property.first, property.second);
270 return parseScenario(scenario->getPackage(), scenario->getName(), scenario->getSubfolder());
273 bool XMLScenarioParser::isScenarioexistent(
const std::string &name,
PackagePtr package,
const std::string& subPath)
275 std::vector<std::string> paths = getScenariosFromFolder(package->getScenarioPath());
277 return std::find(paths.begin(), paths.end(), subPath + name) != paths.end();
282 std::string scenarioDir = package->getScenarioPath();
283 if (scenarioDir.empty())
285 throw LocalException(
"The scenarios directory variable of " + package->getName() +
" is empty - did you run CMake successfully?");
287 if (!package->isScenarioPathWritable())
289 ARMARX_WARNING_S <<
"Warning: Scenario Path is not writable. Unable to create a new Scenario.";
303 if (!std::filesystem::create_directories(scenarioDir.append(
"/").append(name)) ||
304 !std::filesystem::create_directories(scenarioDir +
"/config"))
306 ARMARX_ERROR_S <<
"Can not create Scenario in package " << package->getName();
315 std::ofstream out2(scenarioDir.append(
"/config/global.cfg"));
319 return parseScenario(package, name);
322 void XMLScenarioParser::saveScenario(
const ScenarioWPtr& wScenario,
bool saveApplications)
334 scenario->setLastChangedTime(currentDateStr);
337 scenarioNode.
append_attribute(
"globalConfigName", scenario->getGlobalConfigName());
338 scenarioNode.
append_attribute(
"package", scenario->getPackage()->getName());
342 saveScenarioApplications(scenario, scenarioNode, saveApplications);
345 std::string path = scenario->getPath();
346 if (scenario->isScenarioFileWriteable())
352 saveScenarioGlobalConfig(scenario);
357 for (
auto package : *packages)
359 CMakePackageFinder pFinder = CMakePackageFinderCache::GlobalCache.findPackage(package->getName());
361 if (scenario->getPath().find(scenarioDir) != std::string::npos)
369 std::string XMLScenarioParser::getPackageNameFromScx(
const std::string& path)
373 if (!reader->getRoot(
"scenario").has_attribute(
"package"))
378 return reader->getRoot(
"scenario").attribute_value(
"package");
383 std::vector<ApplicationInstancePtr> applicationInstances = *scenario->getApplications();
384 for (
const auto &app : applicationInstances)
386 if (saveApplications && app->isConfigWritable())
401 void XMLScenarioParser::saveScenarioGlobalConfig(
ScenarioPtr scenario)
404 if (std::filesystem::is_symlink(scenario->getGlobalConfigPath()))
413 std::string resultStr;
417 pdcFormatter.setProperties(props->getProperties());
419 resultStr += pdcFormatter.formatPropertyDefinitionContainer(props);
422 size_t begin = resultStr.rfind(
"# Ice.Config:");
423 std::string ice_set_value =
"Ice.Config = <set value!>";
424 std::string ice_not_defined =
"Ice.Config = ::NOT_DEFINED::";
425 size_t end = resultStr.rfind(ice_set_value) + ice_set_value.length();
427 if (begin != std::string::npos)
429 if (end - ice_set_value.length() != std::string::npos)
431 resultStr.erase(begin, end - begin);
435 end = resultStr.rfind(ice_not_defined) + ice_not_defined.length();
436 if (end - ice_not_defined.length() != std::string::npos)
438 resultStr.erase(begin, end - begin);
443 std::ofstream cfgFile;
444 cfgFile.open(scenario->getGlobalConfigPath(), std::ofstream::out | std::ofstream::trunc);
445 if (cfgFile.fail() && scenario->isGlobalConfigWritable())
447 ARMARX_INFO_S <<
"Failed to write to Global Cfg file at " << scenario->getGlobalConfigPath();
450 cfgFile << resultStr;