IceProperties.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarXCore::core
19 * @author Jan Issac (jan dot issac at mail dot com)
20 * @date 2014
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25#include "IceProperties.h"
26
27#include <Ice/Initialize.h>
28
31
32namespace armarx
33{
36 {
37 Ice::StringSeq strSeq;
38
39 return new IceProperties(Ice::createProperties(strSeq, iceProperties));
40 }
41
43 IceProperties::create(Ice::StringSeq& propertySeq, const Ice::PropertiesPtr& iceProperties)
44 {
45 Ice::PropertiesPtr armarxIceProperties =
46 new IceProperties(Ice::createProperties(propertySeq, iceProperties));
47
48 // adds all options and properties
49 armarxIceProperties->parseCommandLineOptions(std::string(), propertySeq);
50
51 return armarxIceProperties;
52 }
53
55 IceProperties::create(int& argn, char* argv[], const Ice::PropertiesPtr& iceProperties)
56 {
57 Ice::PropertiesPtr armarxIceProperties =
58 new IceProperties(Ice::createProperties(argn, argv, iceProperties));
59
60 Ice::StringSeq propertySeq = Ice::argsToStringSeq(argn, argv);
61
62 // adds all options and properties
63 armarxIceProperties->parseCommandLineOptions(std::string(), propertySeq);
64
65 return armarxIceProperties;
66 }
67
69 internalProperties(iceProperties), modified(true)
70 {
71 inheritanceSolver = new InheritanceSolver();
72 }
73
74 IceProperties::IceProperties(const IceProperties& source) : Shared(source)
75 {
76 internalProperties = source.internalProperties->clone();
77 modified = source.modified;
78 if (source.inheritanceSolver)
79 {
80 inheritanceSolver = new InheritanceSolver(*source.inheritanceSolver);
81 }
82 }
83
87
88 std::string
89 IceProperties::getProperty(const ::std::string& name) ICE_NOEXCEPT
90 {
91 update();
92
93 return internalProperties->getProperty(name);
94 }
95
96 std::string
97 IceProperties::getPropertyWithDefault(const ::std::string& name,
98 const ::std::string& defaultValue) ICE_NOEXCEPT
99 {
100 update();
101
102 return internalProperties->getPropertyWithDefault(name, defaultValue);
103 }
104
105 Ice::Int
106 IceProperties::getPropertyAsInt(const ::std::string& name) ICE_NOEXCEPT
107 {
108 update();
109
110 return internalProperties->getPropertyAsInt(name);
111 }
112
113 Ice::Int
115 ::Ice::Int defaultValue) ICE_NOEXCEPT
116 {
117 update();
118
119 return internalProperties->getPropertyAsIntWithDefault(name, defaultValue);
120 }
121
122 Ice::StringSeq
123 IceProperties::getPropertyAsList(const ::std::string& name) ICE_NOEXCEPT
124 {
125 update();
126
127 return internalProperties->getPropertyAsList(name);
128 }
129
130 Ice::StringSeq
132 const ::Ice::StringSeq& defaultValue) ICE_NOEXCEPT
133 {
134 update();
135
136 return internalProperties->getPropertyAsListWithDefault(name, defaultValue);
137 }
138
139 Ice::PropertyDict
140 IceProperties::getPropertiesForPrefix(const ::std::string& prefix) ICE_NOEXCEPT
141 {
142 update();
143
144 return internalProperties->getPropertiesForPrefix(prefix);
145 }
146
147 void
148 IceProperties::setProperty(const ::std::string& name, const ::std::string& value)
149 {
150 internalProperties->setProperty(name, value);
151 setModified(true);
152 }
153
154 Ice::StringSeq
156 {
157 update();
158
159 return internalProperties->getCommandLineOptions();
160 }
161
162 Ice::StringSeq
163 IceProperties::parseCommandLineOptions(const ::std::string& prefix,
164 const ::Ice::StringSeq& options)
165 {
166 Ice::StringSeq optionSeq = internalProperties->parseCommandLineOptions(prefix, options);
167
168 setModified(true);
169 update();
170
171 return optionSeq;
172 }
173
174 Ice::StringSeq
175 IceProperties::parseIceCommandLineOptions(const ::Ice::StringSeq& options)
176 {
177 Ice::StringSeq optionSeq = internalProperties->parseIceCommandLineOptions(options);
178
179 setModified(true);
180 update();
181
182 return optionSeq;
183 }
184
185 void
186 IceProperties::load(const ::std::string& fileName)
187 {
188 internalProperties->load(fileName);
189
190 setModified(true);
191 }
192
194 IceProperties::clone() ICE_NOEXCEPT
195 {
196 // return new IceProperties(*this);
197 return internalProperties->clone();
198 }
199
200 void
201 IceProperties::setModified(bool mod)
202 {
203 this->modified = mod;
204 }
205
206 bool
207 IceProperties::isModified()
208 {
209 return modified;
210 }
211
212 void
213 IceProperties::update()
214 {
215 if (isModified())
216 {
217 if (inheritanceSolver.get() != nullptr)
218 {
219 inheritanceSolver->resolveInheritance(internalProperties);
220 }
221 }
222
223 setModified(false);
224 }
225
228 {
229 return inheritanceSolver;
230 }
231
232 void
234 {
235 this->inheritanceSolver = solver;
236 }
237
241
242 void
244 {
245 NamespaceMap namespaces;
246
247 extractNamespaces(properties, namespaces);
248
249 NamespaceMap::const_iterator namespacesIter = namespaces.begin();
250
251 while (namespacesIter != namespaces.end())
252 {
253 resolveNamespaceInheritance(namespacesIter->first, properties);
254
255 ++namespacesIter;
256 }
257 }
258
259 void
261 NamespaceMap& namespaces)
262 {
263 namespaces.clear();
264
265 Ice::PropertyDict propertyDict = properties->getPropertiesForPrefix(std::string());
266
267 // extract namespaces
268 Ice::PropertyDict::iterator dictIter = propertyDict.begin();
269
270 while (dictIter != propertyDict.end())
271 {
272 std::string propertyFullName = dictIter->first;
273
274 unsigned nameDelimiter = propertyFullName.find_last_of(".");
275 std::string propertyNamespace = propertyFullName.substr(0, nameDelimiter);
276 namespaces[propertyNamespace] = true;
277
278 ++dictIter;
279 }
280 }
281
282 bool
283 IceProperties::InheritanceSolver::hasParent(const std::string& childNamespace,
284 const Ice::PropertiesPtr& properties)
285 {
286 std::string inheritanceProperty = childNamespace + "." + INHERITANCE_KEYWORD;
287
288 if (properties->getPropertyWithDefault(inheritanceProperty, "::NOT-SET::")
289 .compare("::NOT-SET::") == 0)
290 {
291 return false;
292 }
293
294 return true;
295 }
296
297 std::string
298 IceProperties::InheritanceSolver::getParent(const std::string& childNamespace,
299 const Ice::PropertiesPtr& properties)
300 {
301 const std::string inheritanceProperty = childNamespace + "." + INHERITANCE_KEYWORD;
302
303 return properties->getProperty(inheritanceProperty);
304 }
305
306 bool
307 IceProperties::InheritanceSolver::isInHeritageLine(const std::vector<std::string>& heritageLine,
308 const std::string& namespace_)
309 {
310 std::vector<std::string>::const_iterator heritageLineIter = heritageLine.begin();
311
312 while (heritageLineIter != heritageLine.end())
313 {
314 if ((*heritageLineIter).compare(namespace_) == 0)
315 {
316 return true;
317 }
318
319 ++heritageLineIter;
320 }
321
322 return false;
323 }
324
325 std::string
327 const std::string& namespace_)
328 {
329 return propertyName.substr(namespace_.length() + 1);
330 }
331
332 void
334 Ice::PropertiesPtr& properties)
335 {
336 std::vector<std::string> heritageLine;
337
338 if (hasParent(childNamespace, properties))
339 {
340 inherit(
341 childNamespace, getParent(childNamespace, properties), properties, heritageLine);
342 }
343 }
344
345 void
346 IceProperties::InheritanceSolver::inherit(const std::string& childNamespace,
347 const std::string& parentNamespace,
348 Ice::PropertiesPtr& properties,
349 std::vector<std::string> heritageLine)
350 {
351 heritageLine.push_back(childNamespace);
352
353 // check parent inheritance
354 if (hasParent(parentNamespace, properties))
355 {
356 if (isInHeritageLine(heritageLine, parentNamespace))
357 {
358 heritageLine.push_back(parentNamespace);
360 }
361
362 inherit(
363 parentNamespace, getParent(parentNamespace, properties), properties, heritageLine);
364 }
365
366 // perform actual inheritance
367 Ice::PropertyDict parentProperties = properties->getPropertiesForPrefix(parentNamespace);
368
369 Ice::PropertyDict::iterator parentPropIter = parentProperties.begin();
370
371 while (parentPropIter != parentProperties.end())
372 {
373 // look through all child properties, if the parent variable is referred to as {parentVariable} in the
374 // propertyValue
375 if (parentNamespace == STRINGREPLACEMENT_NAMESPACE)
376 {
377 for (auto property : properties->getPropertiesForPrefix(childNamespace))
378 {
379 std::string propertyVariable =
380 "{" + stripNamespace(parentPropIter->first, parentNamespace) + "}";
381 auto index = property.second.find(propertyVariable);
382 if (index != std::string::npos)
383 {
384 std::string newValue = property.second.replace(
385 index, propertyVariable.size(), parentPropIter->second);
386 properties->setProperty(property.first, newValue);
387 }
388 }
389 }
390 else
391 {
392 std::string newPropertyName =
393 childNamespace + "." + stripNamespace(parentPropIter->first, parentNamespace);
394
395 // Check whether it has been already set. Defined properties override inherited ones.
396 if (properties->getProperty(newPropertyName).empty())
397 {
398 properties->setProperty(newPropertyName, parentPropIter->second);
399 }
400 }
401 ++parentPropIter;
402 }
403
404 // remove inheritance tag
405 properties->setProperty(childNamespace + "." + INHERITANCE_KEYWORD, "");
406 }
407} // namespace armarx
uint8_t index
#define STRINGREPLACEMENT_NAMESPACE
#define INHERITANCE_KEYWORD
void extractNamespaces(const Ice::PropertiesPtr &properties, NamespaceMap &namespaces)
Extracts all existing namespace within the passed property container.
void inherit(const std::string &childNamespace, const std::string &parentNamespace, Ice::PropertiesPtr &properties, std::vector< std::string > heritageLine)
Performs the inheritance of properties from parentNamespace to childNamespace.
bool isInHeritageLine(const std::vector< std::string > &heritageLine, const std::string &namespace_)
Checks whether the specified namespace exists already in the heritageLine.
void resolveNamespaceInheritance(const std::string &childNamespace, Ice::PropertiesPtr &properties)
Resolves namespace inheritance for a specific namespace.
std::string stripNamespace(const std::string &propertyName, const std::string &namespace_)
Removes the namespace of the property name.
bool hasParent(const std::string &childNamespace, const Ice::PropertiesPtr &properties)
Checks whether the specified namespace has a parent which it inherits from.
std::map< std::string, bool > NamespaceMap
void resolveInheritance(Ice::PropertiesPtr &properties)
Resolves all inheritance specifications made using the config notation "<namespace>....
std::string getParent(const std::string &childNamespace, const Ice::PropertiesPtr &properties)
Returns the parent namespace of a child namespace.
::std::string getPropertyWithDefault(const ::std::string &name, const ::std::string &defaultValue) ICE_NOEXCEPT override
IceUtil::Handle< InheritanceSolver > InheritanceSolverPtr
void setProperty(const ::std::string &name, const ::std::string &value) override
IceProperties(const Ice::PropertiesPtr iceProperties)
Ice property container constructor.
::Ice::PropertyDict getPropertiesForPrefix(const ::std::string &prefix) ICE_NOEXCEPT override
::Ice::PropertiesPtr clone() ICE_NOEXCEPT override
virtual void setInheritanceSolver(const InheritanceSolverPtr &inheritanceSolver)
Sets an inheritance solver in case of testing or using a non-default solver.
::Ice::Int getPropertyAsIntWithDefault(const ::std::string &name, ::Ice::Int defaultValue) ICE_NOEXCEPT override
::Ice::StringSeq parseCommandLineOptions(const ::std::string &prefix, const ::Ice::StringSeq &options) override
~IceProperties() override
Ice property container desctructor.
::std::string getProperty(const ::std::string &name) ICE_NOEXCEPT override
::Ice::StringSeq getPropertyAsList(const ::std::string &name) ICE_NOEXCEPT override
::Ice::StringSeq parseIceCommandLineOptions(const ::Ice::StringSeq &options) override
void load(const ::std::string &fileName) override
::Ice::Int getPropertyAsInt(const ::std::string &name) ICE_NOEXCEPT override
::Ice::StringSeq getPropertyAsListWithDefault(const ::std::string &name, const ::Ice::StringSeq &defaultValue) ICE_NOEXCEPT override
::Ice::StringSeq getCommandLineOptions() ICE_NOEXCEPT override
static Ice::PropertiesPtr create(const Ice::PropertiesPtr &iceProperties=nullptr)
virtual InheritanceSolverPtr getInheritanceSolver()
Returns the currently used inheritance solver.
This exception is thrown if a property inheritance cycle has been encountered.
Ice::PropertiesPtr createProperties()
::IceInternal::Handle<::Ice::Properties > PropertiesPtr
This file offers overloads of toIce() and fromIce() functions for STL container types.