blob: 61a8d5b58a26f6deb73de0adda651d2bd4deeaa2 [file] [log] [blame]
Frédéric Boisnarde42dacd2013-02-25 15:56:56 +01001/*
David Wagnerb76c9d62014-02-05 18:30:24 +01002 * Copyright (c) 2011-2014, Intel Corporation
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors
16 * may be used to endorse or promote products derived from this software without
17 * specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Patrick Benavoli68a91282011-08-31 11:23:23 +020029 */
30#include "ConfigurableDomain.h"
31#include "DomainConfiguration.h"
32#include "ConfigurableElement.h"
33#include "ConfigurationAccessContext.h"
Patrick Benavoli68a91282011-08-31 11:23:23 +020034#include "XmlDomainSerializingContext.h"
35#include <assert.h>
36
37#define base CBinarySerializableElement
38
Sebastien Gonzalved9526492014-02-20 22:28:03 +010039using std::string;
40
Patrick Benavoli63499d42011-10-24 18:50:03 +020041CConfigurableDomain::CConfigurableDomain(const string& strName) : base(strName), _bSequenceAware(false), _pLastAppliedConfiguration(NULL)
Patrick Benavoli68a91282011-08-31 11:23:23 +020042{
43}
44
45CConfigurableDomain::~CConfigurableDomain()
46{
Patrick Benavoli63499d42011-10-24 18:50:03 +020047 // Remove all configurable elements
Patrick Benavoli68a91282011-08-31 11:23:23 +020048 ConfigurableElementListIterator it;
49
Patrick Benavoli68a91282011-08-31 11:23:23 +020050 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
51
52 CConfigurableElement* pConfigurableElement = *it;
53
54 // Remove from configurable element
55 pConfigurableElement->removeAttachedConfigurableDomain(this);
56 }
Patrick Benavoli63499d42011-10-24 18:50:03 +020057
58 // Remove all associated syncer sets
59 ConfigurableElementToSyncerSetMapIterator mapIt;
60
61 for (mapIt = _configurableElementToSyncerSetMap.begin(); mapIt != _configurableElementToSyncerSetMap.end(); ++mapIt) {
62
63 delete mapIt->second;
64 }
Patrick Benavoli68a91282011-08-31 11:23:23 +020065}
66
67string CConfigurableDomain::getKind() const
68{
69 return "ConfigurableDomain";
70}
71
72bool CConfigurableDomain::childrenAreDynamic() const
73{
74 return true;
75}
76
Patrick Benavoli0bd50542011-11-29 11:10:27 +010077// Content dumping
78void CConfigurableDomain::logValue(string& strValue, CErrorContext& errorContext) const
79{
80 (void)errorContext;
81
82 strValue = "{";
83
84 // Sequence awareness
85 strValue += "Sequence aware: ";
86 strValue += _bSequenceAware ? "yes" : "no";
87
88 // Last applied configuration
89 strValue += ", Last applied configuration: ";
90 strValue += _pLastAppliedConfiguration ? _pLastAppliedConfiguration->getName() : "<none>";
91
92 strValue += "}";
93}
94
Patrick Benavoli63499d42011-10-24 18:50:03 +020095// Sequence awareness
96void CConfigurableDomain::setSequenceAwareness(bool bSequenceAware)
97{
98 if (_bSequenceAware != bSequenceAware) {
99
Kevin Rocardace81f82012-12-11 16:19:17 +0100100 log_info("Making domain \"%s\" sequence %s", getName().c_str(), bSequenceAware ? "aware" : "unaware");
Patrick Benavoli63499d42011-10-24 18:50:03 +0200101
102 _bSequenceAware = bSequenceAware;
103 }
104}
105
106bool CConfigurableDomain::getSequenceAwareness() const
107{
108 return _bSequenceAware;
109}
110
Patrick Benavoli68a91282011-08-31 11:23:23 +0200111// From IXmlSource
112void CConfigurableDomain::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
113{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200114 // Sequence awareness
115 xmlElement.setAttributeBoolean("SequenceAware", _bSequenceAware);
116
Patrick Benavoli68a91282011-08-31 11:23:23 +0200117 // Configurations
118 composeDomainConfigurations(xmlElement, serializingContext);
119
120 // Configurable Elements
Patrick Benavoli63499d42011-10-24 18:50:03 +0200121 composeConfigurableElements(xmlElement);
122
123 // Settings
124 composeSettings(xmlElement, serializingContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200125}
126
127// XML composing
128void CConfigurableDomain::composeDomainConfigurations(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
129{
130 // Create Configurations element
131 CXmlElement xmlConfigurationsElement;
132
133 xmlElement.createChild(xmlConfigurationsElement, "Configurations");
134
135 // Delegate to base
136 base::toXml(xmlConfigurationsElement, serializingContext);
137}
138
Patrick Benavoli63499d42011-10-24 18:50:03 +0200139void CConfigurableDomain::composeConfigurableElements(CXmlElement& xmlElement) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200140{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200141 // Create ConfigurableElements element
142 CXmlElement xmlConfigurableElementsElement;
143
144 xmlElement.createChild(xmlConfigurableElementsElement, "ConfigurableElements");
145
146 // Serialize out all configurable elements settings
147 ConfigurableElementListIterator it;
148
149 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
150
151 const CConfigurableElement* pConfigurableElement = *it;
152
153 // Create corresponding XML child element
154 CXmlElement xmlChildConfigurableElement;
155
156 xmlConfigurableElementsElement.createChild(xmlChildConfigurableElement, "ConfigurableElement");
157
158 // Set Path attribute
159 xmlChildConfigurableElement.setAttributeString("Path", pConfigurableElement->getPath());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200160 }
161}
162
Patrick Benavoli63499d42011-10-24 18:50:03 +0200163void CConfigurableDomain::composeSettings(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200164{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200165 // Context
166 const CXmlDomainSerializingContext& xmlDomainSerializingContext = static_cast<const CXmlDomainSerializingContext&>(serializingContext);
167
168 if (!xmlDomainSerializingContext.withSettings()) {
169
170 return;
171 }
172
173 // Create Settings element
174 CXmlElement xmlSettingsElement;
175
176 xmlElement.createChild(xmlSettingsElement, "Settings");
177
178 // Serialize out all configurations settings
Patrick Benavoli68a91282011-08-31 11:23:23 +0200179 uint32_t uiNbConfigurations = getNbChildren();
180 uint32_t uiChildConfiguration;
181
182 for (uiChildConfiguration = 0; uiChildConfiguration < uiNbConfigurations; uiChildConfiguration++) {
183
184 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChildConfiguration));
185
186 // Create child xml element for that configuration
187 CXmlElement xmlConfigurationSettingsElement;
188
Patrick Benavoli63499d42011-10-24 18:50:03 +0200189 xmlSettingsElement.createChild(xmlConfigurationSettingsElement, pDomainConfiguration->getKind());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200190
191 // Set its name attribute
192 xmlConfigurationSettingsElement.setNameAttribute(pDomainConfiguration->getName());
193
Patrick Benavoli63499d42011-10-24 18:50:03 +0200194 // Serialize out configuration settings
195 pDomainConfiguration->composeSettings(xmlConfigurationSettingsElement, serializingContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200196 }
197}
198
199// From IXmlSink
200bool CConfigurableDomain::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
201{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200202 // Context
203 CXmlDomainSerializingContext& xmlDomainSerializingContext = static_cast<CXmlDomainSerializingContext&>(serializingContext);
204
205 // Sequence awareness (optional)
206 _bSequenceAware = xmlElement.hasAttribute("SequenceAware") && xmlElement.getAttributeBoolean("SequenceAware");
207
Patrick Benavoli68a91282011-08-31 11:23:23 +0200208 // Local parsing. Do not dig
Patrick Benavoli63499d42011-10-24 18:50:03 +0200209 if (!parseDomainConfigurations(xmlElement, serializingContext) || !parseConfigurableElements(xmlElement, serializingContext) || !parseSettings(xmlElement, serializingContext)) {
210
211 return false;
212 }
213
214 // All provided configurations are parsed
215 // Attempt validation on areas of non provided configurations for all configurable elements if required
216 if (xmlDomainSerializingContext.autoValidationRequired()) {
217
218 autoValidateAll();
219 }
220
221 return true;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200222}
223
224// XML parsing
225bool CConfigurableDomain::parseDomainConfigurations(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
226{
227 // We're supposedly clean
228 assert(_configurableElementList.empty());
229
230 // Get Configurations element
231 CXmlElement xmlConfigurationsElement;
232
233 xmlElement.getChildElement("Configurations", xmlConfigurationsElement);
234
235 // Parse it and create domain configuration objects
236 return base::fromXml(xmlConfigurationsElement, serializingContext);
237}
238
239// Parse configurable elements
240bool CConfigurableDomain::parseConfigurableElements(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
241{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200242 // Get System Class Element
243 CElement* pRootElement = getRoot();
244
245 CElement* pSystemClassElement = pRootElement->findChildOfKind("SystemClass");
246
247 assert(pSystemClassElement);
248
249 // Get ConfigurableElements element
250 CXmlElement xmlConfigurableElementsElement;
251 xmlElement.getChildElement("ConfigurableElements", xmlConfigurableElementsElement);
252
253 // Parse it and associate found configurable elements to it
254 CXmlElement::CChildIterator it(xmlConfigurableElementsElement);
255
256 CXmlElement xmlConfigurableElementElement;
257
258 while (it.next(xmlConfigurableElementElement)) {
259
260 // Locate configurable element
261 string strConfigurableElementPath = xmlConfigurableElementElement.getAttributeString("Path");
262
263 CPathNavigator pathNavigator(strConfigurableElementPath);
Patrick Benavoli065264a2011-11-20 15:46:41 +0100264 string strError;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200265
266 // Is there an element and does it match system class name?
Patrick Benavoli065264a2011-11-20 15:46:41 +0100267 if (!pathNavigator.navigateThrough(pSystemClassElement->getName(), strError)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200268
Patrick Benavoli065264a2011-11-20 15:46:41 +0100269 serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName() + " (" + strError + ")");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200270
271 return false;
272 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200273 // Browse system class for configurable element
274 CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(pSystemClassElement->findDescendant(pathNavigator));
275
276 if (!pConfigurableElement) {
277
278 serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName());
279
280 return false;
281 }
282 // Add found element to domain
Patrick Benavoli68a91282011-08-31 11:23:23 +0200283 if (!addConfigurableElement(pConfigurableElement, NULL, strError)) {
284
285 serializingContext.setError(strError);
286
287 return false;
288 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200289 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200290
291 return true;
292}
293
Patrick Benavoli63499d42011-10-24 18:50:03 +0200294// Parse settings
295bool CConfigurableDomain::parseSettings(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200296{
297 // Context
298 CXmlDomainSerializingContext& xmlDomainSerializingContext = static_cast<CXmlDomainSerializingContext&>(serializingContext);
299
Patrick Benavoli63499d42011-10-24 18:50:03 +0200300 // Check we actually need to parse configuration settings
301 if (!xmlDomainSerializingContext.withSettings()) {
302
303 // No parsing required
304 return true;
305 }
306
307 // Get Settings element
308 CXmlElement xmlSettingsElement;
309 if (!xmlElement.getChildElement("Settings", xmlSettingsElement)) {
310
311 // No settings, bail out successfully
312 return true;
313 }
314
315 // Parse configuration settings
316 CXmlElement::CChildIterator it(xmlSettingsElement);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200317
318 CXmlElement xmlConfigurationSettingsElement;
319
320 while (it.next(xmlConfigurationSettingsElement)) {
321 // Get domain configuration
322 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(xmlConfigurationSettingsElement.getNameAttribute()));
323
324 if (!pDomainConfiguration) {
325
Patrick Benavoli63499d42011-10-24 18:50:03 +0200326 xmlDomainSerializingContext.setError("Could not find domain configuration referred to by configurable domain " + getName());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200327
328 return false;
329 }
Patrick Benavoli63499d42011-10-24 18:50:03 +0200330 // Have domain configuration parse settings for all configurable elements
331 if (!pDomainConfiguration->parseSettings(xmlConfigurationSettingsElement, xmlDomainSerializingContext)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200332
333 return false;
334 }
335 }
336
337 return true;
338}
Patrick Benavoli68a91282011-08-31 11:23:23 +0200339// Configurable elements association
340bool CConfigurableDomain::addConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, string& strError)
341{
342 // Already associated?
343 if (containsConfigurableElement(pConfigurableElement)) {
344
345 strError = "Configurable element " + pConfigurableElement->getPath() + " already associated to configuration domain " + getName();
346
347 return false;
348 }
349
350 // Already owned?
351 if (pConfigurableElement->belongsTo(this)) {
352
353 strError = "Configurable element " + pConfigurableElement->getPath() + " already owned by configuration domain " + getName();
354
355 return false;
356 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200357
358 // Do add
Frédéric Boisnard9620e442012-05-30 16:15:02 +0200359 doAddConfigurableElement(pConfigurableElement, pMainBlackboard);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200360
361 return true;
362}
363
364bool CConfigurableDomain::removeConfigurableElement(CConfigurableElement* pConfigurableElement, string& strError)
365{
366 // Not associated?
367 if (!containsConfigurableElement(pConfigurableElement)) {
368
369 strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName();
370
371 return false;
372 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100373 log_info("Removing configurable element \"%s\" from domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200374
375 // Do remove
376 doRemoveConfigurableElement(pConfigurableElement, true);
377
378 return true;
379}
380
Frédéric Boisnarde42dacd2013-02-25 15:56:56 +0100381/**
382* Blackboard Configuration and Base Offset retrieval.
383*
384* This method fetches the Blackboard associated to the ConfigurableElement
385* given in parameter, for a specific Configuration. The ConfigurableElement
386* must belong to the Domain. If a Blackboard is found, the base offset of
387* the ConfigurableElement is returned as well. This base offset corresponds to
388* the offset of the ancestor of the ConfigurableElement associated to the Configuration.
389*
390* @param[in] strConfiguration Name of the Configuration.
391* @param[in] pCandidateDescendantConfigurableElement Pointer to a CConfigurableElement that
392* belongs to the Domain.
393* @param[out] uiBaseOffset The base offset of the CConfigurableElement.
394* @param[out] bIsLastApplied Boolean indicating that the Configuration is
395* the last one applied of the Domain.
396* @param[out] strError Error message
397*
398* return Pointer to the Blackboard of the Configuration.
399*/
400CParameterBlackboard* CConfigurableDomain::findConfigurationBlackboard(const string& strConfiguration,
401 const CConfigurableElement* pCandidateDescendantConfigurableElement,
402 uint32_t& uiBaseOffset,
403 bool& bIsLastApplied,
404 string& strError) const
405{
406 // Find Configuration
407 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(findChild(strConfiguration));
408
409 if (!pDomainConfiguration) {
410
411 strError = "Domain configuration " + strConfiguration + " not found";
412
413 return NULL;
414 }
415
416 // Parse all configurable elements
417 ConfigurableElementListIterator it;
418
419 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
420
421 const CConfigurableElement* pAssociatedConfigurableElement = *it;
422
423 // Check if the the associated element is the configurable element or one of its ancestors
424 if ((pCandidateDescendantConfigurableElement == pAssociatedConfigurableElement) ||
425 (pCandidateDescendantConfigurableElement->isDescendantOf(pAssociatedConfigurableElement))) {
426
427 uiBaseOffset = pAssociatedConfigurableElement->getOffset();
428 bIsLastApplied = (pDomainConfiguration == _pLastAppliedConfiguration);
429
430 return pDomainConfiguration->getBlackboard(pAssociatedConfigurableElement);
431 }
432 }
433
434 strError = "Element not associated to the Domain";
435
436 return NULL;
437}
438
Patrick Benavoli68a91282011-08-31 11:23:23 +0200439// Domain splitting
440bool CConfigurableDomain::split(CConfigurableElement* pConfigurableElement, string& strError)
441{
442 // Not associated?
443 if (!containsConfigurableElement(pConfigurableElement)) {
444
445 strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName();
446
447 return false;
448 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100449 log_info("Splitting configurable element \"%s\" domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200450
451 // Create sub domain areas for all configurable element's children
452 uint32_t uiNbConfigurableElementChildren = pConfigurableElement->getNbChildren();
453
454 if (!uiNbConfigurableElementChildren) {
455
456 strError = "Configurable element " + pConfigurableElement->getPath() + " has no children to split configurable domain to";
457
458 return false;
459 }
460
461 uint32_t uiChild;
462
463 for (uiChild = 0; uiChild < uiNbConfigurableElementChildren; uiChild++) {
464
465 CConfigurableElement* pChildConfigurableElement = static_cast<CConfigurableElement*>(pConfigurableElement->getChild(uiChild));
466
467 doAddConfigurableElement(pChildConfigurableElement);
468 }
469
470 // Delegate to configurations
471 uint32_t uiNbConfigurations = getNbChildren();
472
473 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
474
475 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
476
477 pDomainConfiguration->split(pConfigurableElement);
478 }
479
480 // Remove given configurable element from this domain
481 // Note: we shouldn't need to recompute the sync set in that case, as the splitted element should include the syncers of its children elements
482 doRemoveConfigurableElement(pConfigurableElement, false);
483
484 return true;
485}
486
Frédéric Boisnard8b243f52012-09-06 18:03:20 +0200487// Check if there is a pending configuration for this domain: i.e. an applicable configuration different from the last applied configuration
488const CDomainConfiguration* CConfigurableDomain::getPendingConfiguration() const
489{
490 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
491
492 if (pApplicableDomainConfiguration) {
493
494 // Check not the last one before applying
495 if (!_pLastAppliedConfiguration || (_pLastAppliedConfiguration != pApplicableDomainConfiguration)) {
496
497 return pApplicableDomainConfiguration;
498 }
499 }
500
501 return NULL;
502}
503
Patrick Benavoli68a91282011-08-31 11:23:23 +0200504// Configuration application if required
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100505void CConfigurableDomain::apply(CParameterBlackboard* pParameterBlackboard, CSyncerSet* pSyncerSet, bool bForce) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200506{
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100507 // Apply configuration only if the blackboard will
508 // be synchronized either now or by syncerSet.
509 if(!pSyncerSet ^ _bSequenceAware) {
510 // The configuration can not be syncronised
511 return;
512 }
513
Patrick Benavoli68a91282011-08-31 11:23:23 +0200514 if (bForce) {
515 // Force a configuration restore by forgetting about last applied configuration
516 _pLastAppliedConfiguration = NULL;
517 }
518 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
519
520 if (pApplicableDomainConfiguration) {
521
522 // Check not the last one before applying
523 if (!_pLastAppliedConfiguration || _pLastAppliedConfiguration != pApplicableDomainConfiguration) {
524
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100525 log_info("Applying configuration \"%s\" from domain \"%s\"",
526 pApplicableDomainConfiguration->getName().c_str(),
527 getName().c_str());
528
529 // Check if we need to synchronize during restore
530 bool bSync = !pSyncerSet && _bSequenceAware;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200531
532 // Do the restore
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100533 pApplicableDomainConfiguration->restore(pParameterBlackboard, bSync, NULL);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200534
535 // Record last applied configuration
536 _pLastAppliedConfiguration = pApplicableDomainConfiguration;
537
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100538 // Check we need to provide syncer set to caller
539 if (pSyncerSet && !_bSequenceAware) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200540
541 // Since we applied changes, add our own sync set to the given one
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100542 *pSyncerSet += _syncerSet;
Patrick Benavoli63499d42011-10-24 18:50:03 +0200543 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200544 }
545 }
546}
547
548// Return applicable configuration validity for given configurable element
549bool CConfigurableDomain::isApplicableConfigurationValid(const CConfigurableElement* pConfigurableElement) const
550{
551 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
552
553 return pApplicableDomainConfiguration && pApplicableDomainConfiguration->isValid(pConfigurableElement);
554}
555
Patrick Benavoli68a91282011-08-31 11:23:23 +0200556// In case configurable element was removed
557void CConfigurableDomain::computeSyncSet()
558{
559 // Clean sync set first
Patrick Benavoli63499d42011-10-24 18:50:03 +0200560 _syncerSet.clear();
Patrick Benavoli68a91282011-08-31 11:23:23 +0200561
Patrick Benavoli63499d42011-10-24 18:50:03 +0200562 // Add syncer sets for all associated configurable elements
563 ConfigurableElementToSyncerSetMapIterator mapIt;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200564
Patrick Benavoli63499d42011-10-24 18:50:03 +0200565 for (mapIt = _configurableElementToSyncerSetMap.begin(); mapIt != _configurableElementToSyncerSetMap.end(); ++mapIt) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200566
Patrick Benavoli63499d42011-10-24 18:50:03 +0200567 const CSyncerSet* pSyncerSet = mapIt->second;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200568
Patrick Benavoli63499d42011-10-24 18:50:03 +0200569 _syncerSet += *pSyncerSet;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200570 }
571}
572
573// Configuration Management
574bool CConfigurableDomain::createConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError)
575{
576 // Already exists?
577 if (findChild(strName)) {
578
579 strError = "Already existing configuration";
580
581 return false;
582 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100583 log_info("Creating domain configuration \"%s\" into domain \"%s\"", strName.c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200584
585 // Creation
586 CDomainConfiguration* pDomainConfiguration = new CDomainConfiguration(strName);
587
588 // Configurable elements association
589 ConfigurableElementListIterator it;
590
591 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
592
Patrick Benavoli63499d42011-10-24 18:50:03 +0200593 const CConfigurableElement* pConfigurableElement = *it;;
594
595 // Retrieve associated syncer set
596 CSyncerSet* pSyncerSet = getSyncerSet(pConfigurableElement);
597
598 // Associate to configuration
599 pDomainConfiguration->addConfigurableElement(pConfigurableElement, pSyncerSet);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200600 }
601
602 // Hierarchy
603 addChild(pDomainConfiguration);
604
605 // Ensure validity of fresh new domain configuration
606 // Attempt auto validation, so that the user gets his/her own settings by defaults
607 if (!autoValidateConfiguration(pDomainConfiguration)) {
608
609 // No valid configuration found to copy in from, validate againt main blackboard (will concerned remaining invalid parts)
610 pDomainConfiguration->validate(pMainBlackboard);
611 }
612
613 return true;
614}
615
616bool CConfigurableDomain::deleteConfiguration(const string& strName, string& strError)
617{
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100618 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200619
620 if (!pDomainConfiguration) {
621
Patrick Benavoli68a91282011-08-31 11:23:23 +0200622 return false;
623 }
624
Kevin Rocardace81f82012-12-11 16:19:17 +0100625 log_info("Deleting configuration \"%s\" from domain \"%s\"", strName.c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200626
627 // Was the last applied?
628 if (pDomainConfiguration == _pLastAppliedConfiguration) {
629
630 // Forget about it
631 _pLastAppliedConfiguration = NULL;
632 }
633
634 // Hierarchy
635 removeChild(pDomainConfiguration);
636
637 // Destroy
638 delete pDomainConfiguration;
639
640 return true;
641}
642
643void CConfigurableDomain::listAssociatedToElements(string& strResult) const
644{
645 strResult = "\n";
646
647 ConfigurableElementListIterator it;
648
649 // Browse all configurable elements
650 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
651
652 const CConfigurableElement* pConfigurableElement = *it;
653
654 strResult += pConfigurableElement->getPath() + "\n";
655 }
656}
657
658bool CConfigurableDomain::renameConfiguration(const string& strName, const string& strNewName, string& strError)
659{
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100660 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200661
662 if (!pDomainConfiguration) {
663
Patrick Benavoli68a91282011-08-31 11:23:23 +0200664 return false;
665 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100666 log_info("Renaming domain \"%s\"'s configuration \"%s\" to \"%s\"", getName().c_str(), strName.c_str(), strNewName.c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200667
668 // Rename
669 return pDomainConfiguration->rename(strNewName, strError);
670}
671
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100672bool CConfigurableDomain::restoreConfiguration(const string& strName, CParameterBlackboard* pMainBlackboard, bool bAutoSync, std::list<string>& lstrError) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200673{
Kevin Rocardace81f82012-12-11 16:19:17 +0100674 string strError;
675
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100676 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200677
678 if (!pDomainConfiguration) {
679
Kevin Rocardace81f82012-12-11 16:19:17 +0100680 lstrError.push_back(strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200681 return false;
682 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100683 log_info("Restoring domain \"%s\"'s configuration \"%s\" to parameter blackboard", getName().c_str(), pDomainConfiguration->getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200684
685 // Delegate
Kevin Rocardace81f82012-12-11 16:19:17 +0100686 bool bSuccess = pDomainConfiguration->restore(pMainBlackboard, bAutoSync && _bSequenceAware, &lstrError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200687
688 // Record last applied configuration
689 _pLastAppliedConfiguration = pDomainConfiguration;
690
691 // Synchronize
Kevin Rocardace81f82012-12-11 16:19:17 +0100692 if (bAutoSync && !_bSequenceAware) {
693
694 bSuccess &= _syncerSet.sync(*pMainBlackboard, false, &lstrError);
695 }
696 return bSuccess;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200697}
698
699bool CConfigurableDomain::saveConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError)
700{
701 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100702 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200703
704 if (!pDomainConfiguration) {
705
Patrick Benavoli68a91282011-08-31 11:23:23 +0200706 return false;
707 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100708 log_info("Saving domain \"%s\"'s configuration \"%s\" from parameter blackboard", getName().c_str(), pDomainConfiguration->getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200709
710 // Delegate
711 pDomainConfiguration->save(pMainBlackboard);
712
713 return true;
714}
715
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100716bool CConfigurableDomain::setElementSequence(const string& strConfiguration, const std::vector<string>& astrNewElementSequence, string& strError)
Patrick Benavoli63499d42011-10-24 18:50:03 +0200717{
718 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100719 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200720
721 if (!pDomainConfiguration) {
722
Patrick Benavoli63499d42011-10-24 18:50:03 +0200723 return false;
724 }
725
726 // Delegate to configuration
727 return pDomainConfiguration->setElementSequence(astrNewElementSequence, strError);
728}
729
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100730bool CConfigurableDomain::getElementSequence(const string& strConfiguration, string& strResult) const
Patrick Benavoli63499d42011-10-24 18:50:03 +0200731{
732 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100733 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strResult);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200734
735 if (!pDomainConfiguration) {
736
Patrick Benavoli63499d42011-10-24 18:50:03 +0200737 return false;
738 }
739
740 // Delegate to configuration
741 pDomainConfiguration->getElementSequence(strResult);
742
743 return true;
744}
745
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100746bool CConfigurableDomain::setApplicationRule(const string& strConfiguration, const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, string& strError)
747{
748 // Find Domain configuration
749 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
750
751 if (!pDomainConfiguration) {
752
753 return false;
754 }
755
756 // Delegate to configuration
757 return pDomainConfiguration->setApplicationRule(strApplicationRule, pSelectionCriteriaDefinition, strError);
758}
759
760bool CConfigurableDomain::clearApplicationRule(const string& strConfiguration, string& strError)
761{
762 // Find Domain configuration
763 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
764
765 if (!pDomainConfiguration) {
766
767 return false;
768 }
769
770 // Delegate to configuration
771 pDomainConfiguration->clearApplicationRule();
772
773 return true;
774}
775
776bool CConfigurableDomain::getApplicationRule(const string& strConfiguration, string& strResult) const
777{
778 // Find Domain configuration
779 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strResult);
780
781 if (!pDomainConfiguration) {
782
783 return false;
784 }
785
786 // Delegate to configuration
787 pDomainConfiguration->getApplicationRule(strResult);
788
789 return true;
790}
791
Patrick Benavoli68a91282011-08-31 11:23:23 +0200792// Last applied configuration
793string CConfigurableDomain::getLastAppliedConfigurationName() const
794{
795 if (_pLastAppliedConfiguration) {
796
797 return _pLastAppliedConfiguration->getName();
798 }
799 return "<none>";
800}
801
Frédéric Boisnard8b243f52012-09-06 18:03:20 +0200802// Pending configuration
803string CConfigurableDomain::getPendingConfigurationName() const
804{
805 const CDomainConfiguration* pPendingConfiguration = getPendingConfiguration();
806
807 if (pPendingConfiguration) {
808
809 return pPendingConfiguration->getName();
810 }
811 return "<none>";
812}
813
Patrick Benavoli68a91282011-08-31 11:23:23 +0200814// Ensure validity on whole domain from main blackboard
815void CConfigurableDomain::validate(const CParameterBlackboard* pMainBlackboard)
816{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200817
818 // Propagate
819 uint32_t uiNbConfigurations = getNbChildren();
820 uint32_t uiChild;
821
822 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
823
824 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
825
826 pDomainConfiguration->validate(pMainBlackboard);
827 }
828}
829
830// Ensure validity on areas related to configurable element
831void CConfigurableDomain::validateAreas(const CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard)
832{
Kevin Rocardace81f82012-12-11 16:19:17 +0100833 log_info("Validating domain \"" + getName() + "\" against main blackboard for configurable element \"" + pConfigurableElement->getPath() + "\"");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200834
835 // Propagate
836 uint32_t uiNbConfigurations = getNbChildren();
837 uint32_t uiChild;
838
839 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
840
841 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
842
843 pDomainConfiguration->validate(pConfigurableElement, pMainBlackboard);
844 }
845}
846
847// Attempt validation for all configurable element's areas, relying on already existing valid configuration inside domain
848void CConfigurableDomain::autoValidateAll()
849{
850 // Validate
851 ConfigurableElementListIterator it;
852
853 // Browse all configurable elements for configuration validation
854 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
855
856 const CConfigurableElement* pConfigurableElement = *it;
857
858 // Auto validate element
859 autoValidateAreas(pConfigurableElement);
860 }
861}
862
863// Attempt validation for configurable element's areas, relying on already existing valid configuration inside domain
864void CConfigurableDomain::autoValidateAreas(const CConfigurableElement* pConfigurableElement)
865{
866 // Find first valid configuration for given configurable element
867 const CDomainConfiguration* pValidDomainConfiguration = findValidDomainConfiguration(pConfigurableElement);
868
869 // No valid configuration found, give up
870 if (!pValidDomainConfiguration) {
871
872 return;
873 }
874
Patrick Benavoli68a91282011-08-31 11:23:23 +0200875 // Validate all other configurations against found one, if any
876 uint32_t uiNbConfigurations = getNbChildren();
877 uint32_t uiChild;
878
879 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
880
881 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
882
883 if (pDomainConfiguration != pValidDomainConfiguration && !pDomainConfiguration->isValid(pConfigurableElement)) {
884 // Validate
885 pDomainConfiguration->validateAgainst(pValidDomainConfiguration, pConfigurableElement);
886 }
887 }
888}
889
890// Attempt configuration validation for all configurable elements' areas, relying on already existing valid configuration inside domain
891bool CConfigurableDomain::autoValidateConfiguration(CDomainConfiguration* pDomainConfiguration)
892{
893 // Find another configuration than this one, that ought to be valid!
894 uint32_t uiNbConfigurations = getNbChildren();
895 uint32_t uiChild;
896
897 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
898
899 const CDomainConfiguration* pPotententialValidDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
900
901 if (pPotententialValidDomainConfiguration != pDomainConfiguration) {
902
903 // Validate against it
904 pDomainConfiguration->validateAgainst(pPotententialValidDomainConfiguration);
905
906 return true;
907 }
908 }
909 return false;
910}
Patrick Benavoli68a91282011-08-31 11:23:23 +0200911
Patrick Benavoli68a91282011-08-31 11:23:23 +0200912// Search for a valid configuration for given configurable element
913const CDomainConfiguration* CConfigurableDomain::findValidDomainConfiguration(const CConfigurableElement* pConfigurableElement) const
914{
915 uint32_t uiNbConfigurations = getNbChildren();
916 uint32_t uiChild;
917
918 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
919
920 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
921
922 if (pDomainConfiguration->isValid(pConfigurableElement)) {
923
924 return pDomainConfiguration;
925 }
926 }
927 return NULL;
928}
929
930// Search for an applicable configuration
931const CDomainConfiguration* CConfigurableDomain::findApplicableDomainConfiguration() const
932{
933 uint32_t uiNbConfigurations = getNbChildren();
934 uint32_t uiChild;
935
936 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
937
938 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
939
940 if (pDomainConfiguration->isApplicable()) {
941
942 return pDomainConfiguration;
943 }
944 }
945 return NULL;
946}
947
948// Gather set of configurable elements
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100949void CConfigurableDomain::gatherConfigurableElements(std::set<const CConfigurableElement*>& configurableElementSet) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200950{
951 // Insert all configurable elements
952 configurableElementSet.insert(_configurableElementList.begin(), _configurableElementList.end());
953}
954
955// Check configurable element already attached
956bool CConfigurableDomain::containsConfigurableElement(const CConfigurableElement* pConfigurableCandidateElement) const
957{
958 ConfigurableElementListIterator it;
959
960 // Browse all configurable elements for comparison
961 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
962
963 if (pConfigurableCandidateElement == *it) {
964
965 return true;
966 }
967 }
968 return false;
969}
970
971// Merge any descended configurable element to this one with this one
972void CConfigurableDomain::mergeAlreadyAssociatedDescendantConfigurableElements(CConfigurableElement* pNewConfigurableElement)
973{
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100974 std::list<CConfigurableElement*> mergedConfigurableElementList;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200975
976 ConfigurableElementListIterator it;
977
978 // Browse all configurable elements (new one not yet in the list!)
979 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
980
981 CConfigurableElement* pConfigurablePotentialDescendantElement = *it;
982
983 if (pConfigurablePotentialDescendantElement->isDescendantOf(pNewConfigurableElement)) {
984
Kevin Rocardace81f82012-12-11 16:19:17 +0100985 log_info("In domain \"%s\", merging descendant configurable element's configurations \"%s\" into its ascendant \"%s\" ones", getName().c_str(), pConfigurablePotentialDescendantElement->getName().c_str(), pNewConfigurableElement->getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200986
987 // Merge configuration data
988 mergeConfigurations(pNewConfigurableElement, pConfigurablePotentialDescendantElement);
989
990 // Keep track for removal
991 mergedConfigurableElementList.push_back(pConfigurablePotentialDescendantElement);
992 }
993 }
994
995 // Remove all merged elements (new one not yet in the list!)
996 for (it = mergedConfigurableElementList.begin(); it != mergedConfigurableElementList.end(); ++it) {
997
998 CConfigurableElement* pMergedConfigurableElement = *it;
999
1000 // Remove merged from configurable element from internal tracking list
1001 // Note: we shouldn't need to recompute the sync set in that case, as the merged to element should include the syncers of merged from elements
1002 doRemoveConfigurableElement(pMergedConfigurableElement, false);
1003 }
1004}
1005
1006void CConfigurableDomain::mergeConfigurations(CConfigurableElement* pToConfigurableElement, CConfigurableElement* pFromConfigurableElement)
1007{
1008 // Propagate to domain configurations
1009 uint32_t uiNbConfigurations = getNbChildren();
1010 uint32_t uiChild;
1011
1012 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1013
1014 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1015
1016 // Do the merge.
1017 pDomainConfiguration->merge(pToConfigurableElement, pFromConfigurableElement);
1018 }
1019}
1020
1021// Configurable elements association
Frédéric Boisnard9620e442012-05-30 16:15:02 +02001022void CConfigurableDomain::doAddConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard *pMainBlackboard)
Patrick Benavoli68a91282011-08-31 11:23:23 +02001023{
1024 // Inform configurable element
1025 pConfigurableElement->addAttachedConfigurableDomain(this);
1026
Patrick Benavoli63499d42011-10-24 18:50:03 +02001027 // Create associated syncer set
1028 CSyncerSet* pSyncerSet = new CSyncerSet;
1029
1030 // Add to sync set the configurable element one
1031 pConfigurableElement->fillSyncerSet(*pSyncerSet);
1032
1033 // Store it
1034 _configurableElementToSyncerSetMap[pConfigurableElement] = pSyncerSet;
1035
1036 // Add it to global one
1037 _syncerSet += *pSyncerSet;
1038
Patrick Benavoli68a91282011-08-31 11:23:23 +02001039 // Inform configurations
1040 uint32_t uiNbConfigurations = getNbChildren();
1041 uint32_t uiChild;
1042
1043 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1044
1045 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1046
Patrick Benavoli63499d42011-10-24 18:50:03 +02001047 pDomainConfiguration->addConfigurableElement(pConfigurableElement, pSyncerSet);
Patrick Benavoli68a91282011-08-31 11:23:23 +02001048 }
Patrick Benavoli68a91282011-08-31 11:23:23 +02001049
Frédéric Boisnard9620e442012-05-30 16:15:02 +02001050 // Ensure area validity for that configurable element (if main blackboard provided)
1051 if (pMainBlackboard) {
1052
1053 // Need to validate against main blackboard
1054 validateAreas(pConfigurableElement, pMainBlackboard);
1055 }
1056
1057 // Already associated descendend configurable elements need a merge of their configuration data
Patrick Benavoli68a91282011-08-31 11:23:23 +02001058 mergeAlreadyAssociatedDescendantConfigurableElements(pConfigurableElement);
1059
1060 // Add to list
1061 _configurableElementList.push_back(pConfigurableElement);
1062}
1063
1064void CConfigurableDomain::doRemoveConfigurableElement(CConfigurableElement* pConfigurableElement, bool bRecomputeSyncSet)
1065{
1066 // Remove from list
1067 _configurableElementList.remove(pConfigurableElement);
1068
Patrick Benavoli63499d42011-10-24 18:50:03 +02001069 // Remove associated syncer set
1070 CSyncerSet* pSyncerSet = getSyncerSet(pConfigurableElement);
1071
1072 _configurableElementToSyncerSetMap.erase(pConfigurableElement);
1073
1074 delete pSyncerSet;
1075
Patrick Benavoli68a91282011-08-31 11:23:23 +02001076 // Inform configurable element
1077 pConfigurableElement->removeAttachedConfigurableDomain(this);
1078
1079 // Inform configurations
1080 uint32_t uiNbConfigurations = getNbChildren();
1081 uint32_t uiChild;
1082
1083 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1084
1085 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1086
1087 pDomainConfiguration->removeConfigurableElement(pConfigurableElement);
1088 }
1089 // Recompute our sync set if needed
1090 if (bRecomputeSyncSet) {
1091
1092 computeSyncSet();
1093 }
1094}
Patrick Benavoli63499d42011-10-24 18:50:03 +02001095
1096// Syncer set retrieval from configurable element
1097CSyncerSet* CConfigurableDomain::getSyncerSet(const CConfigurableElement* pConfigurableElement) const
1098{
1099 ConfigurableElementToSyncerSetMapIterator mapIt = _configurableElementToSyncerSetMap.find(pConfigurableElement);
1100
1101 assert(mapIt != _configurableElementToSyncerSetMap.end());
1102
1103 return mapIt->second;
1104}
Patrick Benavoli0bd50542011-11-29 11:10:27 +01001105
1106// Configuration retrieval
1107CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strConfiguration, string& strError)
1108{
1109 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(strConfiguration));
1110
1111 if (!pDomainConfiguration) {
1112
1113 strError = "Domain configuration " + strConfiguration + " not found";
1114
1115 return NULL;
1116 }
1117 return pDomainConfiguration;
1118}
1119
1120const CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strConfiguration, string& strError) const
1121{
1122 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(findChild(strConfiguration));
1123
1124 if (!pDomainConfiguration) {
1125
1126 strError = "Domain configuration " + strConfiguration + " not found";
1127
1128 return NULL;
1129 }
1130 return pDomainConfiguration;
1131}