blob: 35acb9caf737c2c1afb4108dfa501b41e99f0a67 [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
David Wagnerfd211972014-12-10 15:01:22 +010043CConfigurableDomain::CConfigurableDomain() :
44 _bSequenceAware(false), _pLastAppliedConfiguration(NULL)
45{
46}
47
Patrick Benavoli63499d42011-10-24 18:50:03 +020048CConfigurableDomain::CConfigurableDomain(const string& strName) : base(strName), _bSequenceAware(false), _pLastAppliedConfiguration(NULL)
Patrick Benavoli68a91282011-08-31 11:23:23 +020049{
50}
51
52CConfigurableDomain::~CConfigurableDomain()
53{
Patrick Benavoli63499d42011-10-24 18:50:03 +020054 // Remove all configurable elements
Patrick Benavoli68a91282011-08-31 11:23:23 +020055 ConfigurableElementListIterator it;
56
Patrick Benavoli68a91282011-08-31 11:23:23 +020057 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
58
59 CConfigurableElement* pConfigurableElement = *it;
60
61 // Remove from configurable element
62 pConfigurableElement->removeAttachedConfigurableDomain(this);
63 }
Patrick Benavoli63499d42011-10-24 18:50:03 +020064
65 // Remove all associated syncer sets
66 ConfigurableElementToSyncerSetMapIterator mapIt;
67
68 for (mapIt = _configurableElementToSyncerSetMap.begin(); mapIt != _configurableElementToSyncerSetMap.end(); ++mapIt) {
69
70 delete mapIt->second;
71 }
Patrick Benavoli68a91282011-08-31 11:23:23 +020072}
73
74string CConfigurableDomain::getKind() const
75{
76 return "ConfigurableDomain";
77}
78
79bool CConfigurableDomain::childrenAreDynamic() const
80{
81 return true;
82}
83
Patrick Benavoli0bd50542011-11-29 11:10:27 +010084// Content dumping
85void CConfigurableDomain::logValue(string& strValue, CErrorContext& errorContext) const
86{
87 (void)errorContext;
88
89 strValue = "{";
90
91 // Sequence awareness
92 strValue += "Sequence aware: ";
93 strValue += _bSequenceAware ? "yes" : "no";
94
95 // Last applied configuration
96 strValue += ", Last applied configuration: ";
97 strValue += _pLastAppliedConfiguration ? _pLastAppliedConfiguration->getName() : "<none>";
98
99 strValue += "}";
100}
101
Patrick Benavoli63499d42011-10-24 18:50:03 +0200102// Sequence awareness
103void CConfigurableDomain::setSequenceAwareness(bool bSequenceAware)
104{
105 if (_bSequenceAware != bSequenceAware) {
106
Kevin Rocardace81f82012-12-11 16:19:17 +0100107 log_info("Making domain \"%s\" sequence %s", getName().c_str(), bSequenceAware ? "aware" : "unaware");
Patrick Benavoli63499d42011-10-24 18:50:03 +0200108
109 _bSequenceAware = bSequenceAware;
110 }
111}
112
113bool CConfigurableDomain::getSequenceAwareness() const
114{
115 return _bSequenceAware;
116}
117
Patrick Benavoli68a91282011-08-31 11:23:23 +0200118// From IXmlSource
119void CConfigurableDomain::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
120{
David Wagner8cb5d882014-12-09 15:26:06 +0100121 base::toXml(xmlElement, serializingContext);
122
Patrick Benavoli63499d42011-10-24 18:50:03 +0200123 // Sequence awareness
124 xmlElement.setAttributeBoolean("SequenceAware", _bSequenceAware);
David Wagner8cb5d882014-12-09 15:26:06 +0100125}
Patrick Benavoli63499d42011-10-24 18:50:03 +0200126
David Wagner8cb5d882014-12-09 15:26:06 +0100127void CConfigurableDomain::childrenToXml(CXmlElement& xmlElement,
128 CXmlSerializingContext& serializingContext) const
129{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200130 // Configurations
131 composeDomainConfigurations(xmlElement, serializingContext);
132
133 // Configurable Elements
Patrick Benavoli63499d42011-10-24 18:50:03 +0200134 composeConfigurableElements(xmlElement);
135
136 // Settings
137 composeSettings(xmlElement, serializingContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200138}
139
140// XML composing
141void CConfigurableDomain::composeDomainConfigurations(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
142{
143 // Create Configurations element
144 CXmlElement xmlConfigurationsElement;
145
146 xmlElement.createChild(xmlConfigurationsElement, "Configurations");
147
148 // Delegate to base
David Wagner8cb5d882014-12-09 15:26:06 +0100149 base::childrenToXml(xmlConfigurationsElement, serializingContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200150}
151
Patrick Benavoli63499d42011-10-24 18:50:03 +0200152void CConfigurableDomain::composeConfigurableElements(CXmlElement& xmlElement) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200153{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200154 // Create ConfigurableElements element
155 CXmlElement xmlConfigurableElementsElement;
156
157 xmlElement.createChild(xmlConfigurableElementsElement, "ConfigurableElements");
158
159 // Serialize out all configurable elements settings
160 ConfigurableElementListIterator it;
161
162 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
163
164 const CConfigurableElement* pConfigurableElement = *it;
165
166 // Create corresponding XML child element
167 CXmlElement xmlChildConfigurableElement;
168
169 xmlConfigurableElementsElement.createChild(xmlChildConfigurableElement, "ConfigurableElement");
170
171 // Set Path attribute
172 xmlChildConfigurableElement.setAttributeString("Path", pConfigurableElement->getPath());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200173 }
174}
175
Patrick Benavoli63499d42011-10-24 18:50:03 +0200176void CConfigurableDomain::composeSettings(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200177{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200178 // Context
David Wagner29fa61f2014-12-19 11:15:02 +0100179 const CXmlDomainExportContext& xmlDomainExportContext =
180 static_cast<const CXmlDomainExportContext&>(serializingContext);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200181
David Wagner29fa61f2014-12-19 11:15:02 +0100182 if (!xmlDomainExportContext.withSettings()) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200183
184 return;
185 }
186
187 // Create Settings element
188 CXmlElement xmlSettingsElement;
189
190 xmlElement.createChild(xmlSettingsElement, "Settings");
191
192 // Serialize out all configurations settings
Patrick Benavoli68a91282011-08-31 11:23:23 +0200193 uint32_t uiNbConfigurations = getNbChildren();
194 uint32_t uiChildConfiguration;
195
196 for (uiChildConfiguration = 0; uiChildConfiguration < uiNbConfigurations; uiChildConfiguration++) {
197
198 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChildConfiguration));
199
200 // Create child xml element for that configuration
201 CXmlElement xmlConfigurationSettingsElement;
202
Patrick Benavoli63499d42011-10-24 18:50:03 +0200203 xmlSettingsElement.createChild(xmlConfigurationSettingsElement, pDomainConfiguration->getKind());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200204
205 // Set its name attribute
206 xmlConfigurationSettingsElement.setNameAttribute(pDomainConfiguration->getName());
207
Patrick Benavoli63499d42011-10-24 18:50:03 +0200208 // Serialize out configuration settings
209 pDomainConfiguration->composeSettings(xmlConfigurationSettingsElement, serializingContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200210 }
211}
212
213// From IXmlSink
214bool CConfigurableDomain::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
215{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200216 // Context
David Wagner29fa61f2014-12-19 11:15:02 +0100217 CXmlDomainImportContext& xmlDomainImportContext =
218 static_cast<CXmlDomainImportContext&>(serializingContext);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200219
220 // Sequence awareness (optional)
221 _bSequenceAware = xmlElement.hasAttribute("SequenceAware") && xmlElement.getAttributeBoolean("SequenceAware");
222
David Wagnerfd211972014-12-10 15:01:22 +0100223 setName(xmlElement.getAttributeString("Name"));
224
Patrick Benavoli68a91282011-08-31 11:23:23 +0200225 // Local parsing. Do not dig
David Wagner29fa61f2014-12-19 11:15:02 +0100226 if (!parseDomainConfigurations(xmlElement, xmlDomainImportContext) ||
227 !parseConfigurableElements(xmlElement, xmlDomainImportContext) ||
228 !parseSettings(xmlElement, xmlDomainImportContext)) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200229
230 return false;
231 }
232
233 // All provided configurations are parsed
234 // Attempt validation on areas of non provided configurations for all configurable elements if required
David Wagner29fa61f2014-12-19 11:15:02 +0100235 if (xmlDomainImportContext.autoValidationRequired()) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200236
237 autoValidateAll();
238 }
239
240 return true;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200241}
242
243// XML parsing
David Wagner29fa61f2014-12-19 11:15:02 +0100244bool CConfigurableDomain::parseDomainConfigurations(const CXmlElement& xmlElement,
245 CXmlDomainImportContext& serializingContext)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200246{
247 // We're supposedly clean
248 assert(_configurableElementList.empty());
249
250 // Get Configurations element
251 CXmlElement xmlConfigurationsElement;
252
253 xmlElement.getChildElement("Configurations", xmlConfigurationsElement);
254
255 // Parse it and create domain configuration objects
256 return base::fromXml(xmlConfigurationsElement, serializingContext);
257}
258
259// Parse configurable elements
David Wagner29fa61f2014-12-19 11:15:02 +0100260bool CConfigurableDomain::parseConfigurableElements(const CXmlElement& xmlElement,
261 CXmlDomainImportContext& serializingContext)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200262{
David Wagnerd8a53102014-12-10 14:49:23 +0100263 CSystemClass& systemClass = serializingContext.getSystemClass();
Patrick Benavoli68a91282011-08-31 11:23:23 +0200264
265 // Get ConfigurableElements element
266 CXmlElement xmlConfigurableElementsElement;
267 xmlElement.getChildElement("ConfigurableElements", xmlConfigurableElementsElement);
268
269 // Parse it and associate found configurable elements to it
270 CXmlElement::CChildIterator it(xmlConfigurableElementsElement);
271
272 CXmlElement xmlConfigurableElementElement;
273
274 while (it.next(xmlConfigurableElementElement)) {
275
276 // Locate configurable element
277 string strConfigurableElementPath = xmlConfigurableElementElement.getAttributeString("Path");
278
279 CPathNavigator pathNavigator(strConfigurableElementPath);
Patrick Benavoli065264a2011-11-20 15:46:41 +0100280 string strError;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200281
282 // Is there an element and does it match system class name?
David Wagnerd8a53102014-12-10 14:49:23 +0100283 if (!pathNavigator.navigateThrough(systemClass.getName(), strError)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200284
Patrick Benavoli065264a2011-11-20 15:46:41 +0100285 serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName() + " (" + strError + ")");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200286
287 return false;
288 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200289 // Browse system class for configurable element
David Wagnerd8a53102014-12-10 14:49:23 +0100290 CConfigurableElement* pConfigurableElement =
291 static_cast<CConfigurableElement*>(systemClass.findDescendant(pathNavigator));
Patrick Benavoli68a91282011-08-31 11:23:23 +0200292
293 if (!pConfigurableElement) {
294
295 serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName());
296
297 return false;
298 }
299 // Add found element to domain
Patrick Benavoli68a91282011-08-31 11:23:23 +0200300 if (!addConfigurableElement(pConfigurableElement, NULL, strError)) {
301
302 serializingContext.setError(strError);
303
304 return false;
305 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200306 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200307
308 return true;
309}
310
Patrick Benavoli63499d42011-10-24 18:50:03 +0200311// Parse settings
David Wagner29fa61f2014-12-19 11:15:02 +0100312bool CConfigurableDomain::parseSettings(const CXmlElement& xmlElement,
313 CXmlDomainImportContext& serializingContext)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200314{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200315 // Check we actually need to parse configuration settings
David Wagner29fa61f2014-12-19 11:15:02 +0100316 if (!serializingContext.withSettings()) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200317
318 // No parsing required
319 return true;
320 }
321
322 // Get Settings element
323 CXmlElement xmlSettingsElement;
324 if (!xmlElement.getChildElement("Settings", xmlSettingsElement)) {
325
326 // No settings, bail out successfully
327 return true;
328 }
329
330 // Parse configuration settings
331 CXmlElement::CChildIterator it(xmlSettingsElement);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200332
333 CXmlElement xmlConfigurationSettingsElement;
334
335 while (it.next(xmlConfigurationSettingsElement)) {
336 // Get domain configuration
337 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(xmlConfigurationSettingsElement.getNameAttribute()));
338
339 if (!pDomainConfiguration) {
340
David Wagner29fa61f2014-12-19 11:15:02 +0100341 serializingContext.setError("Could not find domain configuration referred to by"
342 " configurable domain \"" + getName() + "\".");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200343
344 return false;
345 }
Patrick Benavoli63499d42011-10-24 18:50:03 +0200346 // Have domain configuration parse settings for all configurable elements
David Wagner29fa61f2014-12-19 11:15:02 +0100347 if (!pDomainConfiguration->parseSettings(xmlConfigurationSettingsElement,
348 serializingContext)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200349
350 return false;
351 }
352 }
353
354 return true;
355}
Patrick Benavoli68a91282011-08-31 11:23:23 +0200356// Configurable elements association
357bool CConfigurableDomain::addConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, string& strError)
358{
359 // Already associated?
360 if (containsConfigurableElement(pConfigurableElement)) {
361
362 strError = "Configurable element " + pConfigurableElement->getPath() + " already associated to configuration domain " + getName();
363
364 return false;
365 }
366
367 // Already owned?
368 if (pConfigurableElement->belongsTo(this)) {
369
370 strError = "Configurable element " + pConfigurableElement->getPath() + " already owned by configuration domain " + getName();
371
372 return false;
373 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200374
375 // Do add
Frédéric Boisnard9620e442012-05-30 16:15:02 +0200376 doAddConfigurableElement(pConfigurableElement, pMainBlackboard);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200377
378 return true;
379}
380
381bool CConfigurableDomain::removeConfigurableElement(CConfigurableElement* pConfigurableElement, string& strError)
382{
383 // Not associated?
384 if (!containsConfigurableElement(pConfigurableElement)) {
385
386 strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName();
387
388 return false;
389 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100390 log_info("Removing configurable element \"%s\" from domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200391
392 // Do remove
393 doRemoveConfigurableElement(pConfigurableElement, true);
394
395 return true;
396}
397
Frédéric Boisnarde42dacd2013-02-25 15:56:56 +0100398/**
399* Blackboard Configuration and Base Offset retrieval.
400*
401* This method fetches the Blackboard associated to the ConfigurableElement
402* given in parameter, for a specific Configuration. The ConfigurableElement
403* must belong to the Domain. If a Blackboard is found, the base offset of
404* the ConfigurableElement is returned as well. This base offset corresponds to
405* the offset of the ancestor of the ConfigurableElement associated to the Configuration.
406*
407* @param[in] strConfiguration Name of the Configuration.
408* @param[in] pCandidateDescendantConfigurableElement Pointer to a CConfigurableElement that
409* belongs to the Domain.
410* @param[out] uiBaseOffset The base offset of the CConfigurableElement.
411* @param[out] bIsLastApplied Boolean indicating that the Configuration is
412* the last one applied of the Domain.
413* @param[out] strError Error message
414*
415* return Pointer to the Blackboard of the Configuration.
416*/
417CParameterBlackboard* CConfigurableDomain::findConfigurationBlackboard(const string& strConfiguration,
418 const CConfigurableElement* pCandidateDescendantConfigurableElement,
419 uint32_t& uiBaseOffset,
420 bool& bIsLastApplied,
421 string& strError) const
422{
423 // Find Configuration
424 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(findChild(strConfiguration));
425
426 if (!pDomainConfiguration) {
427
428 strError = "Domain configuration " + strConfiguration + " not found";
429
430 return NULL;
431 }
432
433 // Parse all configurable elements
434 ConfigurableElementListIterator it;
435
436 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
437
438 const CConfigurableElement* pAssociatedConfigurableElement = *it;
439
440 // Check if the the associated element is the configurable element or one of its ancestors
441 if ((pCandidateDescendantConfigurableElement == pAssociatedConfigurableElement) ||
442 (pCandidateDescendantConfigurableElement->isDescendantOf(pAssociatedConfigurableElement))) {
443
444 uiBaseOffset = pAssociatedConfigurableElement->getOffset();
445 bIsLastApplied = (pDomainConfiguration == _pLastAppliedConfiguration);
446
447 return pDomainConfiguration->getBlackboard(pAssociatedConfigurableElement);
448 }
449 }
450
451 strError = "Element not associated to the Domain";
452
453 return NULL;
454}
455
Patrick Benavoli68a91282011-08-31 11:23:23 +0200456// Domain splitting
457bool CConfigurableDomain::split(CConfigurableElement* pConfigurableElement, string& strError)
458{
459 // Not associated?
460 if (!containsConfigurableElement(pConfigurableElement)) {
461
462 strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName();
463
464 return false;
465 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100466 log_info("Splitting configurable element \"%s\" domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200467
468 // Create sub domain areas for all configurable element's children
469 uint32_t uiNbConfigurableElementChildren = pConfigurableElement->getNbChildren();
470
471 if (!uiNbConfigurableElementChildren) {
472
473 strError = "Configurable element " + pConfigurableElement->getPath() + " has no children to split configurable domain to";
474
475 return false;
476 }
477
478 uint32_t uiChild;
479
480 for (uiChild = 0; uiChild < uiNbConfigurableElementChildren; uiChild++) {
481
482 CConfigurableElement* pChildConfigurableElement = static_cast<CConfigurableElement*>(pConfigurableElement->getChild(uiChild));
483
484 doAddConfigurableElement(pChildConfigurableElement);
485 }
486
487 // Delegate to configurations
488 uint32_t uiNbConfigurations = getNbChildren();
489
490 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
491
492 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
493
494 pDomainConfiguration->split(pConfigurableElement);
495 }
496
497 // Remove given configurable element from this domain
498 // 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
499 doRemoveConfigurableElement(pConfigurableElement, false);
500
501 return true;
502}
503
Frédéric Boisnard8b243f52012-09-06 18:03:20 +0200504// Check if there is a pending configuration for this domain: i.e. an applicable configuration different from the last applied configuration
505const CDomainConfiguration* CConfigurableDomain::getPendingConfiguration() const
506{
507 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
508
509 if (pApplicableDomainConfiguration) {
510
511 // Check not the last one before applying
512 if (!_pLastAppliedConfiguration || (_pLastAppliedConfiguration != pApplicableDomainConfiguration)) {
513
514 return pApplicableDomainConfiguration;
515 }
516 }
517
518 return NULL;
519}
520
Patrick Benavoli68a91282011-08-31 11:23:23 +0200521// Configuration application if required
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100522void CConfigurableDomain::apply(CParameterBlackboard* pParameterBlackboard, CSyncerSet* pSyncerSet, bool bForce) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200523{
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100524 // Apply configuration only if the blackboard will
525 // be synchronized either now or by syncerSet.
526 if(!pSyncerSet ^ _bSequenceAware) {
527 // The configuration can not be syncronised
528 return;
529 }
530
Patrick Benavoli68a91282011-08-31 11:23:23 +0200531 if (bForce) {
532 // Force a configuration restore by forgetting about last applied configuration
533 _pLastAppliedConfiguration = NULL;
534 }
535 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
536
537 if (pApplicableDomainConfiguration) {
538
539 // Check not the last one before applying
540 if (!_pLastAppliedConfiguration || _pLastAppliedConfiguration != pApplicableDomainConfiguration) {
541
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100542 log_info("Applying configuration \"%s\" from domain \"%s\"",
543 pApplicableDomainConfiguration->getName().c_str(),
544 getName().c_str());
545
546 // Check if we need to synchronize during restore
547 bool bSync = !pSyncerSet && _bSequenceAware;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200548
549 // Do the restore
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100550 pApplicableDomainConfiguration->restore(pParameterBlackboard, bSync, NULL);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200551
552 // Record last applied configuration
553 _pLastAppliedConfiguration = pApplicableDomainConfiguration;
554
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100555 // Check we need to provide syncer set to caller
556 if (pSyncerSet && !_bSequenceAware) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200557
558 // Since we applied changes, add our own sync set to the given one
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100559 *pSyncerSet += _syncerSet;
Patrick Benavoli63499d42011-10-24 18:50:03 +0200560 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200561 }
562 }
563}
564
565// Return applicable configuration validity for given configurable element
566bool CConfigurableDomain::isApplicableConfigurationValid(const CConfigurableElement* pConfigurableElement) const
567{
568 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
569
570 return pApplicableDomainConfiguration && pApplicableDomainConfiguration->isValid(pConfigurableElement);
571}
572
Patrick Benavoli68a91282011-08-31 11:23:23 +0200573// In case configurable element was removed
574void CConfigurableDomain::computeSyncSet()
575{
576 // Clean sync set first
Patrick Benavoli63499d42011-10-24 18:50:03 +0200577 _syncerSet.clear();
Patrick Benavoli68a91282011-08-31 11:23:23 +0200578
Patrick Benavoli63499d42011-10-24 18:50:03 +0200579 // Add syncer sets for all associated configurable elements
580 ConfigurableElementToSyncerSetMapIterator mapIt;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200581
Patrick Benavoli63499d42011-10-24 18:50:03 +0200582 for (mapIt = _configurableElementToSyncerSetMap.begin(); mapIt != _configurableElementToSyncerSetMap.end(); ++mapIt) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200583
Patrick Benavoli63499d42011-10-24 18:50:03 +0200584 const CSyncerSet* pSyncerSet = mapIt->second;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200585
Patrick Benavoli63499d42011-10-24 18:50:03 +0200586 _syncerSet += *pSyncerSet;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200587 }
588}
589
590// Configuration Management
591bool CConfigurableDomain::createConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError)
592{
593 // Already exists?
594 if (findChild(strName)) {
595
596 strError = "Already existing configuration";
597
598 return false;
599 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100600 log_info("Creating domain configuration \"%s\" into domain \"%s\"", strName.c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200601
602 // Creation
603 CDomainConfiguration* pDomainConfiguration = new CDomainConfiguration(strName);
604
605 // Configurable elements association
606 ConfigurableElementListIterator it;
607
608 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
609
Patrick Benavoli63499d42011-10-24 18:50:03 +0200610 const CConfigurableElement* pConfigurableElement = *it;;
611
612 // Retrieve associated syncer set
613 CSyncerSet* pSyncerSet = getSyncerSet(pConfigurableElement);
614
615 // Associate to configuration
616 pDomainConfiguration->addConfigurableElement(pConfigurableElement, pSyncerSet);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200617 }
618
619 // Hierarchy
620 addChild(pDomainConfiguration);
621
622 // Ensure validity of fresh new domain configuration
623 // Attempt auto validation, so that the user gets his/her own settings by defaults
624 if (!autoValidateConfiguration(pDomainConfiguration)) {
625
626 // No valid configuration found to copy in from, validate againt main blackboard (will concerned remaining invalid parts)
627 pDomainConfiguration->validate(pMainBlackboard);
628 }
629
630 return true;
631}
632
633bool CConfigurableDomain::deleteConfiguration(const string& strName, string& strError)
634{
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100635 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200636
637 if (!pDomainConfiguration) {
638
Patrick Benavoli68a91282011-08-31 11:23:23 +0200639 return false;
640 }
641
Kevin Rocardace81f82012-12-11 16:19:17 +0100642 log_info("Deleting configuration \"%s\" from domain \"%s\"", strName.c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200643
644 // Was the last applied?
645 if (pDomainConfiguration == _pLastAppliedConfiguration) {
646
647 // Forget about it
648 _pLastAppliedConfiguration = NULL;
649 }
650
651 // Hierarchy
652 removeChild(pDomainConfiguration);
653
654 // Destroy
655 delete pDomainConfiguration;
656
657 return true;
658}
659
660void CConfigurableDomain::listAssociatedToElements(string& strResult) const
661{
662 strResult = "\n";
663
664 ConfigurableElementListIterator it;
665
666 // Browse all configurable elements
667 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
668
669 const CConfigurableElement* pConfigurableElement = *it;
670
671 strResult += pConfigurableElement->getPath() + "\n";
672 }
673}
674
675bool CConfigurableDomain::renameConfiguration(const string& strName, const string& strNewName, string& strError)
676{
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100677 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200678
679 if (!pDomainConfiguration) {
680
Patrick Benavoli68a91282011-08-31 11:23:23 +0200681 return false;
682 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100683 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 +0200684
685 // Rename
686 return pDomainConfiguration->rename(strNewName, strError);
687}
688
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100689bool CConfigurableDomain::restoreConfiguration(const string& strName, CParameterBlackboard* pMainBlackboard, bool bAutoSync, std::list<string>& lstrError) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200690{
Kevin Rocardace81f82012-12-11 16:19:17 +0100691 string strError;
692
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100693 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200694
695 if (!pDomainConfiguration) {
696
Kevin Rocardace81f82012-12-11 16:19:17 +0100697 lstrError.push_back(strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200698 return false;
699 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100700 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 +0200701
702 // Delegate
Kevin Rocardace81f82012-12-11 16:19:17 +0100703 bool bSuccess = pDomainConfiguration->restore(pMainBlackboard, bAutoSync && _bSequenceAware, &lstrError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200704
705 // Record last applied configuration
706 _pLastAppliedConfiguration = pDomainConfiguration;
707
708 // Synchronize
Kevin Rocardace81f82012-12-11 16:19:17 +0100709 if (bAutoSync && !_bSequenceAware) {
710
711 bSuccess &= _syncerSet.sync(*pMainBlackboard, false, &lstrError);
712 }
713 return bSuccess;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200714}
715
716bool CConfigurableDomain::saveConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError)
717{
718 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100719 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200720
721 if (!pDomainConfiguration) {
722
Patrick Benavoli68a91282011-08-31 11:23:23 +0200723 return false;
724 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100725 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 +0200726
727 // Delegate
728 pDomainConfiguration->save(pMainBlackboard);
729
730 return true;
731}
732
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100733bool CConfigurableDomain::setElementSequence(const string& strConfiguration, const std::vector<string>& astrNewElementSequence, string& strError)
Patrick Benavoli63499d42011-10-24 18:50:03 +0200734{
735 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100736 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200737
738 if (!pDomainConfiguration) {
739
Patrick Benavoli63499d42011-10-24 18:50:03 +0200740 return false;
741 }
742
743 // Delegate to configuration
744 return pDomainConfiguration->setElementSequence(astrNewElementSequence, strError);
745}
746
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100747bool CConfigurableDomain::getElementSequence(const string& strConfiguration, string& strResult) const
Patrick Benavoli63499d42011-10-24 18:50:03 +0200748{
749 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100750 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strResult);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200751
752 if (!pDomainConfiguration) {
753
Patrick Benavoli63499d42011-10-24 18:50:03 +0200754 return false;
755 }
756
757 // Delegate to configuration
758 pDomainConfiguration->getElementSequence(strResult);
759
760 return true;
761}
762
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100763bool CConfigurableDomain::setApplicationRule(const string& strConfiguration, const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, string& strError)
764{
765 // Find Domain configuration
766 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
767
768 if (!pDomainConfiguration) {
769
770 return false;
771 }
772
773 // Delegate to configuration
774 return pDomainConfiguration->setApplicationRule(strApplicationRule, pSelectionCriteriaDefinition, strError);
775}
776
777bool CConfigurableDomain::clearApplicationRule(const string& strConfiguration, string& strError)
778{
779 // Find Domain configuration
780 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
781
782 if (!pDomainConfiguration) {
783
784 return false;
785 }
786
787 // Delegate to configuration
788 pDomainConfiguration->clearApplicationRule();
789
790 return true;
791}
792
793bool CConfigurableDomain::getApplicationRule(const string& strConfiguration, string& strResult) const
794{
795 // Find Domain configuration
796 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strResult);
797
798 if (!pDomainConfiguration) {
799
800 return false;
801 }
802
803 // Delegate to configuration
804 pDomainConfiguration->getApplicationRule(strResult);
805
806 return true;
807}
808
Patrick Benavoli68a91282011-08-31 11:23:23 +0200809// Last applied configuration
810string CConfigurableDomain::getLastAppliedConfigurationName() const
811{
812 if (_pLastAppliedConfiguration) {
813
814 return _pLastAppliedConfiguration->getName();
815 }
816 return "<none>";
817}
818
Frédéric Boisnard8b243f52012-09-06 18:03:20 +0200819// Pending configuration
820string CConfigurableDomain::getPendingConfigurationName() const
821{
822 const CDomainConfiguration* pPendingConfiguration = getPendingConfiguration();
823
824 if (pPendingConfiguration) {
825
826 return pPendingConfiguration->getName();
827 }
828 return "<none>";
829}
830
Patrick Benavoli68a91282011-08-31 11:23:23 +0200831// Ensure validity on whole domain from main blackboard
832void CConfigurableDomain::validate(const CParameterBlackboard* pMainBlackboard)
833{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200834
835 // Propagate
836 uint32_t uiNbConfigurations = getNbChildren();
837 uint32_t uiChild;
838
839 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
840
841 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
842
843 pDomainConfiguration->validate(pMainBlackboard);
844 }
845}
846
847// Ensure validity on areas related to configurable element
848void CConfigurableDomain::validateAreas(const CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard)
849{
Kevin Rocardace81f82012-12-11 16:19:17 +0100850 log_info("Validating domain \"" + getName() + "\" against main blackboard for configurable element \"" + pConfigurableElement->getPath() + "\"");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200851
852 // Propagate
853 uint32_t uiNbConfigurations = getNbChildren();
854 uint32_t uiChild;
855
856 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
857
858 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
859
860 pDomainConfiguration->validate(pConfigurableElement, pMainBlackboard);
861 }
862}
863
864// Attempt validation for all configurable element's areas, relying on already existing valid configuration inside domain
865void CConfigurableDomain::autoValidateAll()
866{
867 // Validate
868 ConfigurableElementListIterator it;
869
870 // Browse all configurable elements for configuration validation
871 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
872
873 const CConfigurableElement* pConfigurableElement = *it;
874
875 // Auto validate element
876 autoValidateAreas(pConfigurableElement);
877 }
878}
879
880// Attempt validation for configurable element's areas, relying on already existing valid configuration inside domain
881void CConfigurableDomain::autoValidateAreas(const CConfigurableElement* pConfigurableElement)
882{
883 // Find first valid configuration for given configurable element
884 const CDomainConfiguration* pValidDomainConfiguration = findValidDomainConfiguration(pConfigurableElement);
885
886 // No valid configuration found, give up
887 if (!pValidDomainConfiguration) {
888
889 return;
890 }
891
Patrick Benavoli68a91282011-08-31 11:23:23 +0200892 // Validate all other configurations against found one, if any
893 uint32_t uiNbConfigurations = getNbChildren();
894 uint32_t uiChild;
895
896 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
897
898 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
899
900 if (pDomainConfiguration != pValidDomainConfiguration && !pDomainConfiguration->isValid(pConfigurableElement)) {
901 // Validate
902 pDomainConfiguration->validateAgainst(pValidDomainConfiguration, pConfigurableElement);
903 }
904 }
905}
906
907// Attempt configuration validation for all configurable elements' areas, relying on already existing valid configuration inside domain
908bool CConfigurableDomain::autoValidateConfiguration(CDomainConfiguration* pDomainConfiguration)
909{
910 // Find another configuration than this one, that ought to be valid!
911 uint32_t uiNbConfigurations = getNbChildren();
912 uint32_t uiChild;
913
914 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
915
916 const CDomainConfiguration* pPotententialValidDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
917
918 if (pPotententialValidDomainConfiguration != pDomainConfiguration) {
919
920 // Validate against it
921 pDomainConfiguration->validateAgainst(pPotententialValidDomainConfiguration);
922
923 return true;
924 }
925 }
926 return false;
927}
Patrick Benavoli68a91282011-08-31 11:23:23 +0200928
Patrick Benavoli68a91282011-08-31 11:23:23 +0200929// Search for a valid configuration for given configurable element
930const CDomainConfiguration* CConfigurableDomain::findValidDomainConfiguration(const CConfigurableElement* pConfigurableElement) const
931{
932 uint32_t uiNbConfigurations = getNbChildren();
933 uint32_t uiChild;
934
935 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
936
937 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
938
939 if (pDomainConfiguration->isValid(pConfigurableElement)) {
940
941 return pDomainConfiguration;
942 }
943 }
944 return NULL;
945}
946
947// Search for an applicable configuration
948const CDomainConfiguration* CConfigurableDomain::findApplicableDomainConfiguration() const
949{
950 uint32_t uiNbConfigurations = getNbChildren();
951 uint32_t uiChild;
952
953 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
954
955 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
956
957 if (pDomainConfiguration->isApplicable()) {
958
959 return pDomainConfiguration;
960 }
961 }
962 return NULL;
963}
964
965// Gather set of configurable elements
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100966void CConfigurableDomain::gatherConfigurableElements(std::set<const CConfigurableElement*>& configurableElementSet) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200967{
968 // Insert all configurable elements
969 configurableElementSet.insert(_configurableElementList.begin(), _configurableElementList.end());
970}
971
972// Check configurable element already attached
973bool CConfigurableDomain::containsConfigurableElement(const CConfigurableElement* pConfigurableCandidateElement) const
974{
975 ConfigurableElementListIterator it;
976
977 // Browse all configurable elements for comparison
978 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
979
980 if (pConfigurableCandidateElement == *it) {
981
982 return true;
983 }
984 }
985 return false;
986}
987
988// Merge any descended configurable element to this one with this one
989void CConfigurableDomain::mergeAlreadyAssociatedDescendantConfigurableElements(CConfigurableElement* pNewConfigurableElement)
990{
Sebastien Gonzalved9526492014-02-20 22:28:03 +0100991 std::list<CConfigurableElement*> mergedConfigurableElementList;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200992
993 ConfigurableElementListIterator it;
994
995 // Browse all configurable elements (new one not yet in the list!)
996 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
997
998 CConfigurableElement* pConfigurablePotentialDescendantElement = *it;
999
1000 if (pConfigurablePotentialDescendantElement->isDescendantOf(pNewConfigurableElement)) {
1001
Kevin Rocardace81f82012-12-11 16:19:17 +01001002 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 +02001003
1004 // Merge configuration data
1005 mergeConfigurations(pNewConfigurableElement, pConfigurablePotentialDescendantElement);
1006
1007 // Keep track for removal
1008 mergedConfigurableElementList.push_back(pConfigurablePotentialDescendantElement);
1009 }
1010 }
1011
1012 // Remove all merged elements (new one not yet in the list!)
1013 for (it = mergedConfigurableElementList.begin(); it != mergedConfigurableElementList.end(); ++it) {
1014
1015 CConfigurableElement* pMergedConfigurableElement = *it;
1016
1017 // Remove merged from configurable element from internal tracking list
1018 // 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
1019 doRemoveConfigurableElement(pMergedConfigurableElement, false);
1020 }
1021}
1022
1023void CConfigurableDomain::mergeConfigurations(CConfigurableElement* pToConfigurableElement, CConfigurableElement* pFromConfigurableElement)
1024{
1025 // Propagate to domain configurations
1026 uint32_t uiNbConfigurations = getNbChildren();
1027 uint32_t uiChild;
1028
1029 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1030
1031 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1032
1033 // Do the merge.
1034 pDomainConfiguration->merge(pToConfigurableElement, pFromConfigurableElement);
1035 }
1036}
1037
1038// Configurable elements association
Frédéric Boisnard9620e442012-05-30 16:15:02 +02001039void CConfigurableDomain::doAddConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard *pMainBlackboard)
Patrick Benavoli68a91282011-08-31 11:23:23 +02001040{
1041 // Inform configurable element
1042 pConfigurableElement->addAttachedConfigurableDomain(this);
1043
Patrick Benavoli63499d42011-10-24 18:50:03 +02001044 // Create associated syncer set
1045 CSyncerSet* pSyncerSet = new CSyncerSet;
1046
1047 // Add to sync set the configurable element one
1048 pConfigurableElement->fillSyncerSet(*pSyncerSet);
1049
1050 // Store it
1051 _configurableElementToSyncerSetMap[pConfigurableElement] = pSyncerSet;
1052
1053 // Add it to global one
1054 _syncerSet += *pSyncerSet;
1055
Patrick Benavoli68a91282011-08-31 11:23:23 +02001056 // Inform configurations
1057 uint32_t uiNbConfigurations = getNbChildren();
1058 uint32_t uiChild;
1059
1060 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1061
1062 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1063
Patrick Benavoli63499d42011-10-24 18:50:03 +02001064 pDomainConfiguration->addConfigurableElement(pConfigurableElement, pSyncerSet);
Patrick Benavoli68a91282011-08-31 11:23:23 +02001065 }
Patrick Benavoli68a91282011-08-31 11:23:23 +02001066
Frédéric Boisnard9620e442012-05-30 16:15:02 +02001067 // Ensure area validity for that configurable element (if main blackboard provided)
1068 if (pMainBlackboard) {
1069
1070 // Need to validate against main blackboard
1071 validateAreas(pConfigurableElement, pMainBlackboard);
1072 }
1073
1074 // Already associated descendend configurable elements need a merge of their configuration data
Patrick Benavoli68a91282011-08-31 11:23:23 +02001075 mergeAlreadyAssociatedDescendantConfigurableElements(pConfigurableElement);
1076
1077 // Add to list
1078 _configurableElementList.push_back(pConfigurableElement);
1079}
1080
1081void CConfigurableDomain::doRemoveConfigurableElement(CConfigurableElement* pConfigurableElement, bool bRecomputeSyncSet)
1082{
1083 // Remove from list
1084 _configurableElementList.remove(pConfigurableElement);
1085
Patrick Benavoli63499d42011-10-24 18:50:03 +02001086 // Remove associated syncer set
1087 CSyncerSet* pSyncerSet = getSyncerSet(pConfigurableElement);
1088
1089 _configurableElementToSyncerSetMap.erase(pConfigurableElement);
1090
1091 delete pSyncerSet;
1092
Patrick Benavoli68a91282011-08-31 11:23:23 +02001093 // Inform configurable element
1094 pConfigurableElement->removeAttachedConfigurableDomain(this);
1095
1096 // Inform configurations
1097 uint32_t uiNbConfigurations = getNbChildren();
1098 uint32_t uiChild;
1099
1100 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
1101
1102 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
1103
1104 pDomainConfiguration->removeConfigurableElement(pConfigurableElement);
1105 }
1106 // Recompute our sync set if needed
1107 if (bRecomputeSyncSet) {
1108
1109 computeSyncSet();
1110 }
1111}
Patrick Benavoli63499d42011-10-24 18:50:03 +02001112
1113// Syncer set retrieval from configurable element
1114CSyncerSet* CConfigurableDomain::getSyncerSet(const CConfigurableElement* pConfigurableElement) const
1115{
1116 ConfigurableElementToSyncerSetMapIterator mapIt = _configurableElementToSyncerSetMap.find(pConfigurableElement);
1117
1118 assert(mapIt != _configurableElementToSyncerSetMap.end());
1119
1120 return mapIt->second;
1121}
Patrick Benavoli0bd50542011-11-29 11:10:27 +01001122
1123// Configuration retrieval
1124CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strConfiguration, string& strError)
1125{
1126 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(strConfiguration));
1127
1128 if (!pDomainConfiguration) {
1129
1130 strError = "Domain configuration " + strConfiguration + " not found";
1131
1132 return NULL;
1133 }
1134 return pDomainConfiguration;
1135}
1136
1137const CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strConfiguration, string& strError) const
1138{
1139 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(findChild(strConfiguration));
1140
1141 if (!pDomainConfiguration) {
1142
1143 strError = "Domain configuration " + strConfiguration + " not found";
1144
1145 return NULL;
1146 }
1147 return pDomainConfiguration;
1148}