blob: f81baecb0bb2fd1bc18d63655cad6da508050607 [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{
David Wagner8cb5d882014-12-09 15:26:06 +0100114 base::toXml(xmlElement, serializingContext);
115
Patrick Benavoli63499d42011-10-24 18:50:03 +0200116 // Sequence awareness
117 xmlElement.setAttributeBoolean("SequenceAware", _bSequenceAware);
David Wagner8cb5d882014-12-09 15:26:06 +0100118}
Patrick Benavoli63499d42011-10-24 18:50:03 +0200119
David Wagner8cb5d882014-12-09 15:26:06 +0100120void CConfigurableDomain::childrenToXml(CXmlElement& xmlElement,
121 CXmlSerializingContext& serializingContext) const
122{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200123 // Configurations
124 composeDomainConfigurations(xmlElement, serializingContext);
125
126 // Configurable Elements
Patrick Benavoli63499d42011-10-24 18:50:03 +0200127 composeConfigurableElements(xmlElement);
128
129 // Settings
130 composeSettings(xmlElement, serializingContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200131}
132
133// XML composing
134void CConfigurableDomain::composeDomainConfigurations(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
135{
136 // Create Configurations element
137 CXmlElement xmlConfigurationsElement;
138
139 xmlElement.createChild(xmlConfigurationsElement, "Configurations");
140
141 // Delegate to base
David Wagner8cb5d882014-12-09 15:26:06 +0100142 base::childrenToXml(xmlConfigurationsElement, serializingContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200143}
144
Patrick Benavoli63499d42011-10-24 18:50:03 +0200145void CConfigurableDomain::composeConfigurableElements(CXmlElement& xmlElement) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200146{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200147 // Create ConfigurableElements element
148 CXmlElement xmlConfigurableElementsElement;
149
150 xmlElement.createChild(xmlConfigurableElementsElement, "ConfigurableElements");
151
152 // Serialize out all configurable elements settings
153 ConfigurableElementListIterator it;
154
155 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
156
157 const CConfigurableElement* pConfigurableElement = *it;
158
159 // Create corresponding XML child element
160 CXmlElement xmlChildConfigurableElement;
161
162 xmlConfigurableElementsElement.createChild(xmlChildConfigurableElement, "ConfigurableElement");
163
164 // Set Path attribute
165 xmlChildConfigurableElement.setAttributeString("Path", pConfigurableElement->getPath());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200166 }
167}
168
Patrick Benavoli63499d42011-10-24 18:50:03 +0200169void CConfigurableDomain::composeSettings(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200170{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200171 // Context
172 const CXmlDomainSerializingContext& xmlDomainSerializingContext = static_cast<const CXmlDomainSerializingContext&>(serializingContext);
173
174 if (!xmlDomainSerializingContext.withSettings()) {
175
176 return;
177 }
178
179 // Create Settings element
180 CXmlElement xmlSettingsElement;
181
182 xmlElement.createChild(xmlSettingsElement, "Settings");
183
184 // Serialize out all configurations settings
Patrick Benavoli68a91282011-08-31 11:23:23 +0200185 uint32_t uiNbConfigurations = getNbChildren();
186 uint32_t uiChildConfiguration;
187
188 for (uiChildConfiguration = 0; uiChildConfiguration < uiNbConfigurations; uiChildConfiguration++) {
189
190 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChildConfiguration));
191
192 // Create child xml element for that configuration
193 CXmlElement xmlConfigurationSettingsElement;
194
Patrick Benavoli63499d42011-10-24 18:50:03 +0200195 xmlSettingsElement.createChild(xmlConfigurationSettingsElement, pDomainConfiguration->getKind());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200196
197 // Set its name attribute
198 xmlConfigurationSettingsElement.setNameAttribute(pDomainConfiguration->getName());
199
Patrick Benavoli63499d42011-10-24 18:50:03 +0200200 // Serialize out configuration settings
201 pDomainConfiguration->composeSettings(xmlConfigurationSettingsElement, serializingContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200202 }
203}
204
205// From IXmlSink
206bool CConfigurableDomain::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
207{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200208 // Context
209 CXmlDomainSerializingContext& xmlDomainSerializingContext = static_cast<CXmlDomainSerializingContext&>(serializingContext);
210
211 // Sequence awareness (optional)
212 _bSequenceAware = xmlElement.hasAttribute("SequenceAware") && xmlElement.getAttributeBoolean("SequenceAware");
213
Patrick Benavoli68a91282011-08-31 11:23:23 +0200214 // Local parsing. Do not dig
Patrick Benavoli63499d42011-10-24 18:50:03 +0200215 if (!parseDomainConfigurations(xmlElement, serializingContext) || !parseConfigurableElements(xmlElement, serializingContext) || !parseSettings(xmlElement, serializingContext)) {
216
217 return false;
218 }
219
220 // All provided configurations are parsed
221 // Attempt validation on areas of non provided configurations for all configurable elements if required
222 if (xmlDomainSerializingContext.autoValidationRequired()) {
223
224 autoValidateAll();
225 }
226
227 return true;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200228}
229
230// XML parsing
231bool CConfigurableDomain::parseDomainConfigurations(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
232{
233 // We're supposedly clean
234 assert(_configurableElementList.empty());
235
236 // Get Configurations element
237 CXmlElement xmlConfigurationsElement;
238
239 xmlElement.getChildElement("Configurations", xmlConfigurationsElement);
240
241 // Parse it and create domain configuration objects
242 return base::fromXml(xmlConfigurationsElement, serializingContext);
243}
244
245// Parse configurable elements
246bool CConfigurableDomain::parseConfigurableElements(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
247{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200248 // Get System Class Element
249 CElement* pRootElement = getRoot();
250
251 CElement* pSystemClassElement = pRootElement->findChildOfKind("SystemClass");
252
253 assert(pSystemClassElement);
254
255 // Get ConfigurableElements element
256 CXmlElement xmlConfigurableElementsElement;
257 xmlElement.getChildElement("ConfigurableElements", xmlConfigurableElementsElement);
258
259 // Parse it and associate found configurable elements to it
260 CXmlElement::CChildIterator it(xmlConfigurableElementsElement);
261
262 CXmlElement xmlConfigurableElementElement;
263
264 while (it.next(xmlConfigurableElementElement)) {
265
266 // Locate configurable element
267 string strConfigurableElementPath = xmlConfigurableElementElement.getAttributeString("Path");
268
269 CPathNavigator pathNavigator(strConfigurableElementPath);
Patrick Benavoli065264a2011-11-20 15:46:41 +0100270 string strError;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200271
272 // Is there an element and does it match system class name?
Patrick Benavoli065264a2011-11-20 15:46:41 +0100273 if (!pathNavigator.navigateThrough(pSystemClassElement->getName(), strError)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200274
Patrick Benavoli065264a2011-11-20 15:46:41 +0100275 serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName() + " (" + strError + ")");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200276
277 return false;
278 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200279 // Browse system class for configurable element
280 CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(pSystemClassElement->findDescendant(pathNavigator));
281
282 if (!pConfigurableElement) {
283
284 serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName());
285
286 return false;
287 }
288 // Add found element to domain
Patrick Benavoli68a91282011-08-31 11:23:23 +0200289 if (!addConfigurableElement(pConfigurableElement, NULL, strError)) {
290
291 serializingContext.setError(strError);
292
293 return false;
294 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200295 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200296
297 return true;
298}
299
Patrick Benavoli63499d42011-10-24 18:50:03 +0200300// Parse settings
301bool CConfigurableDomain::parseSettings(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200302{
303 // Context
304 CXmlDomainSerializingContext& xmlDomainSerializingContext = static_cast<CXmlDomainSerializingContext&>(serializingContext);
305
Patrick Benavoli63499d42011-10-24 18:50:03 +0200306 // Check we actually need to parse configuration settings
307 if (!xmlDomainSerializingContext.withSettings()) {
308
309 // No parsing required
310 return true;
311 }
312
313 // Get Settings element
314 CXmlElement xmlSettingsElement;
315 if (!xmlElement.getChildElement("Settings", xmlSettingsElement)) {
316
317 // No settings, bail out successfully
318 return true;
319 }
320
321 // Parse configuration settings
322 CXmlElement::CChildIterator it(xmlSettingsElement);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200323
324 CXmlElement xmlConfigurationSettingsElement;
325
326 while (it.next(xmlConfigurationSettingsElement)) {
327 // Get domain configuration
328 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(xmlConfigurationSettingsElement.getNameAttribute()));
329
330 if (!pDomainConfiguration) {
331
Patrick Benavoli63499d42011-10-24 18:50:03 +0200332 xmlDomainSerializingContext.setError("Could not find domain configuration referred to by configurable domain " + getName());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200333
334 return false;
335 }
Patrick Benavoli63499d42011-10-24 18:50:03 +0200336 // Have domain configuration parse settings for all configurable elements
337 if (!pDomainConfiguration->parseSettings(xmlConfigurationSettingsElement, xmlDomainSerializingContext)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200338
339 return false;
340 }
341 }
342
343 return true;
344}
Patrick Benavoli68a91282011-08-31 11:23:23 +0200345// Configurable elements association
346bool CConfigurableDomain::addConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, string& strError)
347{
348 // Already associated?
349 if (containsConfigurableElement(pConfigurableElement)) {
350
351 strError = "Configurable element " + pConfigurableElement->getPath() + " already associated to configuration domain " + getName();
352
353 return false;
354 }
355
356 // Already owned?
357 if (pConfigurableElement->belongsTo(this)) {
358
359 strError = "Configurable element " + pConfigurableElement->getPath() + " already owned by configuration domain " + getName();
360
361 return false;
362 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200363
364 // Do add
Frédéric Boisnard9620e442012-05-30 16:15:02 +0200365 doAddConfigurableElement(pConfigurableElement, pMainBlackboard);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200366
367 return true;
368}
369
370bool CConfigurableDomain::removeConfigurableElement(CConfigurableElement* pConfigurableElement, string& strError)
371{
372 // Not associated?
373 if (!containsConfigurableElement(pConfigurableElement)) {
374
375 strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName();
376
377 return false;
378 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100379 log_info("Removing configurable element \"%s\" from domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200380
381 // Do remove
382 doRemoveConfigurableElement(pConfigurableElement, true);
383
384 return true;
385}
386
Frédéric Boisnarde42dacd2013-02-25 15:56:56 +0100387/**
388* Blackboard Configuration and Base Offset retrieval.
389*
390* This method fetches the Blackboard associated to the ConfigurableElement
391* given in parameter, for a specific Configuration. The ConfigurableElement
392* must belong to the Domain. If a Blackboard is found, the base offset of
393* the ConfigurableElement is returned as well. This base offset corresponds to
394* the offset of the ancestor of the ConfigurableElement associated to the Configuration.
395*
396* @param[in] strConfiguration Name of the Configuration.
397* @param[in] pCandidateDescendantConfigurableElement Pointer to a CConfigurableElement that
398* belongs to the Domain.
399* @param[out] uiBaseOffset The base offset of the CConfigurableElement.
400* @param[out] bIsLastApplied Boolean indicating that the Configuration is
401* the last one applied of the Domain.
402* @param[out] strError Error message
403*
404* return Pointer to the Blackboard of the Configuration.
405*/
406CParameterBlackboard* CConfigurableDomain::findConfigurationBlackboard(const string& strConfiguration,
407 const CConfigurableElement* pCandidateDescendantConfigurableElement,
408 uint32_t& uiBaseOffset,
409 bool& bIsLastApplied,
410 string& strError) const
411{
412 // Find Configuration
413 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(findChild(strConfiguration));
414
415 if (!pDomainConfiguration) {
416
417 strError = "Domain configuration " + strConfiguration + " not found";
418
419 return NULL;
420 }
421
422 // Parse all configurable elements
423 ConfigurableElementListIterator it;
424
425 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
426
427 const CConfigurableElement* pAssociatedConfigurableElement = *it;
428
429 // Check if the the associated element is the configurable element or one of its ancestors
430 if ((pCandidateDescendantConfigurableElement == pAssociatedConfigurableElement) ||
431 (pCandidateDescendantConfigurableElement->isDescendantOf(pAssociatedConfigurableElement))) {
432
433 uiBaseOffset = pAssociatedConfigurableElement->getOffset();
434 bIsLastApplied = (pDomainConfiguration == _pLastAppliedConfiguration);
435
436 return pDomainConfiguration->getBlackboard(pAssociatedConfigurableElement);
437 }
438 }
439
440 strError = "Element not associated to the Domain";
441
442 return NULL;
443}
444
Patrick Benavoli68a91282011-08-31 11:23:23 +0200445// Domain splitting
446bool CConfigurableDomain::split(CConfigurableElement* pConfigurableElement, string& strError)
447{
448 // Not associated?
449 if (!containsConfigurableElement(pConfigurableElement)) {
450
451 strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName();
452
453 return false;
454 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100455 log_info("Splitting configurable element \"%s\" domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200456
457 // Create sub domain areas for all configurable element's children
458 uint32_t uiNbConfigurableElementChildren = pConfigurableElement->getNbChildren();
459
460 if (!uiNbConfigurableElementChildren) {
461
462 strError = "Configurable element " + pConfigurableElement->getPath() + " has no children to split configurable domain to";
463
464 return false;
465 }
466
467 uint32_t uiChild;
468
469 for (uiChild = 0; uiChild < uiNbConfigurableElementChildren; uiChild++) {
470
471 CConfigurableElement* pChildConfigurableElement = static_cast<CConfigurableElement*>(pConfigurableElement->getChild(uiChild));
472
473 doAddConfigurableElement(pChildConfigurableElement);
474 }
475
476 // Delegate to configurations
477 uint32_t uiNbConfigurations = getNbChildren();
478
479 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
480
481 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
482
483 pDomainConfiguration->split(pConfigurableElement);
484 }
485
486 // Remove given configurable element from this domain
487 // 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
488 doRemoveConfigurableElement(pConfigurableElement, false);
489
490 return true;
491}
492
Frédéric Boisnard8b243f52012-09-06 18:03:20 +0200493// Check if there is a pending configuration for this domain: i.e. an applicable configuration different from the last applied configuration
494const CDomainConfiguration* CConfigurableDomain::getPendingConfiguration() const
495{
496 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
497
498 if (pApplicableDomainConfiguration) {
499
500 // Check not the last one before applying
501 if (!_pLastAppliedConfiguration || (_pLastAppliedConfiguration != pApplicableDomainConfiguration)) {
502
503 return pApplicableDomainConfiguration;
504 }
505 }
506
507 return NULL;
508}
509
Patrick Benavoli68a91282011-08-31 11:23:23 +0200510// Configuration application if required
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100511void CConfigurableDomain::apply(CParameterBlackboard* pParameterBlackboard, CSyncerSet* pSyncerSet, bool bForce) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200512{
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100513 // Apply configuration only if the blackboard will
514 // be synchronized either now or by syncerSet.
515 if(!pSyncerSet ^ _bSequenceAware) {
516 // The configuration can not be syncronised
517 return;
518 }
519
Patrick Benavoli68a91282011-08-31 11:23:23 +0200520 if (bForce) {
521 // Force a configuration restore by forgetting about last applied configuration
522 _pLastAppliedConfiguration = NULL;
523 }
524 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
525
526 if (pApplicableDomainConfiguration) {
527
528 // Check not the last one before applying
529 if (!_pLastAppliedConfiguration || _pLastAppliedConfiguration != pApplicableDomainConfiguration) {
530
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100531 log_info("Applying configuration \"%s\" from domain \"%s\"",
532 pApplicableDomainConfiguration->getName().c_str(),
533 getName().c_str());
534
535 // Check if we need to synchronize during restore
536 bool bSync = !pSyncerSet && _bSequenceAware;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200537
538 // Do the restore
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100539 pApplicableDomainConfiguration->restore(pParameterBlackboard, bSync, NULL);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200540
541 // Record last applied configuration
542 _pLastAppliedConfiguration = pApplicableDomainConfiguration;
543
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100544 // Check we need to provide syncer set to caller
545 if (pSyncerSet && !_bSequenceAware) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200546
547 // Since we applied changes, add our own sync set to the given one
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100548 *pSyncerSet += _syncerSet;
Patrick Benavoli63499d42011-10-24 18:50:03 +0200549 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200550 }
551 }
552}
553
554// Return applicable configuration validity for given configurable element
555bool CConfigurableDomain::isApplicableConfigurationValid(const CConfigurableElement* pConfigurableElement) const
556{
557 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
558
559 return pApplicableDomainConfiguration && pApplicableDomainConfiguration->isValid(pConfigurableElement);
560}
561
Patrick Benavoli68a91282011-08-31 11:23:23 +0200562// In case configurable element was removed
563void CConfigurableDomain::computeSyncSet()
564{
565 // Clean sync set first
Patrick Benavoli63499d42011-10-24 18:50:03 +0200566 _syncerSet.clear();
Patrick Benavoli68a91282011-08-31 11:23:23 +0200567
Patrick Benavoli63499d42011-10-24 18:50:03 +0200568 // Add syncer sets for all associated configurable elements
569 ConfigurableElementToSyncerSetMapIterator mapIt;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200570
Patrick Benavoli63499d42011-10-24 18:50:03 +0200571 for (mapIt = _configurableElementToSyncerSetMap.begin(); mapIt != _configurableElementToSyncerSetMap.end(); ++mapIt) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200572
Patrick Benavoli63499d42011-10-24 18:50:03 +0200573 const CSyncerSet* pSyncerSet = mapIt->second;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200574
Patrick Benavoli63499d42011-10-24 18:50:03 +0200575 _syncerSet += *pSyncerSet;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200576 }
577}
578
579// Configuration Management
580bool CConfigurableDomain::createConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError)
581{
582 // Already exists?
583 if (findChild(strName)) {
584
585 strError = "Already existing configuration";
586
587 return false;
588 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100589 log_info("Creating domain configuration \"%s\" into domain \"%s\"", strName.c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200590
591 // Creation
592 CDomainConfiguration* pDomainConfiguration = new CDomainConfiguration(strName);
593
594 // Configurable elements association
595 ConfigurableElementListIterator it;
596
597 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
598
Patrick Benavoli63499d42011-10-24 18:50:03 +0200599 const CConfigurableElement* pConfigurableElement = *it;;
600
601 // Retrieve associated syncer set
602 CSyncerSet* pSyncerSet = getSyncerSet(pConfigurableElement);
603
604 // Associate to configuration
605 pDomainConfiguration->addConfigurableElement(pConfigurableElement, pSyncerSet);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200606 }
607
608 // Hierarchy
609 addChild(pDomainConfiguration);
610
611 // Ensure validity of fresh new domain configuration
612 // Attempt auto validation, so that the user gets his/her own settings by defaults
613 if (!autoValidateConfiguration(pDomainConfiguration)) {
614
615 // No valid configuration found to copy in from, validate againt main blackboard (will concerned remaining invalid parts)
616 pDomainConfiguration->validate(pMainBlackboard);
617 }
618
619 return true;
620}
621
622bool CConfigurableDomain::deleteConfiguration(const string& strName, string& strError)
623{
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100624 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200625
626 if (!pDomainConfiguration) {
627
Patrick Benavoli68a91282011-08-31 11:23:23 +0200628 return false;
629 }
630
Kevin Rocardace81f82012-12-11 16:19:17 +0100631 log_info("Deleting configuration \"%s\" from domain \"%s\"", strName.c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200632
633 // Was the last applied?
634 if (pDomainConfiguration == _pLastAppliedConfiguration) {
635
636 // Forget about it
637 _pLastAppliedConfiguration = NULL;
638 }
639
640 // Hierarchy
641 removeChild(pDomainConfiguration);
642
643 // Destroy
644 delete pDomainConfiguration;
645
646 return true;
647}
648
649void CConfigurableDomain::listAssociatedToElements(string& strResult) const
650{
651 strResult = "\n";
652
653 ConfigurableElementListIterator it;
654
655 // Browse all configurable elements
656 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
657
658 const CConfigurableElement* pConfigurableElement = *it;
659
660 strResult += pConfigurableElement->getPath() + "\n";
661 }
662}
663
664bool CConfigurableDomain::renameConfiguration(const string& strName, const string& strNewName, string& strError)
665{
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100666 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200667
668 if (!pDomainConfiguration) {
669
Patrick Benavoli68a91282011-08-31 11:23:23 +0200670 return false;
671 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100672 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 +0200673
674 // Rename
675 return pDomainConfiguration->rename(strNewName, strError);
676}
677
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100678bool CConfigurableDomain::restoreConfiguration(const string& strName, CParameterBlackboard* pMainBlackboard, bool bAutoSync, std::list<string>& lstrError) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200679{
Kevin Rocardace81f82012-12-11 16:19:17 +0100680 string strError;
681
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100682 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200683
684 if (!pDomainConfiguration) {
685
Kevin Rocardace81f82012-12-11 16:19:17 +0100686 lstrError.push_back(strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200687 return false;
688 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100689 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 +0200690
691 // Delegate
Kevin Rocardace81f82012-12-11 16:19:17 +0100692 bool bSuccess = pDomainConfiguration->restore(pMainBlackboard, bAutoSync && _bSequenceAware, &lstrError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200693
694 // Record last applied configuration
695 _pLastAppliedConfiguration = pDomainConfiguration;
696
697 // Synchronize
Kevin Rocardace81f82012-12-11 16:19:17 +0100698 if (bAutoSync && !_bSequenceAware) {
699
700 bSuccess &= _syncerSet.sync(*pMainBlackboard, false, &lstrError);
701 }
702 return bSuccess;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200703}
704
705bool CConfigurableDomain::saveConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError)
706{
707 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100708 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200709
710 if (!pDomainConfiguration) {
711
Patrick Benavoli68a91282011-08-31 11:23:23 +0200712 return false;
713 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100714 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 +0200715
716 // Delegate
717 pDomainConfiguration->save(pMainBlackboard);
718
719 return true;
720}
721
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100722bool CConfigurableDomain::setElementSequence(const string& strConfiguration, const std::vector<string>& astrNewElementSequence, string& strError)
Patrick Benavoli63499d42011-10-24 18:50:03 +0200723{
724 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100725 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200726
727 if (!pDomainConfiguration) {
728
Patrick Benavoli63499d42011-10-24 18:50:03 +0200729 return false;
730 }
731
732 // Delegate to configuration
733 return pDomainConfiguration->setElementSequence(astrNewElementSequence, strError);
734}
735
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100736bool CConfigurableDomain::getElementSequence(const string& strConfiguration, string& strResult) const
Patrick Benavoli63499d42011-10-24 18:50:03 +0200737{
738 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100739 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strResult);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200740
741 if (!pDomainConfiguration) {
742
Patrick Benavoli63499d42011-10-24 18:50:03 +0200743 return false;
744 }
745
746 // Delegate to configuration
747 pDomainConfiguration->getElementSequence(strResult);
748
749 return true;
750}
751
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100752bool CConfigurableDomain::setApplicationRule(const string& strConfiguration, const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, string& strError)
753{
754 // Find Domain configuration
755 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
756
757 if (!pDomainConfiguration) {
758
759 return false;
760 }
761
762 // Delegate to configuration
763 return pDomainConfiguration->setApplicationRule(strApplicationRule, pSelectionCriteriaDefinition, strError);
764}
765
766bool CConfigurableDomain::clearApplicationRule(const string& strConfiguration, string& strError)
767{
768 // Find Domain configuration
769 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
770
771 if (!pDomainConfiguration) {
772
773 return false;
774 }
775
776 // Delegate to configuration
777 pDomainConfiguration->clearApplicationRule();
778
779 return true;
780}
781
782bool CConfigurableDomain::getApplicationRule(const string& strConfiguration, string& strResult) const
783{
784 // Find Domain configuration
785 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strResult);
786
787 if (!pDomainConfiguration) {
788
789 return false;
790 }
791
792 // Delegate to configuration
793 pDomainConfiguration->getApplicationRule(strResult);
794
795 return true;
796}
797
Patrick Benavoli68a91282011-08-31 11:23:23 +0200798// Last applied configuration
799string CConfigurableDomain::getLastAppliedConfigurationName() const
800{
801 if (_pLastAppliedConfiguration) {
802
803 return _pLastAppliedConfiguration->getName();
804 }
805 return "<none>";
806}
807
Frédéric Boisnard8b243f52012-09-06 18:03:20 +0200808// Pending configuration
809string CConfigurableDomain::getPendingConfigurationName() const
810{
811 const CDomainConfiguration* pPendingConfiguration = getPendingConfiguration();
812
813 if (pPendingConfiguration) {
814
815 return pPendingConfiguration->getName();
816 }
817 return "<none>";
818}
819
Patrick Benavoli68a91282011-08-31 11:23:23 +0200820// Ensure validity on whole domain from main blackboard
821void CConfigurableDomain::validate(const CParameterBlackboard* pMainBlackboard)
822{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200823
824 // Propagate
825 uint32_t uiNbConfigurations = getNbChildren();
826 uint32_t uiChild;
827
828 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
829
830 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
831
832 pDomainConfiguration->validate(pMainBlackboard);
833 }
834}
835
836// Ensure validity on areas related to configurable element
837void CConfigurableDomain::validateAreas(const CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard)
838{
Kevin Rocardace81f82012-12-11 16:19:17 +0100839 log_info("Validating domain \"" + getName() + "\" against main blackboard for configurable element \"" + pConfigurableElement->getPath() + "\"");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200840
841 // Propagate
842 uint32_t uiNbConfigurations = getNbChildren();
843 uint32_t uiChild;
844
845 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
846
847 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
848
849 pDomainConfiguration->validate(pConfigurableElement, pMainBlackboard);
850 }
851}
852
853// Attempt validation for all configurable element's areas, relying on already existing valid configuration inside domain
854void CConfigurableDomain::autoValidateAll()
855{
856 // Validate
857 ConfigurableElementListIterator it;
858
859 // Browse all configurable elements for configuration validation
860 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
861
862 const CConfigurableElement* pConfigurableElement = *it;
863
864 // Auto validate element
865 autoValidateAreas(pConfigurableElement);
866 }
867}
868
869// Attempt validation for configurable element's areas, relying on already existing valid configuration inside domain
870void CConfigurableDomain::autoValidateAreas(const CConfigurableElement* pConfigurableElement)
871{
872 // Find first valid configuration for given configurable element
873 const CDomainConfiguration* pValidDomainConfiguration = findValidDomainConfiguration(pConfigurableElement);
874
875 // No valid configuration found, give up
876 if (!pValidDomainConfiguration) {
877
878 return;
879 }
880
Patrick Benavoli68a91282011-08-31 11:23:23 +0200881 // Validate all other configurations against found one, if any
882 uint32_t uiNbConfigurations = getNbChildren();
883 uint32_t uiChild;
884
885 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
886
887 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
888
889 if (pDomainConfiguration != pValidDomainConfiguration && !pDomainConfiguration->isValid(pConfigurableElement)) {
890 // Validate
891 pDomainConfiguration->validateAgainst(pValidDomainConfiguration, pConfigurableElement);
892 }
893 }
894}
895
896// Attempt configuration validation for all configurable elements' areas, relying on already existing valid configuration inside domain
897bool CConfigurableDomain::autoValidateConfiguration(CDomainConfiguration* pDomainConfiguration)
898{
899 // Find another configuration than this one, that ought to be valid!
900 uint32_t uiNbConfigurations = getNbChildren();
901 uint32_t uiChild;
902
903 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
904
905 const CDomainConfiguration* pPotententialValidDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
906
907 if (pPotententialValidDomainConfiguration != pDomainConfiguration) {
908
909 // Validate against it
910 pDomainConfiguration->validateAgainst(pPotententialValidDomainConfiguration);
911
912 return true;
913 }
914 }
915 return false;
916}
Patrick Benavoli68a91282011-08-31 11:23:23 +0200917
Patrick Benavoli68a91282011-08-31 11:23:23 +0200918// Search for a valid configuration for given configurable element
919const CDomainConfiguration* CConfigurableDomain::findValidDomainConfiguration(const CConfigurableElement* pConfigurableElement) const
920{
921 uint32_t uiNbConfigurations = getNbChildren();
922 uint32_t uiChild;
923
924 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
925
926 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
927
928 if (pDomainConfiguration->isValid(pConfigurableElement)) {
929
930 return pDomainConfiguration;
931 }
932 }
933 return NULL;
934}
935
936// Search for an applicable configuration
937const CDomainConfiguration* CConfigurableDomain::findApplicableDomainConfiguration() const
938{
939 uint32_t uiNbConfigurations = getNbChildren();
940 uint32_t uiChild;
941
942 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
943
944 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
945
946 if (pDomainConfiguration->isApplicable()) {
947
948 return pDomainConfiguration;
949 }
950 }
951 return NULL;
952}
953
954// Gather set of configurable elements
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100955void CConfigurableDomain::gatherConfigurableElements(std::set<const CConfigurableElement*>& configurableElementSet) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200956{
957 // Insert all configurable elements
958 configurableElementSet.insert(_configurableElementList.begin(), _configurableElementList.end());
959}
960
961// Check configurable element already attached
962bool CConfigurableDomain::containsConfigurableElement(const CConfigurableElement* pConfigurableCandidateElement) const
963{
964 ConfigurableElementListIterator it;
965
966 // Browse all configurable elements for comparison
967 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
968
969 if (pConfigurableCandidateElement == *it) {
970
971 return true;
972 }
973 }
974 return false;
975}
976
977// Merge any descended configurable element to this one with this one
978void CConfigurableDomain::mergeAlreadyAssociatedDescendantConfigurableElements(CConfigurableElement* pNewConfigurableElement)
979{
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100980 std::list<CConfigurableElement*> mergedConfigurableElementList;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200981
982 ConfigurableElementListIterator it;
983
984 // Browse all configurable elements (new one not yet in the list!)
985 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
986
987 CConfigurableElement* pConfigurablePotentialDescendantElement = *it;
988
989 if (pConfigurablePotentialDescendantElement->isDescendantOf(pNewConfigurableElement)) {
990
Kevin Rocardace81f82012-12-11 16:19:17 +0100991 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 +0200992
993 // Merge configuration data
994 mergeConfigurations(pNewConfigurableElement, pConfigurablePotentialDescendantElement);
995
996 // Keep track for removal
997 mergedConfigurableElementList.push_back(pConfigurablePotentialDescendantElement);
998 }
999 }
1000
1001 // Remove all merged elements (new one not yet in the list!)
1002 for (it = mergedConfigurableElementList.begin(); it != mergedConfigurableElementList.end(); ++it) {
1003
1004 CConfigurableElement* pMergedConfigurableElement = *it;
1005
1006 // Remove merged from configurable element from internal tracking list
1007 // 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
1008 doRemoveConfigurableElement(pMergedConfigurableElement, false);
1009 }
1010}
1011
1012void CConfigurableDomain::mergeConfigurations(CConfigurableElement* pToConfigurableElement, CConfigurableElement* pFromConfigurableElement)
1013{
1014 // Propagate to domain configurations
1015 uint32_t uiNbConfigurations = getNbChildren();
1016 uint32_t uiChild;
1017
1018 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1019
1020 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1021
1022 // Do the merge.
1023 pDomainConfiguration->merge(pToConfigurableElement, pFromConfigurableElement);
1024 }
1025}
1026
1027// Configurable elements association
Frédéric Boisnard9620e442012-05-30 16:15:02 +02001028void CConfigurableDomain::doAddConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard *pMainBlackboard)
Patrick Benavoli68a91282011-08-31 11:23:23 +02001029{
1030 // Inform configurable element
1031 pConfigurableElement->addAttachedConfigurableDomain(this);
1032
Patrick Benavoli63499d42011-10-24 18:50:03 +02001033 // Create associated syncer set
1034 CSyncerSet* pSyncerSet = new CSyncerSet;
1035
1036 // Add to sync set the configurable element one
1037 pConfigurableElement->fillSyncerSet(*pSyncerSet);
1038
1039 // Store it
1040 _configurableElementToSyncerSetMap[pConfigurableElement] = pSyncerSet;
1041
1042 // Add it to global one
1043 _syncerSet += *pSyncerSet;
1044
Patrick Benavoli68a91282011-08-31 11:23:23 +02001045 // Inform configurations
1046 uint32_t uiNbConfigurations = getNbChildren();
1047 uint32_t uiChild;
1048
1049 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1050
1051 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1052
Patrick Benavoli63499d42011-10-24 18:50:03 +02001053 pDomainConfiguration->addConfigurableElement(pConfigurableElement, pSyncerSet);
Patrick Benavoli68a91282011-08-31 11:23:23 +02001054 }
Patrick Benavoli68a91282011-08-31 11:23:23 +02001055
Frédéric Boisnard9620e442012-05-30 16:15:02 +02001056 // Ensure area validity for that configurable element (if main blackboard provided)
1057 if (pMainBlackboard) {
1058
1059 // Need to validate against main blackboard
1060 validateAreas(pConfigurableElement, pMainBlackboard);
1061 }
1062
1063 // Already associated descendend configurable elements need a merge of their configuration data
Patrick Benavoli68a91282011-08-31 11:23:23 +02001064 mergeAlreadyAssociatedDescendantConfigurableElements(pConfigurableElement);
1065
1066 // Add to list
1067 _configurableElementList.push_back(pConfigurableElement);
1068}
1069
1070void CConfigurableDomain::doRemoveConfigurableElement(CConfigurableElement* pConfigurableElement, bool bRecomputeSyncSet)
1071{
1072 // Remove from list
1073 _configurableElementList.remove(pConfigurableElement);
1074
Patrick Benavoli63499d42011-10-24 18:50:03 +02001075 // Remove associated syncer set
1076 CSyncerSet* pSyncerSet = getSyncerSet(pConfigurableElement);
1077
1078 _configurableElementToSyncerSetMap.erase(pConfigurableElement);
1079
1080 delete pSyncerSet;
1081
Patrick Benavoli68a91282011-08-31 11:23:23 +02001082 // Inform configurable element
1083 pConfigurableElement->removeAttachedConfigurableDomain(this);
1084
1085 // Inform configurations
1086 uint32_t uiNbConfigurations = getNbChildren();
1087 uint32_t uiChild;
1088
1089 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1090
1091 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1092
1093 pDomainConfiguration->removeConfigurableElement(pConfigurableElement);
1094 }
1095 // Recompute our sync set if needed
1096 if (bRecomputeSyncSet) {
1097
1098 computeSyncSet();
1099 }
1100}
Patrick Benavoli63499d42011-10-24 18:50:03 +02001101
1102// Syncer set retrieval from configurable element
1103CSyncerSet* CConfigurableDomain::getSyncerSet(const CConfigurableElement* pConfigurableElement) const
1104{
1105 ConfigurableElementToSyncerSetMapIterator mapIt = _configurableElementToSyncerSetMap.find(pConfigurableElement);
1106
1107 assert(mapIt != _configurableElementToSyncerSetMap.end());
1108
1109 return mapIt->second;
1110}
Patrick Benavoli0bd50542011-11-29 11:10:27 +01001111
1112// Configuration retrieval
1113CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strConfiguration, string& strError)
1114{
1115 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(strConfiguration));
1116
1117 if (!pDomainConfiguration) {
1118
1119 strError = "Domain configuration " + strConfiguration + " not found";
1120
1121 return NULL;
1122 }
1123 return pDomainConfiguration;
1124}
1125
1126const CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strConfiguration, string& strError) const
1127{
1128 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(findChild(strConfiguration));
1129
1130 if (!pDomainConfiguration) {
1131
1132 strError = "Domain configuration " + strConfiguration + " not found";
1133
1134 return NULL;
1135 }
1136 return pDomainConfiguration;
1137}