33#include <boost/regex.hpp>
35#include <Ice/Properties.h>
58 std::string configPath = app->getConfigPath();
62 if (!std::filesystem::exists(std::filesystem::path(configPath)))
64 std::ofstream out(configPath);
73 cfgProperties->load(configPath);
76 std::filesystem::path xmlPath =
77 std::filesystem::path(cachePath) / std::filesystem::path(
"ComponentFiles") /
78 std::filesystem::path(app->getPackageName() +
"." + app->getName() +
".xml");
79 if (!std::filesystem::exists(xmlPath))
81 ARMARX_INFO_S <<
"Could not find cached XML file at " << xmlPath;
83 result->setProperties(cfgProperties);
89 Ice::PropertyDict dict = cfgProperties->getPropertiesForPrefix(
"");
90 for (
auto const& property : dict)
93 if (!app->isDefaultProperty(property.first))
95 xmlProperties->defineOptionalProperty(
96 property.first, property.second,
"No Description");
97 xmlProperties->getProperties()->setProperty(property.first, property.second);
98 app->setIsDefaultProperty(property.first,
false);
105 if (property.second.compare(
"<set value!>") &&
106 property.second.compare(
"::_NOT_SET_::"))
108 app->setDefaultPropertyEnabled(property.first,
true);
109 xmlProperties->getProperties()->setProperty(property.first, property.second);
115 return xmlProperties;
129 container->setProperties(properties);
136 const boost::regex e(
"<!-- ([a-zA-Z0-9_]+) properties -->");
137 boost::match_results<std::string::const_iterator> what;
139 bool found = boost::regex_search(contents, what, e);
143 app->setConfigDomain(what[1]);
149 ARMARX_INFO <<
"App `" << app->getName() <<
"` not found.";
158 ARMARX_INFO_S <<
"It is most likely that the file has no valid XML formatting" << std::endl;
163 property_node = property_node.next_sibling())
165 const std::string propertyName = property_node.attribute_value(
"name");
166 const std::string description = property_node.first_node(
"description").value();
171 Ice::StringSeq valueStrings;
172 if (values.is_valid())
177 valueStrings.push_back(current_value.
value());
181 if (!valueStrings.empty())
187 std::string defaultValue =
"";
189 bool required =
false;
191 while (current_attribute.
is_valid())
194 if (current_attribute.
name().compare(
"attribute") != 0)
197 else if (current_attribute.
attribute_value(
"name").find(
"Default") != std::string::npos)
199 defaultValue = current_attribute.
value();
201 else if (current_attribute.
attribute_value(
"name").find(
"CaseSensitivity") !=
208 if (current_attribute.
value().compare(
"yes") == 0)
219 container->defineRequiredProperty<std::string>(propertyName, description);
221 for (
auto& v : valueStrings)
225 container->getProperties()->setProperty(propertyName,
"::_NOT_SET_::");
230 container->defineOptionalProperty(propertyName, defaultValue, description);
232 for (
auto& v : valueStrings)
236 container->getProperties()->setProperty(propertyName, defaultValue);
242 app->setIsDefaultProperty(propertyName,
true);
243 app->setDefaultPropertyEnabled(propertyName,
false);
255 if (!appInstance->isConfigWritable())
265 std::string resultStr;
273 Ice::PropertyDict dict = props->getProperties()->getPropertiesForPrefix(
"");
276 for (
auto const& property : dict)
278 if (appInstance->isDefaultProperty(property.first) &&
279 !appInstance->isDefaultPropertyEnabled(property.first))
281 disableProperty(resultStr, property.first);
286 size_t begin = resultStr.rfind(
"# Ice.Config:");
287 size_t end = resultStr.rfind(
"Ice.Config = <set value!>");
289 if (end == std::string::npos)
291 (end = resultStr.rfind(
"Ice.Config = \"\"")) != std::string::npos ? end += 15
292 : end = std::string::npos;
298 if (begin != std::string::npos && end != std::string::npos)
300 resultStr.erase(begin, end - begin);
303 std::ofstream cfgFile;
304 cfgFile.open(appInstance->getConfigPath(), std::ofstream::out | std::ofstream::trunc);
308 ARMARX_WARNING_S <<
"Failed to write to Cfg file at " << appInstance->getConfigPath();
312 cfgFile << resultStr;
321 return (std::filesystem::path(cachePath) / std::filesystem::path(
"ComponentFiles")).string();
325IceParser::disableProperty(std::string& result,
const std::string propertyName)
328 if (result.find_last_of(propertyName) != std::string::npos)
330 size_t it1 = result.rfind(propertyName +
" = ");
331 std::string commentedName =
"# " + propertyName +
" = ";
332 size_t it2 = result.find(commentedName, it1);
334 if (it1 != std::string::npos && it2 == std::string::npos)
336 result.insert(it1,
"# ");
344 std::filesystem::remove_all(std::filesystem::path(
getCacheDir()));
armarx::PropertyDefinitionsPtr mergeXmlAndCfg(ScenarioManager::Data_Structure::ApplicationInstanceWPtr app, bool firstLoad=false)
armarx::PropertyDefinitionsPtr loadFromXml(std::string path, ScenarioManager::Data_Structure::ApplicationInstanceWPtr app=ScenarioManager::Data_Structure::ApplicationInstancePtr(nullptr))
static std::string getCacheDir()
void saveCfg(ScenarioManager::Data_Structure::ApplicationInstanceWPtr appInstance)
static void clearXmlCacheDir()
static std::string GetCachePath()
The base Cache directory of ArmarX.
IceProperties stores ice properties and resolves property inheritance.
virtual void setInheritanceSolver(const InheritanceSolverPtr &inheritanceSolver)
Sets an inheritance solver in case of testing or using a non-default solver.
static Ice::PropertiesPtr create(const Ice::PropertiesPtr &iceProperties=nullptr)
PropertyDefinitionContainer.
PropertyDefinition defines a property that will be available within the PropertyUser.
PropertyDefinition< PropertyType > & setCaseInsensitive(bool isCaseInsensitive)
Sets whether the property value matching is case insensitive.
PropertyDefinition< PropertyType > & map(const std::string &valueString, PropertyType value)
Maps a string value onto a value of the specified template type.
RapidXmlReaderNode first_node(const char *name=nullptr) const
RapidXmlReaderNode next_sibling(const char *name=nullptr) const
std::string attribute_value(const char *attrName) const
std::string value() const
static std::string ReadFileContents(const std::string &path)
static RapidXmlReaderPtr FromXmlString(const std::string &xml)
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_INFO
The normal logging level.
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
::IceInternal::Handle<::Ice::Properties > PropertiesPtr
std::weak_ptr< ApplicationInstance > ApplicationInstanceWPtr
std::shared_ptr< ApplicationInstance > ApplicationInstancePtr
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::shared_ptr< RapidXmlReader > RapidXmlReaderPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.