blob: c3fa1f957dfbe6a47e1d41a2b0c88c5ffc2c0f8f [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"
David Wagner29fa61f2014-12-19 11:15:02 +010035#include "XmlDomainImportContext.h"
36#include "XmlDomainExportContext.h"
Patrick Benavoli68a91282011-08-31 11:23:23 +020037#include <assert.h>
38
39#define base CBinarySerializableElement
40
Sebastien Gonzalved9526492014-02-20 22:28:03 +010041using std::string;
42
Patrick Benavoli63499d42011-10-24 18:50:03 +020043CConfigurableDomain::CConfigurableDomain(const string& strName) : base(strName), _bSequenceAware(false), _pLastAppliedConfiguration(NULL)
Patrick Benavoli68a91282011-08-31 11:23:23 +020044{
45}
46
47CConfigurableDomain::~CConfigurableDomain()
48{
Patrick Benavoli63499d42011-10-24 18:50:03 +020049 // Remove all configurable elements
Patrick Benavoli68a91282011-08-31 11:23:23 +020050 ConfigurableElementListIterator it;
51
Patrick Benavoli68a91282011-08-31 11:23:23 +020052 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
53
54 CConfigurableElement* pConfigurableElement = *it;
55
56 // Remove from configurable element
57 pConfigurableElement->removeAttachedConfigurableDomain(this);
58 }
Patrick Benavoli63499d42011-10-24 18:50:03 +020059
60 // Remove all associated syncer sets
61 ConfigurableElementToSyncerSetMapIterator mapIt;
62
63 for (mapIt = _configurableElementToSyncerSetMap.begin(); mapIt != _configurableElementToSyncerSetMap.end(); ++mapIt) {
64
65 delete mapIt->second;
66 }
Patrick Benavoli68a91282011-08-31 11:23:23 +020067}
68
69string CConfigurableDomain::getKind() const
70{
71 return "ConfigurableDomain";
72}
73
74bool CConfigurableDomain::childrenAreDynamic() const
75{
76 return true;
77}
78
Patrick Benavoli0bd50542011-11-29 11:10:27 +010079// Content dumping
80void CConfigurableDomain::logValue(string& strValue, CErrorContext& errorContext) const
81{
82 (void)errorContext;
83
84 strValue = "{";
85
86 // Sequence awareness
87 strValue += "Sequence aware: ";
88 strValue += _bSequenceAware ? "yes" : "no";
89
90 // Last applied configuration
91 strValue += ", Last applied configuration: ";
92 strValue += _pLastAppliedConfiguration ? _pLastAppliedConfiguration->getName() : "<none>";
93
94 strValue += "}";
95}
96
Patrick Benavoli63499d42011-10-24 18:50:03 +020097// Sequence awareness
98void CConfigurableDomain::setSequenceAwareness(bool bSequenceAware)
99{
100 if (_bSequenceAware != bSequenceAware) {
101
Kevin Rocardace81f82012-12-11 16:19:17 +0100102 log_info("Making domain \"%s\" sequence %s", getName().c_str(), bSequenceAware ? "aware" : "unaware");
Patrick Benavoli63499d42011-10-24 18:50:03 +0200103
104 _bSequenceAware = bSequenceAware;
105 }
106}
107
108bool CConfigurableDomain::getSequenceAwareness() const
109{
110 return _bSequenceAware;
111}
112
Patrick Benavoli68a91282011-08-31 11:23:23 +0200113// From IXmlSource
114void CConfigurableDomain::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
115{
David Wagner8cb5d882014-12-09 15:26:06 +0100116 base::toXml(xmlElement, serializingContext);
117
Patrick Benavoli63499d42011-10-24 18:50:03 +0200118 // Sequence awareness
119 xmlElement.setAttributeBoolean("SequenceAware", _bSequenceAware);
David Wagner8cb5d882014-12-09 15:26:06 +0100120}
Patrick Benavoli63499d42011-10-24 18:50:03 +0200121
David Wagner8cb5d882014-12-09 15:26:06 +0100122void CConfigurableDomain::childrenToXml(CXmlElement& xmlElement,
123 CXmlSerializingContext& serializingContext) const
124{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200125 // Configurations
126 composeDomainConfigurations(xmlElement, serializingContext);
127
128 // Configurable Elements
Patrick Benavoli63499d42011-10-24 18:50:03 +0200129 composeConfigurableElements(xmlElement);
130
131 // Settings
132 composeSettings(xmlElement, serializingContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200133}
134
135// XML composing
136void CConfigurableDomain::composeDomainConfigurations(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
137{
138 // Create Configurations element
139 CXmlElement xmlConfigurationsElement;
140
141 xmlElement.createChild(xmlConfigurationsElement, "Configurations");
142
143 // Delegate to base
David Wagner8cb5d882014-12-09 15:26:06 +0100144 base::childrenToXml(xmlConfigurationsElement, serializingContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200145}
146
Patrick Benavoli63499d42011-10-24 18:50:03 +0200147void CConfigurableDomain::composeConfigurableElements(CXmlElement& xmlElement) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200148{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200149 // Create ConfigurableElements element
150 CXmlElement xmlConfigurableElementsElement;
151
152 xmlElement.createChild(xmlConfigurableElementsElement, "ConfigurableElements");
153
154 // Serialize out all configurable elements settings
155 ConfigurableElementListIterator it;
156
157 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
158
159 const CConfigurableElement* pConfigurableElement = *it;
160
161 // Create corresponding XML child element
162 CXmlElement xmlChildConfigurableElement;
163
164 xmlConfigurableElementsElement.createChild(xmlChildConfigurableElement, "ConfigurableElement");
165
166 // Set Path attribute
167 xmlChildConfigurableElement.setAttributeString("Path", pConfigurableElement->getPath());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200168 }
169}
170
Patrick Benavoli63499d42011-10-24 18:50:03 +0200171void CConfigurableDomain::composeSettings(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200172{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200173 // Context
David Wagner29fa61f2014-12-19 11:15:02 +0100174 const CXmlDomainExportContext& xmlDomainExportContext =
175 static_cast<const CXmlDomainExportContext&>(serializingContext);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200176
David Wagner29fa61f2014-12-19 11:15:02 +0100177 if (!xmlDomainExportContext.withSettings()) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200178
179 return;
180 }
181
182 // Create Settings element
183 CXmlElement xmlSettingsElement;
184
185 xmlElement.createChild(xmlSettingsElement, "Settings");
186
187 // Serialize out all configurations settings
Patrick Benavoli68a91282011-08-31 11:23:23 +0200188 uint32_t uiNbConfigurations = getNbChildren();
189 uint32_t uiChildConfiguration;
190
191 for (uiChildConfiguration = 0; uiChildConfiguration < uiNbConfigurations; uiChildConfiguration++) {
192
193 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChildConfiguration));
194
195 // Create child xml element for that configuration
196 CXmlElement xmlConfigurationSettingsElement;
197
Patrick Benavoli63499d42011-10-24 18:50:03 +0200198 xmlSettingsElement.createChild(xmlConfigurationSettingsElement, pDomainConfiguration->getKind());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200199
200 // Set its name attribute
201 xmlConfigurationSettingsElement.setNameAttribute(pDomainConfiguration->getName());
202
Patrick Benavoli63499d42011-10-24 18:50:03 +0200203 // Serialize out configuration settings
204 pDomainConfiguration->composeSettings(xmlConfigurationSettingsElement, serializingContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200205 }
206}
207
208// From IXmlSink
209bool CConfigurableDomain::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
210{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200211 // Context
David Wagner29fa61f2014-12-19 11:15:02 +0100212 CXmlDomainImportContext& xmlDomainImportContext =
213 static_cast<CXmlDomainImportContext&>(serializingContext);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200214
215 // Sequence awareness (optional)
216 _bSequenceAware = xmlElement.hasAttribute("SequenceAware") && xmlElement.getAttributeBoolean("SequenceAware");
217
Patrick Benavoli68a91282011-08-31 11:23:23 +0200218 // Local parsing. Do not dig
David Wagner29fa61f2014-12-19 11:15:02 +0100219 if (!parseDomainConfigurations(xmlElement, xmlDomainImportContext) ||
220 !parseConfigurableElements(xmlElement, xmlDomainImportContext) ||
221 !parseSettings(xmlElement, xmlDomainImportContext)) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200222
223 return false;
224 }
225
226 // All provided configurations are parsed
227 // Attempt validation on areas of non provided configurations for all configurable elements if required
David Wagner29fa61f2014-12-19 11:15:02 +0100228 if (xmlDomainImportContext.autoValidationRequired()) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200229
230 autoValidateAll();
231 }
232
233 return true;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200234}
235
236// XML parsing
David Wagner29fa61f2014-12-19 11:15:02 +0100237bool CConfigurableDomain::parseDomainConfigurations(const CXmlElement& xmlElement,
238 CXmlDomainImportContext& serializingContext)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200239{
240 // We're supposedly clean
241 assert(_configurableElementList.empty());
242
243 // Get Configurations element
244 CXmlElement xmlConfigurationsElement;
245
246 xmlElement.getChildElement("Configurations", xmlConfigurationsElement);
247
248 // Parse it and create domain configuration objects
249 return base::fromXml(xmlConfigurationsElement, serializingContext);
250}
251
252// Parse configurable elements
David Wagner29fa61f2014-12-19 11:15:02 +0100253bool CConfigurableDomain::parseConfigurableElements(const CXmlElement& xmlElement,
254 CXmlDomainImportContext& serializingContext)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200255{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200256 // Get System Class Element
257 CElement* pRootElement = getRoot();
258
259 CElement* pSystemClassElement = pRootElement->findChildOfKind("SystemClass");
260
261 assert(pSystemClassElement);
262
263 // Get ConfigurableElements element
264 CXmlElement xmlConfigurableElementsElement;
265 xmlElement.getChildElement("ConfigurableElements", xmlConfigurableElementsElement);
266
267 // Parse it and associate found configurable elements to it
268 CXmlElement::CChildIterator it(xmlConfigurableElementsElement);
269
270 CXmlElement xmlConfigurableElementElement;
271
272 while (it.next(xmlConfigurableElementElement)) {
273
274 // Locate configurable element
275 string strConfigurableElementPath = xmlConfigurableElementElement.getAttributeString("Path");
276
277 CPathNavigator pathNavigator(strConfigurableElementPath);
Patrick Benavoli065264a2011-11-20 15:46:41 +0100278 string strError;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200279
280 // Is there an element and does it match system class name?
Patrick Benavoli065264a2011-11-20 15:46:41 +0100281 if (!pathNavigator.navigateThrough(pSystemClassElement->getName(), strError)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200282
Patrick Benavoli065264a2011-11-20 15:46:41 +0100283 serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName() + " (" + strError + ")");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200284
285 return false;
286 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200287 // Browse system class for configurable element
288 CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(pSystemClassElement->findDescendant(pathNavigator));
289
290 if (!pConfigurableElement) {
291
292 serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName());
293
294 return false;
295 }
296 // Add found element to domain
Patrick Benavoli68a91282011-08-31 11:23:23 +0200297 if (!addConfigurableElement(pConfigurableElement, NULL, strError)) {
298
299 serializingContext.setError(strError);
300
301 return false;
302 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200303 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200304
305 return true;
306}
307
Patrick Benavoli63499d42011-10-24 18:50:03 +0200308// Parse settings
David Wagner29fa61f2014-12-19 11:15:02 +0100309bool CConfigurableDomain::parseSettings(const CXmlElement& xmlElement,
310 CXmlDomainImportContext& serializingContext)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200311{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200312 // Check we actually need to parse configuration settings
David Wagner29fa61f2014-12-19 11:15:02 +0100313 if (!serializingContext.withSettings()) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200314
315 // No parsing required
316 return true;
317 }
318
319 // Get Settings element
320 CXmlElement xmlSettingsElement;
321 if (!xmlElement.getChildElement("Settings", xmlSettingsElement)) {
322
323 // No settings, bail out successfully
324 return true;
325 }
326
327 // Parse configuration settings
328 CXmlElement::CChildIterator it(xmlSettingsElement);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200329
330 CXmlElement xmlConfigurationSettingsElement;
331
332 while (it.next(xmlConfigurationSettingsElement)) {
333 // Get domain configuration
334 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(xmlConfigurationSettingsElement.getNameAttribute()));
335
336 if (!pDomainConfiguration) {
337
David Wagner29fa61f2014-12-19 11:15:02 +0100338 serializingContext.setError("Could not find domain configuration referred to by"
339 " configurable domain \"" + getName() + "\".");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200340
341 return false;
342 }
Patrick Benavoli63499d42011-10-24 18:50:03 +0200343 // Have domain configuration parse settings for all configurable elements
David Wagner29fa61f2014-12-19 11:15:02 +0100344 if (!pDomainConfiguration->parseSettings(xmlConfigurationSettingsElement,
345 serializingContext)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200346
347 return false;
348 }
349 }
350
351 return true;
352}
Patrick Benavoli68a91282011-08-31 11:23:23 +0200353// Configurable elements association
354bool CConfigurableDomain::addConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, string& strError)
355{
356 // Already associated?
357 if (containsConfigurableElement(pConfigurableElement)) {
358
359 strError = "Configurable element " + pConfigurableElement->getPath() + " already associated to configuration domain " + getName();
360
361 return false;
362 }
363
364 // Already owned?
365 if (pConfigurableElement->belongsTo(this)) {
366
367 strError = "Configurable element " + pConfigurableElement->getPath() + " already owned by configuration domain " + getName();
368
369 return false;
370 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200371
372 // Do add
Frédéric Boisnard9620e442012-05-30 16:15:02 +0200373 doAddConfigurableElement(pConfigurableElement, pMainBlackboard);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200374
375 return true;
376}
377
378bool CConfigurableDomain::removeConfigurableElement(CConfigurableElement* pConfigurableElement, string& strError)
379{
380 // Not associated?
381 if (!containsConfigurableElement(pConfigurableElement)) {
382
383 strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName();
384
385 return false;
386 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100387 log_info("Removing configurable element \"%s\" from domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200388
389 // Do remove
390 doRemoveConfigurableElement(pConfigurableElement, true);
391
392 return true;
393}
394
Frédéric Boisnarde42dacd2013-02-25 15:56:56 +0100395/**
396* Blackboard Configuration and Base Offset retrieval.
397*
398* This method fetches the Blackboard associated to the ConfigurableElement
399* given in parameter, for a specific Configuration. The ConfigurableElement
400* must belong to the Domain. If a Blackboard is found, the base offset of
401* the ConfigurableElement is returned as well. This base offset corresponds to
402* the offset of the ancestor of the ConfigurableElement associated to the Configuration.
403*
404* @param[in] strConfiguration Name of the Configuration.
405* @param[in] pCandidateDescendantConfigurableElement Pointer to a CConfigurableElement that
406* belongs to the Domain.
407* @param[out] uiBaseOffset The base offset of the CConfigurableElement.
408* @param[out] bIsLastApplied Boolean indicating that the Configuration is
409* the last one applied of the Domain.
410* @param[out] strError Error message
411*
412* return Pointer to the Blackboard of the Configuration.
413*/
414CParameterBlackboard* CConfigurableDomain::findConfigurationBlackboard(const string& strConfiguration,
415 const CConfigurableElement* pCandidateDescendantConfigurableElement,
416 uint32_t& uiBaseOffset,
417 bool& bIsLastApplied,
418 string& strError) const
419{
420 // Find Configuration
421 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(findChild(strConfiguration));
422
423 if (!pDomainConfiguration) {
424
425 strError = "Domain configuration " + strConfiguration + " not found";
426
427 return NULL;
428 }
429
430 // Parse all configurable elements
431 ConfigurableElementListIterator it;
432
433 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
434
435 const CConfigurableElement* pAssociatedConfigurableElement = *it;
436
437 // Check if the the associated element is the configurable element or one of its ancestors
438 if ((pCandidateDescendantConfigurableElement == pAssociatedConfigurableElement) ||
439 (pCandidateDescendantConfigurableElement->isDescendantOf(pAssociatedConfigurableElement))) {
440
441 uiBaseOffset = pAssociatedConfigurableElement->getOffset();
442 bIsLastApplied = (pDomainConfiguration == _pLastAppliedConfiguration);
443
444 return pDomainConfiguration->getBlackboard(pAssociatedConfigurableElement);
445 }
446 }
447
448 strError = "Element not associated to the Domain";
449
450 return NULL;
451}
452
Patrick Benavoli68a91282011-08-31 11:23:23 +0200453// Domain splitting
454bool CConfigurableDomain::split(CConfigurableElement* pConfigurableElement, string& strError)
455{
456 // Not associated?
457 if (!containsConfigurableElement(pConfigurableElement)) {
458
459 strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName();
460
461 return false;
462 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100463 log_info("Splitting configurable element \"%s\" domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200464
465 // Create sub domain areas for all configurable element's children
466 uint32_t uiNbConfigurableElementChildren = pConfigurableElement->getNbChildren();
467
468 if (!uiNbConfigurableElementChildren) {
469
470 strError = "Configurable element " + pConfigurableElement->getPath() + " has no children to split configurable domain to";
471
472 return false;
473 }
474
475 uint32_t uiChild;
476
477 for (uiChild = 0; uiChild < uiNbConfigurableElementChildren; uiChild++) {
478
479 CConfigurableElement* pChildConfigurableElement = static_cast<CConfigurableElement*>(pConfigurableElement->getChild(uiChild));
480
481 doAddConfigurableElement(pChildConfigurableElement);
482 }
483
484 // Delegate to configurations
485 uint32_t uiNbConfigurations = getNbChildren();
486
487 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
488
489 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
490
491 pDomainConfiguration->split(pConfigurableElement);
492 }
493
494 // Remove given configurable element from this domain
495 // 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
496 doRemoveConfigurableElement(pConfigurableElement, false);
497
498 return true;
499}
500
Frédéric Boisnard8b243f52012-09-06 18:03:20 +0200501// Check if there is a pending configuration for this domain: i.e. an applicable configuration different from the last applied configuration
502const CDomainConfiguration* CConfigurableDomain::getPendingConfiguration() const
503{
504 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
505
506 if (pApplicableDomainConfiguration) {
507
508 // Check not the last one before applying
509 if (!_pLastAppliedConfiguration || (_pLastAppliedConfiguration != pApplicableDomainConfiguration)) {
510
511 return pApplicableDomainConfiguration;
512 }
513 }
514
515 return NULL;
516}
517
Patrick Benavoli68a91282011-08-31 11:23:23 +0200518// Configuration application if required
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100519void CConfigurableDomain::apply(CParameterBlackboard* pParameterBlackboard, CSyncerSet* pSyncerSet, bool bForce) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200520{
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100521 // Apply configuration only if the blackboard will
522 // be synchronized either now or by syncerSet.
523 if(!pSyncerSet ^ _bSequenceAware) {
524 // The configuration can not be syncronised
525 return;
526 }
527
Patrick Benavoli68a91282011-08-31 11:23:23 +0200528 if (bForce) {
529 // Force a configuration restore by forgetting about last applied configuration
530 _pLastAppliedConfiguration = NULL;
531 }
532 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
533
534 if (pApplicableDomainConfiguration) {
535
536 // Check not the last one before applying
537 if (!_pLastAppliedConfiguration || _pLastAppliedConfiguration != pApplicableDomainConfiguration) {
538
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100539 log_info("Applying configuration \"%s\" from domain \"%s\"",
540 pApplicableDomainConfiguration->getName().c_str(),
541 getName().c_str());
542
543 // Check if we need to synchronize during restore
544 bool bSync = !pSyncerSet && _bSequenceAware;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200545
546 // Do the restore
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100547 pApplicableDomainConfiguration->restore(pParameterBlackboard, bSync, NULL);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200548
549 // Record last applied configuration
550 _pLastAppliedConfiguration = pApplicableDomainConfiguration;
551
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100552 // Check we need to provide syncer set to caller
553 if (pSyncerSet && !_bSequenceAware) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200554
555 // Since we applied changes, add our own sync set to the given one
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100556 *pSyncerSet += _syncerSet;
Patrick Benavoli63499d42011-10-24 18:50:03 +0200557 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200558 }
559 }
560}
561
562// Return applicable configuration validity for given configurable element
563bool CConfigurableDomain::isApplicableConfigurationValid(const CConfigurableElement* pConfigurableElement) const
564{
565 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
566
567 return pApplicableDomainConfiguration && pApplicableDomainConfiguration->isValid(pConfigurableElement);
568}
569
Patrick Benavoli68a91282011-08-31 11:23:23 +0200570// In case configurable element was removed
571void CConfigurableDomain::computeSyncSet()
572{
573 // Clean sync set first
Patrick Benavoli63499d42011-10-24 18:50:03 +0200574 _syncerSet.clear();
Patrick Benavoli68a91282011-08-31 11:23:23 +0200575
Patrick Benavoli63499d42011-10-24 18:50:03 +0200576 // Add syncer sets for all associated configurable elements
577 ConfigurableElementToSyncerSetMapIterator mapIt;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200578
Patrick Benavoli63499d42011-10-24 18:50:03 +0200579 for (mapIt = _configurableElementToSyncerSetMap.begin(); mapIt != _configurableElementToSyncerSetMap.end(); ++mapIt) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200580
Patrick Benavoli63499d42011-10-24 18:50:03 +0200581 const CSyncerSet* pSyncerSet = mapIt->second;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200582
Patrick Benavoli63499d42011-10-24 18:50:03 +0200583 _syncerSet += *pSyncerSet;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200584 }
585}
586
587// Configuration Management
588bool CConfigurableDomain::createConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError)
589{
590 // Already exists?
591 if (findChild(strName)) {
592
593 strError = "Already existing configuration";
594
595 return false;
596 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100597 log_info("Creating domain configuration \"%s\" into domain \"%s\"", strName.c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200598
599 // Creation
600 CDomainConfiguration* pDomainConfiguration = new CDomainConfiguration(strName);
601
602 // Configurable elements association
603 ConfigurableElementListIterator it;
604
605 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
606
Patrick Benavoli63499d42011-10-24 18:50:03 +0200607 const CConfigurableElement* pConfigurableElement = *it;;
608
609 // Retrieve associated syncer set
610 CSyncerSet* pSyncerSet = getSyncerSet(pConfigurableElement);
611
612 // Associate to configuration
613 pDomainConfiguration->addConfigurableElement(pConfigurableElement, pSyncerSet);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200614 }
615
616 // Hierarchy
617 addChild(pDomainConfiguration);
618
619 // Ensure validity of fresh new domain configuration
620 // Attempt auto validation, so that the user gets his/her own settings by defaults
621 if (!autoValidateConfiguration(pDomainConfiguration)) {
622
623 // No valid configuration found to copy in from, validate againt main blackboard (will concerned remaining invalid parts)
624 pDomainConfiguration->validate(pMainBlackboard);
625 }
626
627 return true;
628}
629
630bool CConfigurableDomain::deleteConfiguration(const string& strName, string& strError)
631{
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100632 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200633
634 if (!pDomainConfiguration) {
635
Patrick Benavoli68a91282011-08-31 11:23:23 +0200636 return false;
637 }
638
Kevin Rocardace81f82012-12-11 16:19:17 +0100639 log_info("Deleting configuration \"%s\" from domain \"%s\"", strName.c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200640
641 // Was the last applied?
642 if (pDomainConfiguration == _pLastAppliedConfiguration) {
643
644 // Forget about it
645 _pLastAppliedConfiguration = NULL;
646 }
647
648 // Hierarchy
649 removeChild(pDomainConfiguration);
650
651 // Destroy
652 delete pDomainConfiguration;
653
654 return true;
655}
656
657void CConfigurableDomain::listAssociatedToElements(string& strResult) const
658{
659 strResult = "\n";
660
661 ConfigurableElementListIterator it;
662
663 // Browse all configurable elements
664 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
665
666 const CConfigurableElement* pConfigurableElement = *it;
667
668 strResult += pConfigurableElement->getPath() + "\n";
669 }
670}
671
672bool CConfigurableDomain::renameConfiguration(const string& strName, const string& strNewName, string& strError)
673{
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100674 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200675
676 if (!pDomainConfiguration) {
677
Patrick Benavoli68a91282011-08-31 11:23:23 +0200678 return false;
679 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100680 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 +0200681
682 // Rename
683 return pDomainConfiguration->rename(strNewName, strError);
684}
685
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100686bool CConfigurableDomain::restoreConfiguration(const string& strName, CParameterBlackboard* pMainBlackboard, bool bAutoSync, std::list<string>& lstrError) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200687{
Kevin Rocardace81f82012-12-11 16:19:17 +0100688 string strError;
689
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100690 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200691
692 if (!pDomainConfiguration) {
693
Kevin Rocardace81f82012-12-11 16:19:17 +0100694 lstrError.push_back(strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200695 return false;
696 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100697 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 +0200698
699 // Delegate
Kevin Rocardace81f82012-12-11 16:19:17 +0100700 bool bSuccess = pDomainConfiguration->restore(pMainBlackboard, bAutoSync && _bSequenceAware, &lstrError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200701
702 // Record last applied configuration
703 _pLastAppliedConfiguration = pDomainConfiguration;
704
705 // Synchronize
Kevin Rocardace81f82012-12-11 16:19:17 +0100706 if (bAutoSync && !_bSequenceAware) {
707
708 bSuccess &= _syncerSet.sync(*pMainBlackboard, false, &lstrError);
709 }
710 return bSuccess;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200711}
712
713bool CConfigurableDomain::saveConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError)
714{
715 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100716 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200717
718 if (!pDomainConfiguration) {
719
Patrick Benavoli68a91282011-08-31 11:23:23 +0200720 return false;
721 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100722 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 +0200723
724 // Delegate
725 pDomainConfiguration->save(pMainBlackboard);
726
727 return true;
728}
729
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100730bool CConfigurableDomain::setElementSequence(const string& strConfiguration, const std::vector<string>& astrNewElementSequence, string& strError)
Patrick Benavoli63499d42011-10-24 18:50:03 +0200731{
732 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100733 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
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 return pDomainConfiguration->setElementSequence(astrNewElementSequence, strError);
742}
743
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100744bool CConfigurableDomain::getElementSequence(const string& strConfiguration, string& strResult) const
Patrick Benavoli63499d42011-10-24 18:50:03 +0200745{
746 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100747 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strResult);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200748
749 if (!pDomainConfiguration) {
750
Patrick Benavoli63499d42011-10-24 18:50:03 +0200751 return false;
752 }
753
754 // Delegate to configuration
755 pDomainConfiguration->getElementSequence(strResult);
756
757 return true;
758}
759
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100760bool CConfigurableDomain::setApplicationRule(const string& strConfiguration, const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, 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 return pDomainConfiguration->setApplicationRule(strApplicationRule, pSelectionCriteriaDefinition, strError);
772}
773
774bool CConfigurableDomain::clearApplicationRule(const string& strConfiguration, string& strError)
775{
776 // Find Domain configuration
777 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
778
779 if (!pDomainConfiguration) {
780
781 return false;
782 }
783
784 // Delegate to configuration
785 pDomainConfiguration->clearApplicationRule();
786
787 return true;
788}
789
790bool CConfigurableDomain::getApplicationRule(const string& strConfiguration, string& strResult) const
791{
792 // Find Domain configuration
793 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strResult);
794
795 if (!pDomainConfiguration) {
796
797 return false;
798 }
799
800 // Delegate to configuration
801 pDomainConfiguration->getApplicationRule(strResult);
802
803 return true;
804}
805
Patrick Benavoli68a91282011-08-31 11:23:23 +0200806// Last applied configuration
807string CConfigurableDomain::getLastAppliedConfigurationName() const
808{
809 if (_pLastAppliedConfiguration) {
810
811 return _pLastAppliedConfiguration->getName();
812 }
813 return "<none>";
814}
815
Frédéric Boisnard8b243f52012-09-06 18:03:20 +0200816// Pending configuration
817string CConfigurableDomain::getPendingConfigurationName() const
818{
819 const CDomainConfiguration* pPendingConfiguration = getPendingConfiguration();
820
821 if (pPendingConfiguration) {
822
823 return pPendingConfiguration->getName();
824 }
825 return "<none>";
826}
827
Patrick Benavoli68a91282011-08-31 11:23:23 +0200828// Ensure validity on whole domain from main blackboard
829void CConfigurableDomain::validate(const CParameterBlackboard* pMainBlackboard)
830{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200831
832 // Propagate
833 uint32_t uiNbConfigurations = getNbChildren();
834 uint32_t uiChild;
835
836 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
837
838 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
839
840 pDomainConfiguration->validate(pMainBlackboard);
841 }
842}
843
844// Ensure validity on areas related to configurable element
845void CConfigurableDomain::validateAreas(const CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard)
846{
Kevin Rocardace81f82012-12-11 16:19:17 +0100847 log_info("Validating domain \"" + getName() + "\" against main blackboard for configurable element \"" + pConfigurableElement->getPath() + "\"");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200848
849 // Propagate
850 uint32_t uiNbConfigurations = getNbChildren();
851 uint32_t uiChild;
852
853 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
854
855 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
856
857 pDomainConfiguration->validate(pConfigurableElement, pMainBlackboard);
858 }
859}
860
861// Attempt validation for all configurable element's areas, relying on already existing valid configuration inside domain
862void CConfigurableDomain::autoValidateAll()
863{
864 // Validate
865 ConfigurableElementListIterator it;
866
867 // Browse all configurable elements for configuration validation
868 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
869
870 const CConfigurableElement* pConfigurableElement = *it;
871
872 // Auto validate element
873 autoValidateAreas(pConfigurableElement);
874 }
875}
876
877// Attempt validation for configurable element's areas, relying on already existing valid configuration inside domain
878void CConfigurableDomain::autoValidateAreas(const CConfigurableElement* pConfigurableElement)
879{
880 // Find first valid configuration for given configurable element
881 const CDomainConfiguration* pValidDomainConfiguration = findValidDomainConfiguration(pConfigurableElement);
882
883 // No valid configuration found, give up
884 if (!pValidDomainConfiguration) {
885
886 return;
887 }
888
Patrick Benavoli68a91282011-08-31 11:23:23 +0200889 // Validate all other configurations against found one, if any
890 uint32_t uiNbConfigurations = getNbChildren();
891 uint32_t uiChild;
892
893 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
894
895 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
896
897 if (pDomainConfiguration != pValidDomainConfiguration && !pDomainConfiguration->isValid(pConfigurableElement)) {
898 // Validate
899 pDomainConfiguration->validateAgainst(pValidDomainConfiguration, pConfigurableElement);
900 }
901 }
902}
903
904// Attempt configuration validation for all configurable elements' areas, relying on already existing valid configuration inside domain
905bool CConfigurableDomain::autoValidateConfiguration(CDomainConfiguration* pDomainConfiguration)
906{
907 // Find another configuration than this one, that ought to be valid!
908 uint32_t uiNbConfigurations = getNbChildren();
909 uint32_t uiChild;
910
911 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
912
913 const CDomainConfiguration* pPotententialValidDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
914
915 if (pPotententialValidDomainConfiguration != pDomainConfiguration) {
916
917 // Validate against it
918 pDomainConfiguration->validateAgainst(pPotententialValidDomainConfiguration);
919
920 return true;
921 }
922 }
923 return false;
924}
Patrick Benavoli68a91282011-08-31 11:23:23 +0200925
Patrick Benavoli68a91282011-08-31 11:23:23 +0200926// Search for a valid configuration for given configurable element
927const CDomainConfiguration* CConfigurableDomain::findValidDomainConfiguration(const CConfigurableElement* pConfigurableElement) const
928{
929 uint32_t uiNbConfigurations = getNbChildren();
930 uint32_t uiChild;
931
932 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
933
934 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
935
936 if (pDomainConfiguration->isValid(pConfigurableElement)) {
937
938 return pDomainConfiguration;
939 }
940 }
941 return NULL;
942}
943
944// Search for an applicable configuration
945const CDomainConfiguration* CConfigurableDomain::findApplicableDomainConfiguration() const
946{
947 uint32_t uiNbConfigurations = getNbChildren();
948 uint32_t uiChild;
949
950 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
951
952 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
953
954 if (pDomainConfiguration->isApplicable()) {
955
956 return pDomainConfiguration;
957 }
958 }
959 return NULL;
960}
961
962// Gather set of configurable elements
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100963void CConfigurableDomain::gatherConfigurableElements(std::set<const CConfigurableElement*>& configurableElementSet) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200964{
965 // Insert all configurable elements
966 configurableElementSet.insert(_configurableElementList.begin(), _configurableElementList.end());
967}
968
969// Check configurable element already attached
970bool CConfigurableDomain::containsConfigurableElement(const CConfigurableElement* pConfigurableCandidateElement) const
971{
972 ConfigurableElementListIterator it;
973
974 // Browse all configurable elements for comparison
975 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
976
977 if (pConfigurableCandidateElement == *it) {
978
979 return true;
980 }
981 }
982 return false;
983}
984
985// Merge any descended configurable element to this one with this one
986void CConfigurableDomain::mergeAlreadyAssociatedDescendantConfigurableElements(CConfigurableElement* pNewConfigurableElement)
987{
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100988 std::list<CConfigurableElement*> mergedConfigurableElementList;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200989
990 ConfigurableElementListIterator it;
991
992 // Browse all configurable elements (new one not yet in the list!)
993 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
994
995 CConfigurableElement* pConfigurablePotentialDescendantElement = *it;
996
997 if (pConfigurablePotentialDescendantElement->isDescendantOf(pNewConfigurableElement)) {
998
Kevin Rocardace81f82012-12-11 16:19:17 +0100999 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 +02001000
1001 // Merge configuration data
1002 mergeConfigurations(pNewConfigurableElement, pConfigurablePotentialDescendantElement);
1003
1004 // Keep track for removal
1005 mergedConfigurableElementList.push_back(pConfigurablePotentialDescendantElement);
1006 }
1007 }
1008
1009 // Remove all merged elements (new one not yet in the list!)
1010 for (it = mergedConfigurableElementList.begin(); it != mergedConfigurableElementList.end(); ++it) {
1011
1012 CConfigurableElement* pMergedConfigurableElement = *it;
1013
1014 // Remove merged from configurable element from internal tracking list
1015 // 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
1016 doRemoveConfigurableElement(pMergedConfigurableElement, false);
1017 }
1018}
1019
1020void CConfigurableDomain::mergeConfigurations(CConfigurableElement* pToConfigurableElement, CConfigurableElement* pFromConfigurableElement)
1021{
1022 // Propagate to domain configurations
1023 uint32_t uiNbConfigurations = getNbChildren();
1024 uint32_t uiChild;
1025
1026 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1027
1028 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1029
1030 // Do the merge.
1031 pDomainConfiguration->merge(pToConfigurableElement, pFromConfigurableElement);
1032 }
1033}
1034
1035// Configurable elements association
Frédéric Boisnard9620e442012-05-30 16:15:02 +02001036void CConfigurableDomain::doAddConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard *pMainBlackboard)
Patrick Benavoli68a91282011-08-31 11:23:23 +02001037{
1038 // Inform configurable element
1039 pConfigurableElement->addAttachedConfigurableDomain(this);
1040
Patrick Benavoli63499d42011-10-24 18:50:03 +02001041 // Create associated syncer set
1042 CSyncerSet* pSyncerSet = new CSyncerSet;
1043
1044 // Add to sync set the configurable element one
1045 pConfigurableElement->fillSyncerSet(*pSyncerSet);
1046
1047 // Store it
1048 _configurableElementToSyncerSetMap[pConfigurableElement] = pSyncerSet;
1049
1050 // Add it to global one
1051 _syncerSet += *pSyncerSet;
1052
Patrick Benavoli68a91282011-08-31 11:23:23 +02001053 // Inform configurations
1054 uint32_t uiNbConfigurations = getNbChildren();
1055 uint32_t uiChild;
1056
1057 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1058
1059 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1060
Patrick Benavoli63499d42011-10-24 18:50:03 +02001061 pDomainConfiguration->addConfigurableElement(pConfigurableElement, pSyncerSet);
Patrick Benavoli68a91282011-08-31 11:23:23 +02001062 }
Patrick Benavoli68a91282011-08-31 11:23:23 +02001063
Frédéric Boisnard9620e442012-05-30 16:15:02 +02001064 // Ensure area validity for that configurable element (if main blackboard provided)
1065 if (pMainBlackboard) {
1066
1067 // Need to validate against main blackboard
1068 validateAreas(pConfigurableElement, pMainBlackboard);
1069 }
1070
1071 // Already associated descendend configurable elements need a merge of their configuration data
Patrick Benavoli68a91282011-08-31 11:23:23 +02001072 mergeAlreadyAssociatedDescendantConfigurableElements(pConfigurableElement);
1073
1074 // Add to list
1075 _configurableElementList.push_back(pConfigurableElement);
1076}
1077
1078void CConfigurableDomain::doRemoveConfigurableElement(CConfigurableElement* pConfigurableElement, bool bRecomputeSyncSet)
1079{
1080 // Remove from list
1081 _configurableElementList.remove(pConfigurableElement);
1082
Patrick Benavoli63499d42011-10-24 18:50:03 +02001083 // Remove associated syncer set
1084 CSyncerSet* pSyncerSet = getSyncerSet(pConfigurableElement);
1085
1086 _configurableElementToSyncerSetMap.erase(pConfigurableElement);
1087
1088 delete pSyncerSet;
1089
Patrick Benavoli68a91282011-08-31 11:23:23 +02001090 // Inform configurable element
1091 pConfigurableElement->removeAttachedConfigurableDomain(this);
1092
1093 // Inform configurations
1094 uint32_t uiNbConfigurations = getNbChildren();
1095 uint32_t uiChild;
1096
1097 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1098
1099 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1100
1101 pDomainConfiguration->removeConfigurableElement(pConfigurableElement);
1102 }
1103 // Recompute our sync set if needed
1104 if (bRecomputeSyncSet) {
1105
1106 computeSyncSet();
1107 }
1108}
Patrick Benavoli63499d42011-10-24 18:50:03 +02001109
1110// Syncer set retrieval from configurable element
1111CSyncerSet* CConfigurableDomain::getSyncerSet(const CConfigurableElement* pConfigurableElement) const
1112{
1113 ConfigurableElementToSyncerSetMapIterator mapIt = _configurableElementToSyncerSetMap.find(pConfigurableElement);
1114
1115 assert(mapIt != _configurableElementToSyncerSetMap.end());
1116
1117 return mapIt->second;
1118}
Patrick Benavoli0bd50542011-11-29 11:10:27 +01001119
1120// Configuration retrieval
1121CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strConfiguration, string& strError)
1122{
1123 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(strConfiguration));
1124
1125 if (!pDomainConfiguration) {
1126
1127 strError = "Domain configuration " + strConfiguration + " not found";
1128
1129 return NULL;
1130 }
1131 return pDomainConfiguration;
1132}
1133
1134const CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strConfiguration, string& strError) const
1135{
1136 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(findChild(strConfiguration));
1137
1138 if (!pDomainConfiguration) {
1139
1140 strError = "Domain configuration " + strConfiguration + " not found";
1141
1142 return NULL;
1143 }
1144 return pDomainConfiguration;
1145}