blob: 6d1c19ce67287d71371a66ba28f562d2319d2b72 [file] [log] [blame]
Kevin Rocard93250d12012-07-19 17:48:30 +02001/*
Patrick Benavoli68a91282011-08-31 11:23:23 +02002 * INTEL CONFIDENTIAL
3 * Copyright © 2011 Intel
4 * Corporation All Rights Reserved.
5 *
6 * The source code contained or described herein and all documents related to
7 * the source code ("Material") are owned by Intel Corporation or its suppliers
8 * or licensors. Title to the Material remains with Intel Corporation or its
9 * suppliers and licensors. The Material contains trade secrets and proprietary
10 * and confidential information of Intel or its suppliers and licensors. The
11 * Material is protected by worldwide copyright and trade secret laws and
12 * treaty provisions. No part of the Material may be used, copied, reproduced,
13 * modified, published, uploaded, posted, transmitted, distributed, or
14 * disclosed in any way without Intel’s prior express written permission.
15 *
16 * No license under any patent, copyright, trade secret or other intellectual
17 * property right is granted to or conferred upon you by disclosure or delivery
18 * of the Materials, either expressly, by implication, inducement, estoppel or
19 * otherwise. Any license under such intellectual property rights must be
20 * express and approved by Intel in writing.
21 *
Patrick Benavoli68a91282011-08-31 11:23:23 +020022 * CREATED: 2011-06-01
23 * UPDATED: 2011-07-27
Patrick Benavoli68a91282011-08-31 11:23:23 +020024 */
25#include "ConfigurableDomain.h"
26#include "DomainConfiguration.h"
27#include "ConfigurableElement.h"
28#include "ConfigurationAccessContext.h"
Patrick Benavoli68a91282011-08-31 11:23:23 +020029#include "XmlDomainSerializingContext.h"
30#include <assert.h>
31
32#define base CBinarySerializableElement
33
Patrick Benavoli63499d42011-10-24 18:50:03 +020034CConfigurableDomain::CConfigurableDomain(const string& strName) : base(strName), _bSequenceAware(false), _pLastAppliedConfiguration(NULL)
Patrick Benavoli68a91282011-08-31 11:23:23 +020035{
36}
37
38CConfigurableDomain::~CConfigurableDomain()
39{
Patrick Benavoli63499d42011-10-24 18:50:03 +020040 // Remove all configurable elements
Patrick Benavoli68a91282011-08-31 11:23:23 +020041 ConfigurableElementListIterator it;
42
Patrick Benavoli68a91282011-08-31 11:23:23 +020043 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
44
45 CConfigurableElement* pConfigurableElement = *it;
46
47 // Remove from configurable element
48 pConfigurableElement->removeAttachedConfigurableDomain(this);
49 }
Patrick Benavoli63499d42011-10-24 18:50:03 +020050
51 // Remove all associated syncer sets
52 ConfigurableElementToSyncerSetMapIterator mapIt;
53
54 for (mapIt = _configurableElementToSyncerSetMap.begin(); mapIt != _configurableElementToSyncerSetMap.end(); ++mapIt) {
55
56 delete mapIt->second;
57 }
Patrick Benavoli68a91282011-08-31 11:23:23 +020058}
59
60string CConfigurableDomain::getKind() const
61{
62 return "ConfigurableDomain";
63}
64
65bool CConfigurableDomain::childrenAreDynamic() const
66{
67 return true;
68}
69
Patrick Benavoli0bd50542011-11-29 11:10:27 +010070// Content dumping
71void CConfigurableDomain::logValue(string& strValue, CErrorContext& errorContext) const
72{
73 (void)errorContext;
74
75 strValue = "{";
76
77 // Sequence awareness
78 strValue += "Sequence aware: ";
79 strValue += _bSequenceAware ? "yes" : "no";
80
81 // Last applied configuration
82 strValue += ", Last applied configuration: ";
83 strValue += _pLastAppliedConfiguration ? _pLastAppliedConfiguration->getName() : "<none>";
84
85 strValue += "}";
86}
87
Patrick Benavoli63499d42011-10-24 18:50:03 +020088// Sequence awareness
89void CConfigurableDomain::setSequenceAwareness(bool bSequenceAware)
90{
91 if (_bSequenceAware != bSequenceAware) {
92
Kevin Rocardace81f82012-12-11 16:19:17 +010093 log_info("Making domain \"%s\" sequence %s", getName().c_str(), bSequenceAware ? "aware" : "unaware");
Patrick Benavoli63499d42011-10-24 18:50:03 +020094
95 _bSequenceAware = bSequenceAware;
96 }
97}
98
99bool CConfigurableDomain::getSequenceAwareness() const
100{
101 return _bSequenceAware;
102}
103
Patrick Benavoli68a91282011-08-31 11:23:23 +0200104// From IXmlSource
105void CConfigurableDomain::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
106{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200107 // Sequence awareness
108 xmlElement.setAttributeBoolean("SequenceAware", _bSequenceAware);
109
Patrick Benavoli68a91282011-08-31 11:23:23 +0200110 // Configurations
111 composeDomainConfigurations(xmlElement, serializingContext);
112
113 // Configurable Elements
Patrick Benavoli63499d42011-10-24 18:50:03 +0200114 composeConfigurableElements(xmlElement);
115
116 // Settings
117 composeSettings(xmlElement, serializingContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200118}
119
120// XML composing
121void CConfigurableDomain::composeDomainConfigurations(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
122{
123 // Create Configurations element
124 CXmlElement xmlConfigurationsElement;
125
126 xmlElement.createChild(xmlConfigurationsElement, "Configurations");
127
128 // Delegate to base
129 base::toXml(xmlConfigurationsElement, serializingContext);
130}
131
Patrick Benavoli63499d42011-10-24 18:50:03 +0200132void CConfigurableDomain::composeConfigurableElements(CXmlElement& xmlElement) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200133{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200134 // Create ConfigurableElements element
135 CXmlElement xmlConfigurableElementsElement;
136
137 xmlElement.createChild(xmlConfigurableElementsElement, "ConfigurableElements");
138
139 // Serialize out all configurable elements settings
140 ConfigurableElementListIterator it;
141
142 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
143
144 const CConfigurableElement* pConfigurableElement = *it;
145
146 // Create corresponding XML child element
147 CXmlElement xmlChildConfigurableElement;
148
149 xmlConfigurableElementsElement.createChild(xmlChildConfigurableElement, "ConfigurableElement");
150
151 // Set Path attribute
152 xmlChildConfigurableElement.setAttributeString("Path", pConfigurableElement->getPath());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200153 }
154}
155
Patrick Benavoli63499d42011-10-24 18:50:03 +0200156void CConfigurableDomain::composeSettings(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200157{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200158 // Context
159 const CXmlDomainSerializingContext& xmlDomainSerializingContext = static_cast<const CXmlDomainSerializingContext&>(serializingContext);
160
161 if (!xmlDomainSerializingContext.withSettings()) {
162
163 return;
164 }
165
166 // Create Settings element
167 CXmlElement xmlSettingsElement;
168
169 xmlElement.createChild(xmlSettingsElement, "Settings");
170
171 // Serialize out all configurations settings
Patrick Benavoli68a91282011-08-31 11:23:23 +0200172 uint32_t uiNbConfigurations = getNbChildren();
173 uint32_t uiChildConfiguration;
174
175 for (uiChildConfiguration = 0; uiChildConfiguration < uiNbConfigurations; uiChildConfiguration++) {
176
177 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChildConfiguration));
178
179 // Create child xml element for that configuration
180 CXmlElement xmlConfigurationSettingsElement;
181
Patrick Benavoli63499d42011-10-24 18:50:03 +0200182 xmlSettingsElement.createChild(xmlConfigurationSettingsElement, pDomainConfiguration->getKind());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200183
184 // Set its name attribute
185 xmlConfigurationSettingsElement.setNameAttribute(pDomainConfiguration->getName());
186
Patrick Benavoli63499d42011-10-24 18:50:03 +0200187 // Serialize out configuration settings
188 pDomainConfiguration->composeSettings(xmlConfigurationSettingsElement, serializingContext);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200189 }
190}
191
192// From IXmlSink
193bool CConfigurableDomain::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
194{
Patrick Benavoli63499d42011-10-24 18:50:03 +0200195 // Context
196 CXmlDomainSerializingContext& xmlDomainSerializingContext = static_cast<CXmlDomainSerializingContext&>(serializingContext);
197
198 // Sequence awareness (optional)
199 _bSequenceAware = xmlElement.hasAttribute("SequenceAware") && xmlElement.getAttributeBoolean("SequenceAware");
200
Patrick Benavoli68a91282011-08-31 11:23:23 +0200201 // Local parsing. Do not dig
Patrick Benavoli63499d42011-10-24 18:50:03 +0200202 if (!parseDomainConfigurations(xmlElement, serializingContext) || !parseConfigurableElements(xmlElement, serializingContext) || !parseSettings(xmlElement, serializingContext)) {
203
204 return false;
205 }
206
207 // All provided configurations are parsed
208 // Attempt validation on areas of non provided configurations for all configurable elements if required
209 if (xmlDomainSerializingContext.autoValidationRequired()) {
210
211 autoValidateAll();
212 }
213
214 return true;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200215}
216
217// XML parsing
218bool CConfigurableDomain::parseDomainConfigurations(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
219{
220 // We're supposedly clean
221 assert(_configurableElementList.empty());
222
223 // Get Configurations element
224 CXmlElement xmlConfigurationsElement;
225
226 xmlElement.getChildElement("Configurations", xmlConfigurationsElement);
227
228 // Parse it and create domain configuration objects
229 return base::fromXml(xmlConfigurationsElement, serializingContext);
230}
231
232// Parse configurable elements
233bool CConfigurableDomain::parseConfigurableElements(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
234{
Patrick Benavoli68a91282011-08-31 11:23:23 +0200235 // Get System Class Element
236 CElement* pRootElement = getRoot();
237
238 CElement* pSystemClassElement = pRootElement->findChildOfKind("SystemClass");
239
240 assert(pSystemClassElement);
241
242 // Get ConfigurableElements element
243 CXmlElement xmlConfigurableElementsElement;
244 xmlElement.getChildElement("ConfigurableElements", xmlConfigurableElementsElement);
245
246 // Parse it and associate found configurable elements to it
247 CXmlElement::CChildIterator it(xmlConfigurableElementsElement);
248
249 CXmlElement xmlConfigurableElementElement;
250
251 while (it.next(xmlConfigurableElementElement)) {
252
253 // Locate configurable element
254 string strConfigurableElementPath = xmlConfigurableElementElement.getAttributeString("Path");
255
256 CPathNavigator pathNavigator(strConfigurableElementPath);
Patrick Benavoli065264a2011-11-20 15:46:41 +0100257 string strError;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200258
259 // Is there an element and does it match system class name?
Patrick Benavoli065264a2011-11-20 15:46:41 +0100260 if (!pathNavigator.navigateThrough(pSystemClassElement->getName(), strError)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200261
Patrick Benavoli065264a2011-11-20 15:46:41 +0100262 serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName() + " (" + strError + ")");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200263
264 return false;
265 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200266 // Browse system class for configurable element
267 CConfigurableElement* pConfigurableElement = static_cast<CConfigurableElement*>(pSystemClassElement->findDescendant(pathNavigator));
268
269 if (!pConfigurableElement) {
270
271 serializingContext.setError("Could not find configurable element of path " + strConfigurableElementPath + " from ConfigurableDomain description " + getName());
272
273 return false;
274 }
275 // Add found element to domain
Patrick Benavoli68a91282011-08-31 11:23:23 +0200276 if (!addConfigurableElement(pConfigurableElement, NULL, strError)) {
277
278 serializingContext.setError(strError);
279
280 return false;
281 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200282 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200283
284 return true;
285}
286
Patrick Benavoli63499d42011-10-24 18:50:03 +0200287// Parse settings
288bool CConfigurableDomain::parseSettings(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200289{
290 // Context
291 CXmlDomainSerializingContext& xmlDomainSerializingContext = static_cast<CXmlDomainSerializingContext&>(serializingContext);
292
Patrick Benavoli63499d42011-10-24 18:50:03 +0200293 // Check we actually need to parse configuration settings
294 if (!xmlDomainSerializingContext.withSettings()) {
295
296 // No parsing required
297 return true;
298 }
299
300 // Get Settings element
301 CXmlElement xmlSettingsElement;
302 if (!xmlElement.getChildElement("Settings", xmlSettingsElement)) {
303
304 // No settings, bail out successfully
305 return true;
306 }
307
308 // Parse configuration settings
309 CXmlElement::CChildIterator it(xmlSettingsElement);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200310
311 CXmlElement xmlConfigurationSettingsElement;
312
313 while (it.next(xmlConfigurationSettingsElement)) {
314 // Get domain configuration
315 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(xmlConfigurationSettingsElement.getNameAttribute()));
316
317 if (!pDomainConfiguration) {
318
Patrick Benavoli63499d42011-10-24 18:50:03 +0200319 xmlDomainSerializingContext.setError("Could not find domain configuration referred to by configurable domain " + getName());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200320
321 return false;
322 }
Patrick Benavoli63499d42011-10-24 18:50:03 +0200323 // Have domain configuration parse settings for all configurable elements
324 if (!pDomainConfiguration->parseSettings(xmlConfigurationSettingsElement, xmlDomainSerializingContext)) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200325
326 return false;
327 }
328 }
329
330 return true;
331}
Patrick Benavoli68a91282011-08-31 11:23:23 +0200332// Configurable elements association
333bool CConfigurableDomain::addConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, string& strError)
334{
335 // Already associated?
336 if (containsConfigurableElement(pConfigurableElement)) {
337
338 strError = "Configurable element " + pConfigurableElement->getPath() + " already associated to configuration domain " + getName();
339
340 return false;
341 }
342
343 // Already owned?
344 if (pConfigurableElement->belongsTo(this)) {
345
346 strError = "Configurable element " + pConfigurableElement->getPath() + " already owned by configuration domain " + getName();
347
348 return false;
349 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100350 log_info("Adding configurable element \"%s\" into domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200351
352 // Do add
Frédéric Boisnard9620e442012-05-30 16:15:02 +0200353 doAddConfigurableElement(pConfigurableElement, pMainBlackboard);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200354
355 return true;
356}
357
358bool CConfigurableDomain::removeConfigurableElement(CConfigurableElement* pConfigurableElement, string& strError)
359{
360 // Not associated?
361 if (!containsConfigurableElement(pConfigurableElement)) {
362
363 strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName();
364
365 return false;
366 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100367 log_info("Removing configurable element \"%s\" from domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200368
369 // Do remove
370 doRemoveConfigurableElement(pConfigurableElement, true);
371
372 return true;
373}
374
375// Domain splitting
376bool CConfigurableDomain::split(CConfigurableElement* pConfigurableElement, string& strError)
377{
378 // Not associated?
379 if (!containsConfigurableElement(pConfigurableElement)) {
380
381 strError = "Configurable element " + pConfigurableElement->getPath() + " not associated to configuration domain " + getName();
382
383 return false;
384 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100385 log_info("Splitting configurable element \"%s\" domain \"%s\"", pConfigurableElement->getPath().c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200386
387 // Create sub domain areas for all configurable element's children
388 uint32_t uiNbConfigurableElementChildren = pConfigurableElement->getNbChildren();
389
390 if (!uiNbConfigurableElementChildren) {
391
392 strError = "Configurable element " + pConfigurableElement->getPath() + " has no children to split configurable domain to";
393
394 return false;
395 }
396
397 uint32_t uiChild;
398
399 for (uiChild = 0; uiChild < uiNbConfigurableElementChildren; uiChild++) {
400
401 CConfigurableElement* pChildConfigurableElement = static_cast<CConfigurableElement*>(pConfigurableElement->getChild(uiChild));
402
403 doAddConfigurableElement(pChildConfigurableElement);
404 }
405
406 // Delegate to configurations
407 uint32_t uiNbConfigurations = getNbChildren();
408
409 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
410
411 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
412
413 pDomainConfiguration->split(pConfigurableElement);
414 }
415
416 // Remove given configurable element from this domain
417 // 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
418 doRemoveConfigurableElement(pConfigurableElement, false);
419
420 return true;
421}
422
Frédéric Boisnard8b243f52012-09-06 18:03:20 +0200423// Check if there is a pending configuration for this domain: i.e. an applicable configuration different from the last applied configuration
424const CDomainConfiguration* CConfigurableDomain::getPendingConfiguration() const
425{
426 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
427
428 if (pApplicableDomainConfiguration) {
429
430 // Check not the last one before applying
431 if (!_pLastAppliedConfiguration || (_pLastAppliedConfiguration != pApplicableDomainConfiguration)) {
432
433 return pApplicableDomainConfiguration;
434 }
435 }
436
437 return NULL;
438}
439
Patrick Benavoli68a91282011-08-31 11:23:23 +0200440// Configuration application if required
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100441void CConfigurableDomain::apply(CParameterBlackboard* pParameterBlackboard, CSyncerSet* pSyncerSet, bool bForce) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200442{
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100443 // Apply configuration only if the blackboard will
444 // be synchronized either now or by syncerSet.
445 if(!pSyncerSet ^ _bSequenceAware) {
446 // The configuration can not be syncronised
447 return;
448 }
449
Patrick Benavoli68a91282011-08-31 11:23:23 +0200450 if (bForce) {
451 // Force a configuration restore by forgetting about last applied configuration
452 _pLastAppliedConfiguration = NULL;
453 }
454 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
455
456 if (pApplicableDomainConfiguration) {
457
458 // Check not the last one before applying
459 if (!_pLastAppliedConfiguration || _pLastAppliedConfiguration != pApplicableDomainConfiguration) {
460
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100461 log_info("Applying configuration \"%s\" from domain \"%s\"",
462 pApplicableDomainConfiguration->getName().c_str(),
463 getName().c_str());
464
465 // Check if we need to synchronize during restore
466 bool bSync = !pSyncerSet && _bSequenceAware;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200467
468 // Do the restore
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100469 pApplicableDomainConfiguration->restore(pParameterBlackboard, bSync, NULL);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200470
471 // Record last applied configuration
472 _pLastAppliedConfiguration = pApplicableDomainConfiguration;
473
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100474 // Check we need to provide syncer set to caller
475 if (pSyncerSet && !_bSequenceAware) {
Patrick Benavoli63499d42011-10-24 18:50:03 +0200476
477 // Since we applied changes, add our own sync set to the given one
Guillaume Denneulinf2fd15a2012-12-20 17:53:29 +0100478 *pSyncerSet += _syncerSet;
Patrick Benavoli63499d42011-10-24 18:50:03 +0200479 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200480 }
481 }
482}
483
484// Return applicable configuration validity for given configurable element
485bool CConfigurableDomain::isApplicableConfigurationValid(const CConfigurableElement* pConfigurableElement) const
486{
487 const CDomainConfiguration* pApplicableDomainConfiguration = findApplicableDomainConfiguration();
488
489 return pApplicableDomainConfiguration && pApplicableDomainConfiguration->isValid(pConfigurableElement);
490}
491
Patrick Benavoli68a91282011-08-31 11:23:23 +0200492// In case configurable element was removed
493void CConfigurableDomain::computeSyncSet()
494{
495 // Clean sync set first
Patrick Benavoli63499d42011-10-24 18:50:03 +0200496 _syncerSet.clear();
Patrick Benavoli68a91282011-08-31 11:23:23 +0200497
Patrick Benavoli63499d42011-10-24 18:50:03 +0200498 // Add syncer sets for all associated configurable elements
499 ConfigurableElementToSyncerSetMapIterator mapIt;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200500
Patrick Benavoli63499d42011-10-24 18:50:03 +0200501 for (mapIt = _configurableElementToSyncerSetMap.begin(); mapIt != _configurableElementToSyncerSetMap.end(); ++mapIt) {
Patrick Benavoli68a91282011-08-31 11:23:23 +0200502
Patrick Benavoli63499d42011-10-24 18:50:03 +0200503 const CSyncerSet* pSyncerSet = mapIt->second;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200504
Patrick Benavoli63499d42011-10-24 18:50:03 +0200505 _syncerSet += *pSyncerSet;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200506 }
507}
508
509// Configuration Management
510bool CConfigurableDomain::createConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError)
511{
512 // Already exists?
513 if (findChild(strName)) {
514
515 strError = "Already existing configuration";
516
517 return false;
518 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100519 log_info("Creating domain configuration \"%s\" into domain \"%s\"", strName.c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200520
521 // Creation
522 CDomainConfiguration* pDomainConfiguration = new CDomainConfiguration(strName);
523
524 // Configurable elements association
525 ConfigurableElementListIterator it;
526
527 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
528
Patrick Benavoli63499d42011-10-24 18:50:03 +0200529 const CConfigurableElement* pConfigurableElement = *it;;
530
531 // Retrieve associated syncer set
532 CSyncerSet* pSyncerSet = getSyncerSet(pConfigurableElement);
533
534 // Associate to configuration
535 pDomainConfiguration->addConfigurableElement(pConfigurableElement, pSyncerSet);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200536 }
537
538 // Hierarchy
539 addChild(pDomainConfiguration);
540
541 // Ensure validity of fresh new domain configuration
542 // Attempt auto validation, so that the user gets his/her own settings by defaults
543 if (!autoValidateConfiguration(pDomainConfiguration)) {
544
545 // No valid configuration found to copy in from, validate againt main blackboard (will concerned remaining invalid parts)
546 pDomainConfiguration->validate(pMainBlackboard);
547 }
548
549 return true;
550}
551
552bool CConfigurableDomain::deleteConfiguration(const string& strName, string& strError)
553{
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100554 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200555
556 if (!pDomainConfiguration) {
557
Patrick Benavoli68a91282011-08-31 11:23:23 +0200558 return false;
559 }
560
Kevin Rocardace81f82012-12-11 16:19:17 +0100561 log_info("Deleting configuration \"%s\" from domain \"%s\"", strName.c_str(), getName().c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200562
563 // Was the last applied?
564 if (pDomainConfiguration == _pLastAppliedConfiguration) {
565
566 // Forget about it
567 _pLastAppliedConfiguration = NULL;
568 }
569
570 // Hierarchy
571 removeChild(pDomainConfiguration);
572
573 // Destroy
574 delete pDomainConfiguration;
575
576 return true;
577}
578
579void CConfigurableDomain::listAssociatedToElements(string& strResult) const
580{
581 strResult = "\n";
582
583 ConfigurableElementListIterator it;
584
585 // Browse all configurable elements
586 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
587
588 const CConfigurableElement* pConfigurableElement = *it;
589
590 strResult += pConfigurableElement->getPath() + "\n";
591 }
592}
593
594bool CConfigurableDomain::renameConfiguration(const string& strName, const string& strNewName, string& strError)
595{
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100596 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200597
598 if (!pDomainConfiguration) {
599
Patrick Benavoli68a91282011-08-31 11:23:23 +0200600 return false;
601 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100602 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 +0200603
604 // Rename
605 return pDomainConfiguration->rename(strNewName, strError);
606}
607
Kevin Rocardace81f82012-12-11 16:19:17 +0100608bool CConfigurableDomain::restoreConfiguration(const string& strName, CParameterBlackboard* pMainBlackboard, bool bAutoSync, list<string>& lstrError) const
Patrick Benavoli68a91282011-08-31 11:23:23 +0200609{
Kevin Rocardace81f82012-12-11 16:19:17 +0100610 string strError;
611
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100612 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200613
614 if (!pDomainConfiguration) {
615
Kevin Rocardace81f82012-12-11 16:19:17 +0100616 lstrError.push_back(strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200617 return false;
618 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100619 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 +0200620
621 // Delegate
Kevin Rocardace81f82012-12-11 16:19:17 +0100622 bool bSuccess = pDomainConfiguration->restore(pMainBlackboard, bAutoSync && _bSequenceAware, &lstrError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200623
624 // Record last applied configuration
625 _pLastAppliedConfiguration = pDomainConfiguration;
626
627 // Synchronize
Kevin Rocardace81f82012-12-11 16:19:17 +0100628 if (bAutoSync && !_bSequenceAware) {
629
630 bSuccess &= _syncerSet.sync(*pMainBlackboard, false, &lstrError);
631 }
632 return bSuccess;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200633}
634
635bool CConfigurableDomain::saveConfiguration(const string& strName, const CParameterBlackboard* pMainBlackboard, string& strError)
636{
637 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100638 CDomainConfiguration* pDomainConfiguration = findConfiguration(strName, strError);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200639
640 if (!pDomainConfiguration) {
641
Patrick Benavoli68a91282011-08-31 11:23:23 +0200642 return false;
643 }
Kevin Rocardace81f82012-12-11 16:19:17 +0100644 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 +0200645
646 // Delegate
647 pDomainConfiguration->save(pMainBlackboard);
648
649 return true;
650}
651
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100652bool CConfigurableDomain::setElementSequence(const string& strConfiguration, const vector<string>& astrNewElementSequence, string& strError)
Patrick Benavoli63499d42011-10-24 18:50:03 +0200653{
654 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100655 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200656
657 if (!pDomainConfiguration) {
658
Patrick Benavoli63499d42011-10-24 18:50:03 +0200659 return false;
660 }
661
662 // Delegate to configuration
663 return pDomainConfiguration->setElementSequence(astrNewElementSequence, strError);
664}
665
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100666bool CConfigurableDomain::getElementSequence(const string& strConfiguration, string& strResult) const
Patrick Benavoli63499d42011-10-24 18:50:03 +0200667{
668 // Find Domain configuration
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100669 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strResult);
Patrick Benavoli63499d42011-10-24 18:50:03 +0200670
671 if (!pDomainConfiguration) {
672
Patrick Benavoli63499d42011-10-24 18:50:03 +0200673 return false;
674 }
675
676 // Delegate to configuration
677 pDomainConfiguration->getElementSequence(strResult);
678
679 return true;
680}
681
Patrick Benavoli0bd50542011-11-29 11:10:27 +0100682bool CConfigurableDomain::setApplicationRule(const string& strConfiguration, const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, string& strError)
683{
684 // Find Domain configuration
685 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
686
687 if (!pDomainConfiguration) {
688
689 return false;
690 }
691
692 // Delegate to configuration
693 return pDomainConfiguration->setApplicationRule(strApplicationRule, pSelectionCriteriaDefinition, strError);
694}
695
696bool CConfigurableDomain::clearApplicationRule(const string& strConfiguration, string& strError)
697{
698 // Find Domain configuration
699 CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strError);
700
701 if (!pDomainConfiguration) {
702
703 return false;
704 }
705
706 // Delegate to configuration
707 pDomainConfiguration->clearApplicationRule();
708
709 return true;
710}
711
712bool CConfigurableDomain::getApplicationRule(const string& strConfiguration, string& strResult) const
713{
714 // Find Domain configuration
715 const CDomainConfiguration* pDomainConfiguration = findConfiguration(strConfiguration, strResult);
716
717 if (!pDomainConfiguration) {
718
719 return false;
720 }
721
722 // Delegate to configuration
723 pDomainConfiguration->getApplicationRule(strResult);
724
725 return true;
726}
727
Patrick Benavoli68a91282011-08-31 11:23:23 +0200728// Last applied configuration
729string CConfigurableDomain::getLastAppliedConfigurationName() const
730{
731 if (_pLastAppliedConfiguration) {
732
733 return _pLastAppliedConfiguration->getName();
734 }
735 return "<none>";
736}
737
Frédéric Boisnard8b243f52012-09-06 18:03:20 +0200738// Pending configuration
739string CConfigurableDomain::getPendingConfigurationName() const
740{
741 const CDomainConfiguration* pPendingConfiguration = getPendingConfiguration();
742
743 if (pPendingConfiguration) {
744
745 return pPendingConfiguration->getName();
746 }
747 return "<none>";
748}
749
Patrick Benavoli68a91282011-08-31 11:23:23 +0200750// Ensure validity on whole domain from main blackboard
751void CConfigurableDomain::validate(const CParameterBlackboard* pMainBlackboard)
752{
Kevin Rocardace81f82012-12-11 16:19:17 +0100753 log_info("Validating whole domain \"" + getName() + "\" against main blackboard");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200754
755 // Propagate
756 uint32_t uiNbConfigurations = getNbChildren();
757 uint32_t uiChild;
758
759 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
760
761 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
762
763 pDomainConfiguration->validate(pMainBlackboard);
764 }
765}
766
767// Ensure validity on areas related to configurable element
768void CConfigurableDomain::validateAreas(const CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard)
769{
Kevin Rocardace81f82012-12-11 16:19:17 +0100770 log_info("Validating domain \"" + getName() + "\" against main blackboard for configurable element \"" + pConfigurableElement->getPath() + "\"");
Patrick Benavoli68a91282011-08-31 11:23:23 +0200771
772 // Propagate
773 uint32_t uiNbConfigurations = getNbChildren();
774 uint32_t uiChild;
775
776 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
777
778 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
779
780 pDomainConfiguration->validate(pConfigurableElement, pMainBlackboard);
781 }
782}
783
784// Attempt validation for all configurable element's areas, relying on already existing valid configuration inside domain
785void CConfigurableDomain::autoValidateAll()
786{
787 // Validate
788 ConfigurableElementListIterator it;
789
790 // Browse all configurable elements for configuration validation
791 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
792
793 const CConfigurableElement* pConfigurableElement = *it;
794
795 // Auto validate element
796 autoValidateAreas(pConfigurableElement);
797 }
798}
799
800// Attempt validation for configurable element's areas, relying on already existing valid configuration inside domain
801void CConfigurableDomain::autoValidateAreas(const CConfigurableElement* pConfigurableElement)
802{
803 // Find first valid configuration for given configurable element
804 const CDomainConfiguration* pValidDomainConfiguration = findValidDomainConfiguration(pConfigurableElement);
805
806 // No valid configuration found, give up
807 if (!pValidDomainConfiguration) {
808
809 return;
810 }
811
Kevin Rocardace81f82012-12-11 16:19:17 +0100812 log_info("Auto validating domain \"" + getName() + "\" against configuration \"" + pValidDomainConfiguration->getName() + "\" for configurable element " + pConfigurableElement->getPath());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200813
814 // Validate all other configurations against found one, if any
815 uint32_t uiNbConfigurations = getNbChildren();
816 uint32_t uiChild;
817
818 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
819
820 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
821
822 if (pDomainConfiguration != pValidDomainConfiguration && !pDomainConfiguration->isValid(pConfigurableElement)) {
823 // Validate
824 pDomainConfiguration->validateAgainst(pValidDomainConfiguration, pConfigurableElement);
825 }
826 }
827}
828
829// Attempt configuration validation for all configurable elements' areas, relying on already existing valid configuration inside domain
830bool CConfigurableDomain::autoValidateConfiguration(CDomainConfiguration* pDomainConfiguration)
831{
832 // Find another configuration than this one, that ought to be valid!
833 uint32_t uiNbConfigurations = getNbChildren();
834 uint32_t uiChild;
835
836 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
837
838 const CDomainConfiguration* pPotententialValidDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
839
840 if (pPotententialValidDomainConfiguration != pDomainConfiguration) {
841
842 // Validate against it
843 pDomainConfiguration->validateAgainst(pPotententialValidDomainConfiguration);
844
845 return true;
846 }
847 }
848 return false;
849}
Patrick Benavoli68a91282011-08-31 11:23:23 +0200850
Patrick Benavoli68a91282011-08-31 11:23:23 +0200851// Search for a valid configuration for given configurable element
852const CDomainConfiguration* CConfigurableDomain::findValidDomainConfiguration(const CConfigurableElement* pConfigurableElement) const
853{
854 uint32_t uiNbConfigurations = getNbChildren();
855 uint32_t uiChild;
856
857 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
858
859 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
860
861 if (pDomainConfiguration->isValid(pConfigurableElement)) {
862
863 return pDomainConfiguration;
864 }
865 }
866 return NULL;
867}
868
869// Search for an applicable configuration
870const CDomainConfiguration* CConfigurableDomain::findApplicableDomainConfiguration() const
871{
872 uint32_t uiNbConfigurations = getNbChildren();
873 uint32_t uiChild;
874
875 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
876
877 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(getChild(uiChild));
878
879 if (pDomainConfiguration->isApplicable()) {
880
881 return pDomainConfiguration;
882 }
883 }
884 return NULL;
885}
886
887// Gather set of configurable elements
888void CConfigurableDomain::gatherConfigurableElements(set<const CConfigurableElement*>& configurableElementSet) const
889{
890 // Insert all configurable elements
891 configurableElementSet.insert(_configurableElementList.begin(), _configurableElementList.end());
892}
893
894// Check configurable element already attached
895bool CConfigurableDomain::containsConfigurableElement(const CConfigurableElement* pConfigurableCandidateElement) const
896{
897 ConfigurableElementListIterator it;
898
899 // Browse all configurable elements for comparison
900 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
901
902 if (pConfigurableCandidateElement == *it) {
903
904 return true;
905 }
906 }
907 return false;
908}
909
910// Merge any descended configurable element to this one with this one
911void CConfigurableDomain::mergeAlreadyAssociatedDescendantConfigurableElements(CConfigurableElement* pNewConfigurableElement)
912{
913 list<CConfigurableElement*> mergedConfigurableElementList;
914
915 ConfigurableElementListIterator it;
916
917 // Browse all configurable elements (new one not yet in the list!)
918 for (it = _configurableElementList.begin(); it != _configurableElementList.end(); ++it) {
919
920 CConfigurableElement* pConfigurablePotentialDescendantElement = *it;
921
922 if (pConfigurablePotentialDescendantElement->isDescendantOf(pNewConfigurableElement)) {
923
Kevin Rocardace81f82012-12-11 16:19:17 +0100924 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 +0200925
926 // Merge configuration data
927 mergeConfigurations(pNewConfigurableElement, pConfigurablePotentialDescendantElement);
928
929 // Keep track for removal
930 mergedConfigurableElementList.push_back(pConfigurablePotentialDescendantElement);
931 }
932 }
933
934 // Remove all merged elements (new one not yet in the list!)
935 for (it = mergedConfigurableElementList.begin(); it != mergedConfigurableElementList.end(); ++it) {
936
937 CConfigurableElement* pMergedConfigurableElement = *it;
938
939 // Remove merged from configurable element from internal tracking list
940 // 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
941 doRemoveConfigurableElement(pMergedConfigurableElement, false);
942 }
943}
944
945void CConfigurableDomain::mergeConfigurations(CConfigurableElement* pToConfigurableElement, CConfigurableElement* pFromConfigurableElement)
946{
947 // Propagate to domain configurations
948 uint32_t uiNbConfigurations = getNbChildren();
949 uint32_t uiChild;
950
951 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
952
953 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
954
955 // Do the merge.
956 pDomainConfiguration->merge(pToConfigurableElement, pFromConfigurableElement);
957 }
958}
959
960// Configurable elements association
Frédéric Boisnard9620e442012-05-30 16:15:02 +0200961void CConfigurableDomain::doAddConfigurableElement(CConfigurableElement* pConfigurableElement, const CParameterBlackboard *pMainBlackboard)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200962{
963 // Inform configurable element
964 pConfigurableElement->addAttachedConfigurableDomain(this);
965
Patrick Benavoli63499d42011-10-24 18:50:03 +0200966 // Create associated syncer set
967 CSyncerSet* pSyncerSet = new CSyncerSet;
968
969 // Add to sync set the configurable element one
970 pConfigurableElement->fillSyncerSet(*pSyncerSet);
971
972 // Store it
973 _configurableElementToSyncerSetMap[pConfigurableElement] = pSyncerSet;
974
975 // Add it to global one
976 _syncerSet += *pSyncerSet;
977
Patrick Benavoli68a91282011-08-31 11:23:23 +0200978 // Inform configurations
979 uint32_t uiNbConfigurations = getNbChildren();
980 uint32_t uiChild;
981
982 for (uiChild = 0; uiChild < uiNbConfigurations; uiChild++) {
983
984 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(getChild(uiChild));
985
Patrick Benavoli63499d42011-10-24 18:50:03 +0200986 pDomainConfiguration->addConfigurableElement(pConfigurableElement, pSyncerSet);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200987 }
Patrick Benavoli68a91282011-08-31 11:23:23 +0200988
Frédéric Boisnard9620e442012-05-30 16:15:02 +0200989 // Ensure area validity for that configurable element (if main blackboard provided)
990 if (pMainBlackboard) {
991
992 // Need to validate against main blackboard
993 validateAreas(pConfigurableElement, pMainBlackboard);
994 }
995
996 // Already associated descendend configurable elements need a merge of their configuration data
Patrick Benavoli68a91282011-08-31 11:23:23 +0200997 mergeAlreadyAssociatedDescendantConfigurableElements(pConfigurableElement);
998
999 // Add to list
1000 _configurableElementList.push_back(pConfigurableElement);
1001}
1002
1003void CConfigurableDomain::doRemoveConfigurableElement(CConfigurableElement* pConfigurableElement, bool bRecomputeSyncSet)
1004{
1005 // Remove from list
1006 _configurableElementList.remove(pConfigurableElement);
1007
Patrick Benavoli63499d42011-10-24 18:50:03 +02001008 // Remove associated syncer set
1009 CSyncerSet* pSyncerSet = getSyncerSet(pConfigurableElement);
1010
1011 _configurableElementToSyncerSetMap.erase(pConfigurableElement);
1012
1013 delete pSyncerSet;
1014
Patrick Benavoli68a91282011-08-31 11:23:23 +02001015 // Inform configurable element
1016 pConfigurableElement->removeAttachedConfigurableDomain(this);
1017
1018 // Inform 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 pDomainConfiguration->removeConfigurableElement(pConfigurableElement);
1027 }
1028 // Recompute our sync set if needed
1029 if (bRecomputeSyncSet) {
1030
1031 computeSyncSet();
1032 }
1033}
Patrick Benavoli63499d42011-10-24 18:50:03 +02001034
1035// Syncer set retrieval from configurable element
1036CSyncerSet* CConfigurableDomain::getSyncerSet(const CConfigurableElement* pConfigurableElement) const
1037{
1038 ConfigurableElementToSyncerSetMapIterator mapIt = _configurableElementToSyncerSetMap.find(pConfigurableElement);
1039
1040 assert(mapIt != _configurableElementToSyncerSetMap.end());
1041
1042 return mapIt->second;
1043}
Patrick Benavoli0bd50542011-11-29 11:10:27 +01001044
1045// Configuration retrieval
1046CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strConfiguration, string& strError)
1047{
1048 CDomainConfiguration* pDomainConfiguration = static_cast<CDomainConfiguration*>(findChild(strConfiguration));
1049
1050 if (!pDomainConfiguration) {
1051
1052 strError = "Domain configuration " + strConfiguration + " not found";
1053
1054 return NULL;
1055 }
1056 return pDomainConfiguration;
1057}
1058
1059const CDomainConfiguration* CConfigurableDomain::findConfiguration(const string& strConfiguration, string& strError) const
1060{
1061 const CDomainConfiguration* pDomainConfiguration = static_cast<const CDomainConfiguration*>(findChild(strConfiguration));
1062
1063 if (!pDomainConfiguration) {
1064
1065 strError = "Domain configuration " + strConfiguration + " not found";
1066
1067 return NULL;
1068 }
1069 return pDomainConfiguration;
1070}