blob: bdcddd449ed52d7a5ea9ef4986f6d1e75c51e94b [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{
David Wagnerd8a53102014-12-10 14:49:23 +0100256 CSystemClass& systemClass = serializingContext.getSystemClass();
Patrick Benavoli68a91282011-08-31 11:23:23 +0200257
258 // Get ConfigurableElements element
259 CXmlElement xmlConfigurableElementsElement;
260 xmlElement.getChildElement("ConfigurableElements", xmlConfigurableElementsElement);
261
262 // Parse it and associate found configurable elements to it
263 CXmlElement::CChildIterator it(xmlConfigurableElementsElement);
264
265 CXmlElement xmlConfigurableElementElement;
266
267 while (it.next(xmlConfigurableElementElement)) {
268
269 // Locate configurable element
270 string strConfigurableElementPath = xmlConfigurableElementElement.getAttributeString("Path");
271
272 CPathNavigator pathNavigator(strConfigurableElementPath);
Patrick Benavoli065264a2011-11-20 15:46:41 +0100273 string strError;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200274
275 // Is there an element and does it match system class name?
David Wagnerd8a53102014-12-10 14:49:23 +0100276 if (!pathNavigator.navigateThrough(systemClass.getName(), strError)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200277
Patrick Benavoli065264a2011-11-20 15:46:41 +0100278 serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName() + " (" + strError + ")");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200279
280 return false;
281 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200282 // Browse system class for configurable element
David Wagnerd8a53102014-12-10 14:49:23 +0100283 CConfigurableElement* pConfigurableElement =
284 static_cast<CConfigurableElement*>(systemClass.findDescendant(pathNavigator));
Patrick Benavoli68a91282011-08-31 11:23:23 +0200285
286 if (!pConfigurableElement) {
287
288 serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName());
289
290 return false;
291 }
292 // Add found element to domain
Patrick Benavoli68a91282011-08-31 11:23:23 +0200293 if (!addConfigurableElement(pConfigurableElement, NULL, strError)) {
294
295 serializingContext.setError(strError);
296
297 return false;
298 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200299 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200300
301 return true;
302}
303
Patrick Benavoli63499d42011-10-24 18:50:03 +0200304// Parse settings
David Wagner29fa61f2014-12-19 11:15:02 +0100305bool CConfigurableDomain::parseSettings(const CXmlElement& xmlElement,
306 CXmlDomainImportContext& serializingContext)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200307{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200308 // Check we actually need to parse configuration settings
David Wagner29fa61f2014-12-19 11:15:02 +0100309 if (!serializingContext.withSettings()) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200310
311 // No parsing required
312 return true;
313 }
314
315 // Get Settings element
316 CXmlElement xmlSettingsElement;
317 if (!xmlElement.getChildElement("Settings", xmlSettingsElement)) {
318
319 // No settings, bail out successfully
320 return true;
321 }
322
323 // Parse configuration settings
324 CXmlElement::CChildIterator it(xmlSettingsElement);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200325
326 CXmlElement xmlConfigurationSettingsElement;
327
328 while (it.next(xmlConfigurationSettingsElement)) {
329 // Get domain configuration
330 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(xmlConfigurationSettingsElement.getNameAttribute()));
331
332 if (!pDomainConfiguration) {
333
David Wagner29fa61f2014-12-19 11:15:02 +0100334 serializingContext.setError("Could not find domain configuration referred to by"
335 " configurable domain \"" + getName() + "\".");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200336
337 return false;
338 }
Patrick Benavoli63499d42011-10-24 18:50:03 +0200339 // Have domain configuration parse settings for all configurable elements
David Wagner29fa61f2014-12-19 11:15:02 +0100340 if (!pDomainConfiguration->parseSettings(xmlConfigurationSettingsElement,
341 serializingContext)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200342
343 return false;
344 }
345 }
346
347 return true;
348}
Patrick Benavoli68a91282011-08-31 11:23:23 +0200349// Configurable elements association
350bool CConfigurableDomain::addConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, string& strError)
351{
352 // Already associated?
353 if (containsConfigurableElement(pConfigurableElement)) {
354
355 strError = "Configurable element " + pConfigurableElement->getPath() + " already associated to configuration domain " + getName();
356
357 return false;
358 }
359
360 // Already owned?
361 if (pConfigurableElement->belongsTo(this)) {
362
363 strError = "Configurable element " + pConfigurableElement->getPath() + " already owned by configuration domain " + getName();
364
365 return false;
366 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200367
368 // Do add
Frédéric Boisnard9620e442012-05-30 16:15:02 +0200369 doAddConfigurableElement(pConfigurableElement, pMainBlackboard);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200370
371 return true;
372}
373
374bool CConfigurableDomain::removeConfigurableElement(CConfigurableElement* pConfigurableElement, string& strError)
375{
376 // Not associated?
377 if (!containsConfigurableElement(pConfigurableElement)) {
378
379 strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName();
380
381 return false;
382 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100383 log_info("Removing configurable element \"%s\" from domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200384
385 // Do remove
386 doRemoveConfigurableElement(pConfigurableElement, true);
387
388 return true;
389}
390
Frédéric Boisnarde42dacd2013-02-25 15:56:56 +0100391/**
392* Blackboard Configuration and Base Offset retrieval.
393*
394* This method fetches the Blackboard associated to the ConfigurableElement
395* given in parameter, for a specific Configuration. The ConfigurableElement
396* must belong to the Domain. If a Blackboard is found, the base offset of
397* the ConfigurableElement is returned as well. This base offset corresponds to
398* the offset of the ancestor of the ConfigurableElement associated to the Configuration.
399*
400* @param[in] strConfiguration Name of the Configuration.
401* @param[in] pCandidateDescendantConfigurableElement Pointer to a CConfigurableElement that
402* belongs to the Domain.
403* @param[out] uiBaseOffset The base offset of the CConfigurableElement.
404* @param[out] bIsLastApplied Boolean indicating that the Configuration is
405* the last one applied of the Domain.
406* @param[out] strError Error message
407*
408* return Pointer to the Blackboard of the Configuration.
409*/
410CParameterBlackboard* CConfigurableDomain::findConfigurationBlackboard(const string& strConfiguration,
411 const CConfigurableElement* pCandidateDescendantConfigurableElement,
412 uint32_t& uiBaseOffset,
413 bool& bIsLastApplied,
414 string& strError) const
415{
416 // Find Configuration
417 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(findChild(strConfiguration));
418
419 if (!pDomainConfiguration) {
420
421 strError = "Domain configuration " + strConfiguration + " not found";
422
423 return NULL;
424 }
425
426 // Parse all configurable elements
427 ConfigurableElementListIterator it;
428
429 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
430
431 const CConfigurableElement* pAssociatedConfigurableElement = *it;
432
433 // Check if the the associated element is the configurable element or one of its ancestors
434 if ((pCandidateDescendantConfigurableElement == pAssociatedConfigurableElement) ||
435 (pCandidateDescendantConfigurableElement->isDescendantOf(pAssociatedConfigurableElement))) {
436
437 uiBaseOffset = pAssociatedConfigurableElement->getOffset();
438 bIsLastApplied = (pDomainConfiguration == _pLastAppliedConfiguration);
439
440 return pDomainConfiguration->getBlackboard(pAssociatedConfigurableElement);
441 }
442 }
443
444 strError = "Element not associated to the Domain";
445
446 return NULL;
447}
448
Patrick Benavoli68a91282011-08-31 11:23:23 +0200449// Domain splitting
450bool CConfigurableDomain::split(CConfigurableElement* pConfigurableElement, string& strError)
451{
452 // Not associated?
453 if (!containsConfigurableElement(pConfigurableElement)) {
454
455 strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName();
456
457 return false;
458 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100459 log_info("Splitting configurable element \"%s\" domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200460
461 // Create sub domain areas for all configurable element's children
462 uint32_t uiNbConfigurableElementChildren = pConfigurableElement->getNbChildren();
463
464 if (!uiNbConfigurableElementChildren) {
465
466 strError = "Configurable element " + pConfigurableElement->getPath() + " has no children to split configurable domain to";
467
468 return false;
469 }
470
471 uint32_t uiChild;
472
473 for (uiChild = 0; uiChild < uiNbConfigurableElementChildren; uiChild++) {
474
475 CConfigurableElement* pChildConfigurableElement = static_cast<CConfigurableElement*>(pConfigurableElement->getChild(uiChild));
476
477 doAddConfigurableElement(pChildConfigurableElement);
478 }
479
480 // Delegate to configurations
481 uint32_t uiNbConfigurations = getNbChildren();
482
483 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
484
485 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
486
487 pDomainConfiguration->split(pConfigurableElement);
488 }
489
490 // Remove given configurable element from this domain
491 // 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
492 doRemoveConfigurableElement(pConfigurableElement, false);
493
494 return true;
495}
496
Frédéric Boisnard8b243f52012-09-06 18:03:20 +0200497// Check if there is a pending configuration for this domain: i.e. an applicable configuration different from the last applied configuration
498const CDomainConfiguration* CConfigurableDomain::getPendingConfiguration() const
499{
500 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
501
502 if (pApplicableDomainConfiguration) {
503
504 // Check not the last one before applying
505 if (!_pLastAppliedConfiguration || (_pLastAppliedConfiguration != pApplicableDomainConfiguration)) {
506
507 return pApplicableDomainConfiguration;
508 }
509 }
510
511 return NULL;
512}
513
Patrick Benavoli68a91282011-08-31 11:23:23 +0200514// Configuration application if required
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100515void CConfigurableDomain::apply(CParameterBlackboard* pParameterBlackboard, CSyncerSet* pSyncerSet, bool bForce) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200516{
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100517 // Apply configuration only if the blackboard will
518 // be synchronized either now or by syncerSet.
519 if(!pSyncerSet ^ _bSequenceAware) {
520 // The configuration can not be syncronised
521 return;
522 }
523
Patrick Benavoli68a91282011-08-31 11:23:23 +0200524 if (bForce) {
525 // Force a configuration restore by forgetting about last applied configuration
526 _pLastAppliedConfiguration = NULL;
527 }
528 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
529
530 if (pApplicableDomainConfiguration) {
531
532 // Check not the last one before applying
533 if (!_pLastAppliedConfiguration || _pLastAppliedConfiguration != pApplicableDomainConfiguration) {
534
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100535 log_info("Applying configuration \"%s\" from domain \"%s\"",
536 pApplicableDomainConfiguration->getName().c_str(),
537 getName().c_str());
538
539 // Check if we need to synchronize during restore
540 bool bSync = !pSyncerSet && _bSequenceAware;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200541
542 // Do the restore
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100543 pApplicableDomainConfiguration->restore(pParameterBlackboard, bSync, NULL);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200544
545 // Record last applied configuration
546 _pLastAppliedConfiguration = pApplicableDomainConfiguration;
547
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100548 // Check we need to provide syncer set to caller
549 if (pSyncerSet && !_bSequenceAware) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200550
551 // Since we applied changes, add our own sync set to the given one
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100552 *pSyncerSet += _syncerSet;
Patrick Benavoli63499d42011-10-24 18:50:03 +0200553 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200554 }
555 }
556}
557
558// Return applicable configuration validity for given configurable element
559bool CConfigurableDomain::isApplicableConfigurationValid(const CConfigurableElement* pConfigurableElement) const
560{
561 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
562
563 return pApplicableDomainConfiguration && pApplicableDomainConfiguration->isValid(pConfigurableElement);
564}
565
Patrick Benavoli68a91282011-08-31 11:23:23 +0200566// In case configurable element was removed
567void CConfigurableDomain::computeSyncSet()
568{
569 // Clean sync set first
Patrick Benavoli63499d42011-10-24 18:50:03 +0200570 _syncerSet.clear();
Patrick Benavoli68a91282011-08-31 11:23:23 +0200571
Patrick Benavoli63499d42011-10-24 18:50:03 +0200572 // Add syncer sets for all associated configurable elements
573 ConfigurableElementToSyncerSetMapIterator mapIt;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200574
Patrick Benavoli63499d42011-10-24 18:50:03 +0200575 for (mapIt = _configurableElementToSyncerSetMap.begin(); mapIt != _configurableElementToSyncerSetMap.end(); ++mapIt) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200576
Patrick Benavoli63499d42011-10-24 18:50:03 +0200577 const CSyncerSet* pSyncerSet = mapIt->second;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200578
Patrick Benavoli63499d42011-10-24 18:50:03 +0200579 _syncerSet += *pSyncerSet;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200580 }
581}
582
583// Configuration Management
584bool CConfigurableDomain::createConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError)
585{
586 // Already exists?
587 if (findChild(strName)) {
588
589 strError = "Already existing configuration";
590
591 return false;
592 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100593 log_info("Creating domain configuration \"%s\" into domain \"%s\"", strName.c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200594
595 // Creation
596 CDomainConfiguration* pDomainConfiguration = new CDomainConfiguration(strName);
597
598 // Configurable elements association
599 ConfigurableElementListIterator it;
600
601 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
602
Patrick Benavoli63499d42011-10-24 18:50:03 +0200603 const CConfigurableElement* pConfigurableElement = *it;;
604
605 // Retrieve associated syncer set
606 CSyncerSet* pSyncerSet = getSyncerSet(pConfigurableElement);
607
608 // Associate to configuration
609 pDomainConfiguration->addConfigurableElement(pConfigurableElement, pSyncerSet);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200610 }
611
612 // Hierarchy
613 addChild(pDomainConfiguration);
614
615 // Ensure validity of fresh new domain configuration
616 // Attempt auto validation, so that the user gets his/her own settings by defaults
617 if (!autoValidateConfiguration(pDomainConfiguration)) {
618
619 // No valid configuration found to copy in from, validate againt main blackboard (will concerned remaining invalid parts)
620 pDomainConfiguration->validate(pMainBlackboard);
621 }
622
623 return true;
624}
625
626bool CConfigurableDomain::deleteConfiguration(const string& strName, string& strError)
627{
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100628 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200629
630 if (!pDomainConfiguration) {
631
Patrick Benavoli68a91282011-08-31 11:23:23 +0200632 return false;
633 }
634
Kevin Rocardace81f82012-12-11 16:19:17 +0100635 log_info("Deleting configuration \"%s\" from domain \"%s\"", strName.c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200636
637 // Was the last applied?
638 if (pDomainConfiguration == _pLastAppliedConfiguration) {
639
640 // Forget about it
641 _pLastAppliedConfiguration = NULL;
642 }
643
644 // Hierarchy
645 removeChild(pDomainConfiguration);
646
647 // Destroy
648 delete pDomainConfiguration;
649
650 return true;
651}
652
653void CConfigurableDomain::listAssociatedToElements(string& strResult) const
654{
655 strResult = "\n";
656
657 ConfigurableElementListIterator it;
658
659 // Browse all configurable elements
660 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
661
662 const CConfigurableElement* pConfigurableElement = *it;
663
664 strResult += pConfigurableElement->getPath() + "\n";
665 }
666}
667
668bool CConfigurableDomain::renameConfiguration(const string& strName, const string& strNewName, string& strError)
669{
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100670 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200671
672 if (!pDomainConfiguration) {
673
Patrick Benavoli68a91282011-08-31 11:23:23 +0200674 return false;
675 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100676 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 +0200677
678 // Rename
679 return pDomainConfiguration->rename(strNewName, strError);
680}
681
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100682bool CConfigurableDomain::restoreConfiguration(const string& strName, CParameterBlackboard* pMainBlackboard, bool bAutoSync, std::list<string>& lstrError) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200683{
Kevin Rocardace81f82012-12-11 16:19:17 +0100684 string strError;
685
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100686 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200687
688 if (!pDomainConfiguration) {
689
Kevin Rocardace81f82012-12-11 16:19:17 +0100690 lstrError.push_back(strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200691 return false;
692 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100693 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 +0200694
695 // Delegate
Kevin Rocardace81f82012-12-11 16:19:17 +0100696 bool bSuccess = pDomainConfiguration->restore(pMainBlackboard, bAutoSync && _bSequenceAware, &lstrError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200697
698 // Record last applied configuration
699 _pLastAppliedConfiguration = pDomainConfiguration;
700
701 // Synchronize
Kevin Rocardace81f82012-12-11 16:19:17 +0100702 if (bAutoSync && !_bSequenceAware) {
703
704 bSuccess &= _syncerSet.sync(*pMainBlackboard, false, &lstrError);
705 }
706 return bSuccess;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200707}
708
709bool CConfigurableDomain::saveConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError)
710{
711 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100712 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200713
714 if (!pDomainConfiguration) {
715
Patrick Benavoli68a91282011-08-31 11:23:23 +0200716 return false;
717 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100718 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 +0200719
720 // Delegate
721 pDomainConfiguration->save(pMainBlackboard);
722
723 return true;
724}
725
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100726bool CConfigurableDomain::setElementSequence(const string& strConfiguration, const std::vector<string>& astrNewElementSequence, string& strError)
Patrick Benavoli63499d42011-10-24 18:50:03 +0200727{
728 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100729 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200730
731 if (!pDomainConfiguration) {
732
Patrick Benavoli63499d42011-10-24 18:50:03 +0200733 return false;
734 }
735
736 // Delegate to configuration
737 return pDomainConfiguration->setElementSequence(astrNewElementSequence, strError);
738}
739
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100740bool CConfigurableDomain::getElementSequence(const string& strConfiguration, string& strResult) const
Patrick Benavoli63499d42011-10-24 18:50:03 +0200741{
742 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100743 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strResult);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200744
745 if (!pDomainConfiguration) {
746
Patrick Benavoli63499d42011-10-24 18:50:03 +0200747 return false;
748 }
749
750 // Delegate to configuration
751 pDomainConfiguration->getElementSequence(strResult);
752
753 return true;
754}
755
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100756bool CConfigurableDomain::setApplicationRule(const string& strConfiguration, const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, string& strError)
757{
758 // Find Domain configuration
759 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
760
761 if (!pDomainConfiguration) {
762
763 return false;
764 }
765
766 // Delegate to configuration
767 return pDomainConfiguration->setApplicationRule(strApplicationRule, pSelectionCriteriaDefinition, strError);
768}
769
770bool CConfigurableDomain::clearApplicationRule(const string& strConfiguration, string& strError)
771{
772 // Find Domain configuration
773 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
774
775 if (!pDomainConfiguration) {
776
777 return false;
778 }
779
780 // Delegate to configuration
781 pDomainConfiguration->clearApplicationRule();
782
783 return true;
784}
785
786bool CConfigurableDomain::getApplicationRule(const string& strConfiguration, string& strResult) const
787{
788 // Find Domain configuration
789 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strResult);
790
791 if (!pDomainConfiguration) {
792
793 return false;
794 }
795
796 // Delegate to configuration
797 pDomainConfiguration->getApplicationRule(strResult);
798
799 return true;
800}
801
Patrick Benavoli68a91282011-08-31 11:23:23 +0200802// Last applied configuration
803string CConfigurableDomain::getLastAppliedConfigurationName() const
804{
805 if (_pLastAppliedConfiguration) {
806
807 return _pLastAppliedConfiguration->getName();
808 }
809 return "<none>";
810}
811
Frédéric Boisnard8b243f52012-09-06 18:03:20 +0200812// Pending configuration
813string CConfigurableDomain::getPendingConfigurationName() const
814{
815 const CDomainConfiguration* pPendingConfiguration = getPendingConfiguration();
816
817 if (pPendingConfiguration) {
818
819 return pPendingConfiguration->getName();
820 }
821 return "<none>";
822}
823
Patrick Benavoli68a91282011-08-31 11:23:23 +0200824// Ensure validity on whole domain from main blackboard
825void CConfigurableDomain::validate(const CParameterBlackboard* pMainBlackboard)
826{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200827
828 // Propagate
829 uint32_t uiNbConfigurations = getNbChildren();
830 uint32_t uiChild;
831
832 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
833
834 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
835
836 pDomainConfiguration->validate(pMainBlackboard);
837 }
838}
839
840// Ensure validity on areas related to configurable element
841void CConfigurableDomain::validateAreas(const CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard)
842{
Kevin Rocardace81f82012-12-11 16:19:17 +0100843 log_info("Validating domain \"" + getName() + "\" against main blackboard for configurable element \"" + pConfigurableElement->getPath() + "\"");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200844
845 // Propagate
846 uint32_t uiNbConfigurations = getNbChildren();
847 uint32_t uiChild;
848
849 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
850
851 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
852
853 pDomainConfiguration->validate(pConfigurableElement, pMainBlackboard);
854 }
855}
856
857// Attempt validation for all configurable element's areas, relying on already existing valid configuration inside domain
858void CConfigurableDomain::autoValidateAll()
859{
860 // Validate
861 ConfigurableElementListIterator it;
862
863 // Browse all configurable elements for configuration validation
864 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
865
866 const CConfigurableElement* pConfigurableElement = *it;
867
868 // Auto validate element
869 autoValidateAreas(pConfigurableElement);
870 }
871}
872
873// Attempt validation for configurable element's areas, relying on already existing valid configuration inside domain
874void CConfigurableDomain::autoValidateAreas(const CConfigurableElement* pConfigurableElement)
875{
876 // Find first valid configuration for given configurable element
877 const CDomainConfiguration* pValidDomainConfiguration = findValidDomainConfiguration(pConfigurableElement);
878
879 // No valid configuration found, give up
880 if (!pValidDomainConfiguration) {
881
882 return;
883 }
884
Patrick Benavoli68a91282011-08-31 11:23:23 +0200885 // Validate all other configurations against found one, if any
886 uint32_t uiNbConfigurations = getNbChildren();
887 uint32_t uiChild;
888
889 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
890
891 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
892
893 if (pDomainConfiguration != pValidDomainConfiguration && !pDomainConfiguration->isValid(pConfigurableElement)) {
894 // Validate
895 pDomainConfiguration->validateAgainst(pValidDomainConfiguration, pConfigurableElement);
896 }
897 }
898}
899
900// Attempt configuration validation for all configurable elements' areas, relying on already existing valid configuration inside domain
901bool CConfigurableDomain::autoValidateConfiguration(CDomainConfiguration* pDomainConfiguration)
902{
903 // Find another configuration than this one, that ought to be valid!
904 uint32_t uiNbConfigurations = getNbChildren();
905 uint32_t uiChild;
906
907 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
908
909 const CDomainConfiguration* pPotententialValidDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
910
911 if (pPotententialValidDomainConfiguration != pDomainConfiguration) {
912
913 // Validate against it
914 pDomainConfiguration->validateAgainst(pPotententialValidDomainConfiguration);
915
916 return true;
917 }
918 }
919 return false;
920}
Patrick Benavoli68a91282011-08-31 11:23:23 +0200921
Patrick Benavoli68a91282011-08-31 11:23:23 +0200922// Search for a valid configuration for given configurable element
923const CDomainConfiguration* CConfigurableDomain::findValidDomainConfiguration(const CConfigurableElement* pConfigurableElement) const
924{
925 uint32_t uiNbConfigurations = getNbChildren();
926 uint32_t uiChild;
927
928 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
929
930 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
931
932 if (pDomainConfiguration->isValid(pConfigurableElement)) {
933
934 return pDomainConfiguration;
935 }
936 }
937 return NULL;
938}
939
940// Search for an applicable configuration
941const CDomainConfiguration* CConfigurableDomain::findApplicableDomainConfiguration() const
942{
943 uint32_t uiNbConfigurations = getNbChildren();
944 uint32_t uiChild;
945
946 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
947
948 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
949
950 if (pDomainConfiguration->isApplicable()) {
951
952 return pDomainConfiguration;
953 }
954 }
955 return NULL;
956}
957
958// Gather set of configurable elements
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100959void CConfigurableDomain::gatherConfigurableElements(std::set<const CConfigurableElement*>& configurableElementSet) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200960{
961 // Insert all configurable elements
962 configurableElementSet.insert(_configurableElementList.begin(), _configurableElementList.end());
963}
964
965// Check configurable element already attached
966bool CConfigurableDomain::containsConfigurableElement(const CConfigurableElement* pConfigurableCandidateElement) const
967{
968 ConfigurableElementListIterator it;
969
970 // Browse all configurable elements for comparison
971 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
972
973 if (pConfigurableCandidateElement == *it) {
974
975 return true;
976 }
977 }
978 return false;
979}
980
981// Merge any descended configurable element to this one with this one
982void CConfigurableDomain::mergeAlreadyAssociatedDescendantConfigurableElements(CConfigurableElement* pNewConfigurableElement)
983{
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100984 std::list<CConfigurableElement*> mergedConfigurableElementList;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200985
986 ConfigurableElementListIterator it;
987
988 // Browse all configurable elements (new one not yet in the list!)
989 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
990
991 CConfigurableElement* pConfigurablePotentialDescendantElement = *it;
992
993 if (pConfigurablePotentialDescendantElement->isDescendantOf(pNewConfigurableElement)) {
994
Kevin Rocardace81f82012-12-11 16:19:17 +0100995 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 +0200996
997 // Merge configuration data
998 mergeConfigurations(pNewConfigurableElement, pConfigurablePotentialDescendantElement);
999
1000 // Keep track for removal
1001 mergedConfigurableElementList.push_back(pConfigurablePotentialDescendantElement);
1002 }
1003 }
1004
1005 // Remove all merged elements (new one not yet in the list!)
1006 for (it = mergedConfigurableElementList.begin(); it != mergedConfigurableElementList.end(); ++it) {
1007
1008 CConfigurableElement* pMergedConfigurableElement = *it;
1009
1010 // Remove merged from configurable element from internal tracking list
1011 // 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
1012 doRemoveConfigurableElement(pMergedConfigurableElement, false);
1013 }
1014}
1015
1016void CConfigurableDomain::mergeConfigurations(CConfigurableElement* pToConfigurableElement, CConfigurableElement* pFromConfigurableElement)
1017{
1018 // Propagate to domain configurations
1019 uint32_t uiNbConfigurations = getNbChildren();
1020 uint32_t uiChild;
1021
1022 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1023
1024 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1025
1026 // Do the merge.
1027 pDomainConfiguration->merge(pToConfigurableElement, pFromConfigurableElement);
1028 }
1029}
1030
1031// Configurable elements association
Frédéric Boisnard9620e442012-05-30 16:15:02 +02001032void CConfigurableDomain::doAddConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard *pMainBlackboard)
Patrick Benavoli68a91282011-08-31 11:23:23 +02001033{
1034 // Inform configurable element
1035 pConfigurableElement->addAttachedConfigurableDomain(this);
1036
Patrick Benavoli63499d42011-10-24 18:50:03 +02001037 // Create associated syncer set
1038 CSyncerSet* pSyncerSet = new CSyncerSet;
1039
1040 // Add to sync set the configurable element one
1041 pConfigurableElement->fillSyncerSet(*pSyncerSet);
1042
1043 // Store it
1044 _configurableElementToSyncerSetMap[pConfigurableElement] = pSyncerSet;
1045
1046 // Add it to global one
1047 _syncerSet += *pSyncerSet;
1048
Patrick Benavoli68a91282011-08-31 11:23:23 +02001049 // Inform configurations
1050 uint32_t uiNbConfigurations = getNbChildren();
1051 uint32_t uiChild;
1052
1053 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1054
1055 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1056
Patrick Benavoli63499d42011-10-24 18:50:03 +02001057 pDomainConfiguration->addConfigurableElement(pConfigurableElement, pSyncerSet);
Patrick Benavoli68a91282011-08-31 11:23:23 +02001058 }
Patrick Benavoli68a91282011-08-31 11:23:23 +02001059
Frédéric Boisnard9620e442012-05-30 16:15:02 +02001060 // Ensure area validity for that configurable element (if main blackboard provided)
1061 if (pMainBlackboard) {
1062
1063 // Need to validate against main blackboard
1064 validateAreas(pConfigurableElement, pMainBlackboard);
1065 }
1066
1067 // Already associated descendend configurable elements need a merge of their configuration data
Patrick Benavoli68a91282011-08-31 11:23:23 +02001068 mergeAlreadyAssociatedDescendantConfigurableElements(pConfigurableElement);
1069
1070 // Add to list
1071 _configurableElementList.push_back(pConfigurableElement);
1072}
1073
1074void CConfigurableDomain::doRemoveConfigurableElement(CConfigurableElement* pConfigurableElement, bool bRecomputeSyncSet)
1075{
1076 // Remove from list
1077 _configurableElementList.remove(pConfigurableElement);
1078
Patrick Benavoli63499d42011-10-24 18:50:03 +02001079 // Remove associated syncer set
1080 CSyncerSet* pSyncerSet = getSyncerSet(pConfigurableElement);
1081
1082 _configurableElementToSyncerSetMap.erase(pConfigurableElement);
1083
1084 delete pSyncerSet;
1085
Patrick Benavoli68a91282011-08-31 11:23:23 +02001086 // Inform configurable element
1087 pConfigurableElement->removeAttachedConfigurableDomain(this);
1088
1089 // Inform configurations
1090 uint32_t uiNbConfigurations = getNbChildren();
1091 uint32_t uiChild;
1092
1093 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1094
1095 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1096
1097 pDomainConfiguration->removeConfigurableElement(pConfigurableElement);
1098 }
1099 // Recompute our sync set if needed
1100 if (bRecomputeSyncSet) {
1101
1102 computeSyncSet();
1103 }
1104}
Patrick Benavoli63499d42011-10-24 18:50:03 +02001105
1106// Syncer set retrieval from configurable element
1107CSyncerSet* CConfigurableDomain::getSyncerSet(const CConfigurableElement* pConfigurableElement) const
1108{
1109 ConfigurableElementToSyncerSetMapIterator mapIt = _configurableElementToSyncerSetMap.find(pConfigurableElement);
1110
1111 assert(mapIt != _configurableElementToSyncerSetMap.end());
1112
1113 return mapIt->second;
1114}
Patrick Benavoli0bd50542011-11-29 11:10:27 +01001115
1116// Configuration retrieval
1117CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strConfiguration, string& strError)
1118{
1119 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(strConfiguration));
1120
1121 if (!pDomainConfiguration) {
1122
1123 strError = "Domain configuration " + strConfiguration + " not found";
1124
1125 return NULL;
1126 }
1127 return pDomainConfiguration;
1128}
1129
1130const CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strConfiguration, string& strError) const
1131{
1132 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(findChild(strConfiguration));
1133
1134 if (!pDomainConfiguration) {
1135
1136 strError = "Domain configuration " + strConfiguration + " not found";
1137
1138 return NULL;
1139 }
1140 return pDomainConfiguration;
1141}